]> git.saurik.com Git - bison.git/blobdiff - src/conflicts.c
* src/conflicts.c (print_reductions): Formatting changes.
[bison.git] / src / conflicts.c
index 2ade63da446361bd94121310005e78965ffd473e..f10c36b335d6dcbed3b370dfb4f2cd613f7696fa 100644 (file)
@@ -1,5 +1,5 @@
 /* Find and resolve or report look-ahead conflicts for bison,
 /* Find and resolve or report look-ahead conflicts for bison,
-   Copyright (C) 1984, 1989, 1992, 2000 Free Software Foundation, Inc.
+   Copyright 1984, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
    02111-1307, USA.  */
 
 #include "system.h"
    02111-1307, USA.  */
 
 #include "system.h"
+#include "complain.h"
 #include "getargs.h"
 #include "getargs.h"
-#include "alloc.h"
 #include "files.h"
 #include "gram.h"
 #include "state.h"
 #include "lalr.h"
 #include "conflicts.h"
 #include "files.h"
 #include "gram.h"
 #include "state.h"
 #include "lalr.h"
 #include "conflicts.h"
+#include "reader.h"
+#include "LR0.h"
 
 
-extern char **tags;
-extern int fixed_outfiles;
+/* -1 stands for not specified. */
+int expected_conflicts = -1;
+static char *conflicts = NULL;
 
 
-int any_conflicts = 0;
-errs **err_table;
-int expected_conflicts;
-static char *conflicts;
-
-static unsigned *shiftset;
-static unsigned *lookaheadset;
-static int src_total;
-static int rrc_total;
-static int src_count;
-static int rrc_count;
+static unsigned *shiftset = NULL;
+static unsigned *lookaheadset = NULL;
 \f
 
 static inline void
 log_resolution (int state, int LAno, int token, char *resolution)
 {
 \f
 
 static inline void
 log_resolution (int state, int LAno, int token, char *resolution)
 {
-  if (verboseflag)
-    fprintf (foutput,
-            _("\
+  if (verbose_flag)
+    obstack_fgrow4 (&output_obstack,
+                   _("\
 Conflict in state %d between rule %d and token %s resolved as %s.\n"),
 Conflict in state %d between rule %d and token %s resolved as %s.\n"),
-            state, LAruleno[LAno], tags[token], resolution);
+                   state, LAruleno[LAno], tags[token], resolution);
 }
 
 
 }
 
 
@@ -63,21 +57,26 @@ Conflict in state %d between rule %d and token %s resolved as %s.\n"),
 static void
 flush_shift (int state, int token)
 {
 static void
 flush_shift (int state, int token)
 {
-  shifts *shiftp;
-  int k, i;
+  shifts *shiftp = state_table[state]->shifts;
+  int i;
 
 
-  shiftp = shift_table[state];
+  RESETBIT (lookaheadset, token);
+  for (i = 0; i < shiftp->nshifts; i++)
+    if (!SHIFT_IS_DISABLED (shiftp, i) && SHIFT_SYMBOL (shiftp, i) == token)
+      SHIFT_DISABLE (shiftp, i);
+}
 
 
-  if (shiftp)
-    {
-      k = shiftp->nshifts;
-      for (i = 0; i < k; i++)
-       {
-         if (shiftp->shifts[i]
-             && token == accessing_symbol[shiftp->shifts[i]])
-           (shiftp->shifts[i]) = 0;
-       }
-    }
+
+/*-------------------------------------------------------------------.
+| Turn off the reduce recorded for the specified token for the       |
+| specified lookahead.  Used when we resolve a shift-reduce conflict |
+| in favor of the shift.                                             |
+`-------------------------------------------------------------------*/
+
+static void
+flush_reduce (int lookahead, int token)
+{
+  RESETBIT (LA (lookahead), token);
 }
 
 
 }
 
 
@@ -89,98 +88,66 @@ flush_shift (int state, int token)
 `------------------------------------------------------------------*/
 
 static void
 `------------------------------------------------------------------*/
 
 static void
-resolve_sr_conflict (int state, int lookaheadnum)
+resolve_sr_conflict (int state, int lookahead)
 {
   int i;
 {
   int i;
-  int mask;
-  unsigned *fp1;
-  unsigned *fp2;
-  int redprec;
-  errs *errp = (errs *) xmalloc (sizeof (errs) + ntokens * sizeof (short));
-  short *errtokens = errp->errs;
-
   /* find the rule to reduce by to get precedence of reduction  */
   /* find the rule to reduce by to get precedence of reduction  */
-  redprec = rprec[LAruleno[lookaheadnum]];
+  int redprec = rule_table[LAruleno[lookahead]].prec;
+  errs *errp = ERRS_ALLOC (ntokens + 1);
+  short *errtokens = errp->errs;
 
 
-  mask = 1;
-  fp1 = LA + lookaheadnum * tokensetsize;
-  fp2 = lookaheadset;
   for (i = 0; i < ntokens; i++)
   for (i = 0; i < ntokens; i++)
-    {
-      if ((mask & *fp2 & *fp1) && sprec[i])
+    if (BITISSET (LA (lookahead), i)
+       && BITISSET (lookaheadset, i)
+       && sprec[i])
+      {
        /* Shift-reduce conflict occurs for token number i
           and it has a precedence.
           The precedence of shifting is that of token i.  */
        /* Shift-reduce conflict occurs for token number i
           and it has a precedence.
           The precedence of shifting is that of token i.  */
-       {
-         if (sprec[i] < redprec)
-           {
-             log_resolution (state, lookaheadnum, i, _("reduce"));
-             *fp2 &= ~mask;    /* flush the shift for this token */
-             flush_shift (state, i);
-           }
-         else if (sprec[i] > redprec)
-           {
-             log_resolution (state, lookaheadnum, i, _("shift"));
-             *fp1 &= ~mask;    /* flush the reduce for this token */
-           }
-         else
-           {
-             /* Matching precedence levels.
-                For left association, keep only the reduction.
-                For right association, keep only the shift.
-                For nonassociation, keep neither.  */
-
-             switch (sassoc[i])
-               {
-               case RIGHT_ASSOC:
-                 log_resolution (state, lookaheadnum, i, _("shift"));
-                 break;
+       if (sprec[i] < redprec)
+         {
+           log_resolution (state, lookahead, i, _("reduce"));
+           flush_shift (state, i);
+         }
+       else if (sprec[i] > redprec)
+         {
+           log_resolution (state, lookahead, i, _("shift"));
+           flush_reduce (lookahead, i);
+         }
+       else
+         /* Matching precedence levels.
+            For left association, keep only the reduction.
+            For right association, keep only the shift.
+            For nonassociation, keep neither.  */
 
 
-               case LEFT_ASSOC:
-                 log_resolution (state, lookaheadnum, i, _("reduce"));
-                 break;
+         switch (sassoc[i])
+           {
+           case right_assoc:
+             log_resolution (state, lookahead, i, _("shift"));
+             flush_reduce (lookahead, i);
+             break;
 
 
-               case NON_ASSOC:
-                 log_resolution (state, lookaheadnum, i, _("an error"));
-                 break;
-               }
+           case left_assoc:
+             log_resolution (state, lookahead, i, _("reduce"));
+             flush_shift (state, i);
+             break;
 
 
-             if (sassoc[i] != RIGHT_ASSOC)
-               {
-                 *fp2 &= ~mask;        /* flush the shift for this token */
-                 flush_shift (state, i);
-               }
-             if (sassoc[i] != LEFT_ASSOC)
-               {
-                 *fp1 &= ~mask;        /* flush the reduce for this token */
-               }
-             if (sassoc[i] == NON_ASSOC)
-               {
-                 /* Record an explicit error for this token.  */
-                 *errtokens++ = i;
-               }
+           case non_assoc:
+             log_resolution (state, lookahead, i, _("an error"));
+             flush_shift (state, i);
+             flush_reduce (lookahead, i);
+             /* Record an explicit error for this token.  */
+             *errtokens++ = i;
+             break;
            }
            }
-       }
+      }
 
 
-      mask <<= 1;
-      if (mask == 0)
-       {
-         mask = 1;
-         fp2++;
-         fp1++;
-       }
-    }
   errp->nerrs = errtokens - errp->errs;
   errp->nerrs = errtokens - errp->errs;
-  if (errp->nerrs)
-    {
-      /* Some tokens have been explicitly made errors.  Allocate
-         a permanent errs structure for this state, to record them.  */
-      i = (char *) errtokens - (char *) errp;
-      err_table[state] = (errs *) xmalloc ((unsigned int) i);
-      bcopy (errp, err_table[state], i);
-    }
-  else
-    err_table[state] = 0;
+  /* Some tokens have been explicitly made errors.  Allocate a
+     permanent errs structure for this state, to record them.  */
+  i = (char *) errtokens - (char *) errp;
+  state_table[state]->errs = ERRS_ALLOC (i + 1);
+  memcpy (state_table[state]->errs, errp, i);
   free (errp);
 }
 
   free (errp);
 }
 
@@ -188,95 +155,58 @@ resolve_sr_conflict (int state, int lookaheadnum)
 static void
 set_conflicts (int state)
 {
 static void
 set_conflicts (int state)
 {
-  int i;
-  int k;
+  int i, j;
   shifts *shiftp;
   shifts *shiftp;
-  unsigned *fp2;
-  unsigned *fp3;
-  unsigned *fp4;
-  unsigned *fp1;
-  int symbol;
 
 
-  if (consistent[state])
+  if (state_table[state]->consistent)
     return;
 
   for (i = 0; i < tokensetsize; i++)
     lookaheadset[i] = 0;
 
     return;
 
   for (i = 0; i < tokensetsize; i++)
     lookaheadset[i] = 0;
 
-  shiftp = shift_table[state];
-  if (shiftp)
-    {
-      k = shiftp->nshifts;
-      for (i = 0; i < k; i++)
-       {
-         symbol = accessing_symbol[shiftp->shifts[i]];
-         if (ISVAR (symbol))
-           break;
-         SETBIT (lookaheadset, symbol);
-       }
-    }
-
-  k = lookaheads[state + 1];
-  fp4 = lookaheadset + tokensetsize;
+  shiftp = state_table[state]->shifts;
+  for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
+    if (!SHIFT_IS_DISABLED (shiftp, i))
+      SETBIT (lookaheadset, SHIFT_SYMBOL (shiftp, i));
 
   /* Loop over all rules which require lookahead in this state.  First
      check for shift-reduce conflict, and try to resolve using
      precedence */
 
   /* Loop over all rules which require lookahead in this state.  First
      check for shift-reduce conflict, and try to resolve using
      precedence */
-  for (i = lookaheads[state]; i < k; i++)
-    if (rprec[LAruleno[i]])
-      {
-       fp1 = LA + i * tokensetsize;
-       fp2 = fp1;
-       fp3 = lookaheadset;
-
-       while (fp3 < fp4)
+  for (i = state_table[state]->lookaheads;
+       i < state_table[state + 1]->lookaheads;
+       ++i)
+    if (rule_table[LAruleno[i]].prec)
+      for (j = 0; j < tokensetsize; ++j)
+       if (LA (i)[j] & lookaheadset[j])
          {
          {
-           if (*fp2++ & *fp3++)
-             {
-               resolve_sr_conflict (state, i);
-               break;
-             }
+           resolve_sr_conflict (state, i);
+           break;
          }
          }
-      }
 
 
   /* Loop over all rules which require lookahead in this state.  Check
      for conflicts not resolved above.  */
 
 
   /* Loop over all rules which require lookahead in this state.  Check
      for conflicts not resolved above.  */
-  for (i = lookaheads[state]; i < k; i++)
+  for (i = state_table[state]->lookaheads;
+       i < state_table[state + 1]->lookaheads;
+       ++i)
     {
     {
-      fp1 = LA + i * tokensetsize;
-      fp2 = fp1;
-      fp3 = lookaheadset;
-
-      while (fp3 < fp4)
-       {
-         if (*fp2++ & *fp3++)
-           {
-             conflicts[state] = 1;
-             any_conflicts = 1;
-           }
-       }
+      for (j = 0; j < tokensetsize; ++j)
+       if (LA (i)[j] & lookaheadset[j])
+         conflicts[state] = 1;
 
 
-      fp2 = fp1;
-      fp3 = lookaheadset;
-
-      while (fp3 < fp4)
-       *fp3++ |= *fp2++;
+      for (j = 0; j < tokensetsize; ++j)
+       lookaheadset[j] |= LA (i)[j];
     }
 }
 
 void
     }
 }
 
 void
-initialize_conflicts (void)
+solve_conflicts (void)
 {
   int i;
 
 {
   int i;
 
-  conflicts = NEW2 (nstates, char);
-  shiftset = NEW2 (tokensetsize, unsigned);
-  lookaheadset = NEW2 (tokensetsize, unsigned);
-
-  err_table = NEW2 (nstates, errs *);
-
-  any_conflicts = 0;
+  conflicts = XCALLOC (char, nstates);
+  shiftset = XCALLOC (unsigned, tokensetsize);
+  lookaheadset = XCALLOC (unsigned, tokensetsize);
 
   for (i = 0; i < nstates; i++)
     set_conflicts (i);
 
   for (i = 0; i < nstates; i++)
     set_conflicts (i);
@@ -287,23 +217,15 @@ initialize_conflicts (void)
 | Count the number of shift/reduce conflicts.  |
 `---------------------------------------------*/
 
 | Count the number of shift/reduce conflicts.  |
 `---------------------------------------------*/
 
-static void
+static int
 count_sr_conflicts (int state)
 {
 count_sr_conflicts (int state)
 {
-  int i;
-  int k;
-  int mask;
-  shifts *shiftp;
-  unsigned *fp1;
-  unsigned *fp2;
-  unsigned *fp3;
-  int symbol;
+  int i, k;
+  int src_count = 0;
+  shifts *shiftp = state_table[state]->shifts;
 
 
-  src_count = 0;
-
-  shiftp = shift_table[state];
   if (!shiftp)
   if (!shiftp)
-    return;
+    return 0;
 
   for (i = 0; i < tokensetsize; i++)
     {
 
   for (i = 0; i < tokensetsize; i++)
     {
@@ -311,49 +233,24 @@ count_sr_conflicts (int state)
       lookaheadset[i] = 0;
     }
 
       lookaheadset[i] = 0;
     }
 
-  k = shiftp->nshifts;
-  for (i = 0; i < k; i++)
-    {
-      if (!shiftp->shifts[i])
-       continue;
-      symbol = accessing_symbol[shiftp->shifts[i]];
-      if (ISVAR (symbol))
-       break;
-      SETBIT (shiftset, symbol);
-    }
-
-  k = lookaheads[state + 1];
-  fp3 = lookaheadset + tokensetsize;
-
-  for (i = lookaheads[state]; i < k; i++)
-    {
-      fp1 = LA + i * tokensetsize;
-      fp2 = lookaheadset;
+  for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
+    if (!SHIFT_IS_DISABLED (shiftp, i))
+      SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
 
 
-      while (fp2 < fp3)
-       *fp2++ |= *fp1++;
-    }
-
-  fp1 = shiftset;
-  fp2 = lookaheadset;
+  for (i = state_table[state]->lookaheads;
+       i < state_table[state + 1]->lookaheads;
+       ++i)
+    for (k = 0; k < tokensetsize; ++k)
+      lookaheadset[k] |= LA (i)[k];
 
 
-  while (fp2 < fp3)
-    *fp2++ &= *fp1++;
+  for (k = 0; k < tokensetsize; ++k)
+    lookaheadset[k] &= shiftset[k];
 
 
-  mask = 1;
-  fp2 = lookaheadset;
   for (i = 0; i < ntokens; i++)
   for (i = 0; i < ntokens; i++)
-    {
-      if (mask & *fp2)
-       src_count++;
+    if (BITISSET (lookaheadset, i))
+      src_count++;
 
 
-      mask <<= 1;
-      if (mask == 0)
-       {
-         mask = 1;
-         fp2++;
-       }
-    }
+  return src_count;
 }
 
 
 }
 
 
@@ -361,112 +258,128 @@ count_sr_conflicts (int state)
 | Count the number of reduce/reduce conflicts.  |
 `----------------------------------------------*/
 
 | Count the number of reduce/reduce conflicts.  |
 `----------------------------------------------*/
 
-static void
+static int
 count_rr_conflicts (int state)
 {
   int i;
 count_rr_conflicts (int state)
 {
   int i;
-  int j;
-  int count;
-  unsigned mask;
-  unsigned *baseword;
-  unsigned *wordp;
-  int m;
-  int n;
+  int rrc_count = 0;
 
 
-  rrc_count = 0;
-
-  m = lookaheads[state];
-  n = lookaheads[state + 1];
+  int m = state_table[state]->lookaheads;
+  int n = state_table[state + 1]->lookaheads;
 
   if (n - m < 2)
 
   if (n - m < 2)
-    return;
+    return 0;
 
 
-  mask = 1;
-  baseword = LA + m * tokensetsize;
   for (i = 0; i < ntokens; i++)
     {
   for (i = 0; i < ntokens; i++)
     {
-      wordp = baseword;
-
-      count = 0;
+      int count = 0;
+      int j;
       for (j = m; j < n; j++)
       for (j = m; j < n; j++)
-       {
-         if (mask & *wordp)
-           count++;
-
-         wordp += tokensetsize;
-       }
+       if (BITISSET (LA (m), j))
+         count++;
 
       if (count >= 2)
        rrc_count++;
 
       if (count >= 2)
        rrc_count++;
-
-      mask <<= 1;
-      if (mask == 0)
-       {
-         mask = 1;
-         baseword++;
-       }
     }
     }
+
+  return rrc_count;
 }
 
 }
 
-/*----------------------------------------------------------.
-| Output to OUT a human readable report on shift/reduce and |
-| reduce/reduce conflict numbers (SRC_NUM, RRC_NUM).        |
-`----------------------------------------------------------*/
+/*--------------------------------------------------------------.
+| Return a human readable string which reports shift/reduce and |
+| reduce/reduce conflict numbers (SRC_NUM, RRC_NUM).            |
+`--------------------------------------------------------------*/
 
 
-static void
-conflict_report (FILE *out, int src_num, int rrc_num)
+static const char *
+conflict_report (int src_num, int rrc_num)
 {
 {
-  if (src_num == 1)
-    fprintf (out, _(" 1 shift/reduce conflict"));
-  else if (src_num > 1)
-    fprintf (out, _(" %d shift/reduce conflicts"), src_num);
+  static char res[4096];
+  char *cp = res;
+
+  if (src_num >= 1)
+    {
+      sprintf (cp, ngettext ("%d shift/reduce conflict",
+                            "%d shift/reduce conflicts", src_num), src_num);
+      cp += strlen (cp);
+    }
 
   if (src_num > 0 && rrc_num > 0)
 
   if (src_num > 0 && rrc_num > 0)
-    fprintf (out, _(" and"));
+    {
+      sprintf (cp, " %s ", _("and"));
+      cp += strlen (cp);
+    }
+
+  if (rrc_num >= 1)
+    {
+      sprintf (cp, ngettext ("%d reduce/reduce conflict",
+                            "%d reduce/reduce conflicts", rrc_num), rrc_num);
+      cp += strlen (cp);
+    }
 
 
-  if (rrc_num == 1)
-    fprintf (out, _(" 1 reduce/reduce conflict"));
-  else if (rrc_num > 1)
-    fprintf (out, _(" %d reduce/reduce conflicts"), rrc_num);
+  *cp++ = '.';
+  *cp++ = '\n';
+  *cp++ = '\0';
 
 
-  putc ('.', out);
-  putc ('\n', out);
+  return res;
 }
 
 
 }
 
 
-/*---------------------------------------------.
-| Compute and give a report on the conflicts.  |
-`---------------------------------------------*/
+/*-----------------------------------------------------------.
+| Output the detailed description of states with conflicts.  |
+`-----------------------------------------------------------*/
 
 void
 
 void
-print_conflicts (void)
+conflicts_output (FILE *out)
 {
 {
+  bool printed_sth = FALSE;
   int i;
   int i;
+  for (i = 0; i < nstates; i++)
+    if (conflicts[i])
+      {
+       fprintf (out, _("State %d contains "), i);
+       fputs (conflict_report (count_sr_conflicts (i),
+                               count_rr_conflicts (i)), out);
+       printed_sth = TRUE;
+      }
+  if (printed_sth)
+    fputs ("\n\n", out);
+}
+
 
 
-  src_total = 0;
-  rrc_total = 0;
+/*------------------------------------------.
+| Reporting the total number of conflicts.  |
+`------------------------------------------*/
 
 
-  /* Count the total number of conflicts, and if wanted, give a
-     detailed report in FOUTPUT.  */
+void
+conflicts_print (void)
+{
+  int i;
+
+  /* Is the number of SR conflicts OK?  Either EXPECTED_CONFLICTS is
+     not set, and then we want 0 SR, or else it is specified, in which
+     case we want equality.  */
+  int src_ok = 0;
+
+  int src_total = 0;
+  int rrc_total = 0;
+
+  /* Conflicts by state.  */
   for (i = 0; i < nstates; i++)
   for (i = 0; i < nstates; i++)
-    {
-      if (conflicts[i])
-       {
-         count_sr_conflicts (i);
-         count_rr_conflicts (i);
-         src_total += src_count;
-         rrc_total += rrc_count;
+    if (conflicts[i])
+      {
+       src_total += count_sr_conflicts (i);
+       rrc_total += count_rr_conflicts (i);
+      }
 
 
-         if (verboseflag)
-           {
-             fprintf (foutput, _("State %d contains"), i);
-             conflict_report (foutput, src_count, rrc_count);
-           }
-       }
-    }
+  src_ok = src_total == (expected_conflicts == -1 ? 0 : expected_conflicts);
+
+  /* If there are no RR conflicts, and as many SR conflicts as
+     expected, then there is nothing to report.  */
+  if (!rrc_total && src_ok)
+    return;
 
   /* Report the total number of conflicts on STDERR.  */
 
   /* Report the total number of conflicts on STDERR.  */
-  if (fixed_outfiles)
+  if (yacc_flag)
     {
       /* If invoked with `--yacc', use the output format specified by
         POSIX.  */
     {
       /* If invoked with `--yacc', use the output format specified by
         POSIX.  */
@@ -481,136 +394,86 @@ print_conflicts (void)
     }
   else
     {
     }
   else
     {
-      fprintf (stderr, _("%s contains"), infile);
-      conflict_report (stderr, src_total, rrc_total);
+      fprintf (stderr, _("%s contains "), infile);
+      fputs (conflict_report (src_total, rrc_total), stderr);
+    }
+
+  if (expected_conflicts != -1 && !src_ok)
+    {
+      complain_message_count++;
+      fprintf (stderr, ngettext ("expected %d shift/reduce conflict\n",
+                                "expected %d shift/reduce conflicts\n",
+                                expected_conflicts),
+              expected_conflicts);
     }
 }
 
 
 void
     }
 }
 
 
 void
-print_reductions (int state)
+print_reductions (FILE *out, int state)
 {
   int i;
   int j;
 {
   int i;
   int j;
-  int k;
-  unsigned *fp1;
-  unsigned *fp2;
-  unsigned *fp3;
-  unsigned *fp4;
-  int rule;
-  int symbol;
-  unsigned mask;
-  int m;
-  int n;
-  int default_LA;
-  int default_rule = 0;
-  int cmax;
-  int count;
-  shifts *shiftp;
-  errs *errp;
+  int m = state_table[state]->lookaheads;
+  int n = state_table[state + 1]->lookaheads;
+  shifts *shiftp = state_table[state]->shifts;
+  errs *errp = state_table[state]->errs;
   int nodefault = 0;
 
   for (i = 0; i < tokensetsize; i++)
     shiftset[i] = 0;
 
   int nodefault = 0;
 
   for (i = 0; i < tokensetsize; i++)
     shiftset[i] = 0;
 
-  shiftp = shift_table[state];
-  if (shiftp)
-    {
-      k = shiftp->nshifts;
-      for (i = 0; i < k; i++)
-       {
-         if (!shiftp->shifts[i])
-           continue;
-         symbol = accessing_symbol[shiftp->shifts[i]];
-         if (ISVAR (symbol))
-           break;
-         /* if this state has a shift for the error token,
-            don't use a default rule.  */
-         if (symbol == error_token_number)
-           nodefault = 1;
-         SETBIT (shiftset, symbol);
-       }
-    }
+  for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
+    if (!SHIFT_IS_DISABLED (shiftp, i))
+      {
+       /* if this state has a shift for the error token, don't use a
+          default rule.  */
+       if (SHIFT_IS_ERROR (shiftp, i))
+         nodefault = 1;
+       SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
+      }
 
 
-  errp = err_table[state];
   if (errp)
   if (errp)
-    {
-      k = errp->nerrs;
-      for (i = 0; i < k; i++)
-       {
-         if (!errp->errs[i])
-           continue;
-         symbol = errp->errs[i];
-         SETBIT (shiftset, symbol);
-       }
-    }
-
-  m = lookaheads[state];
-  n = lookaheads[state + 1];
+    for (i = 0; i < errp->nerrs; i++)
+      if (errp->errs[i])
+       SETBIT (shiftset, errp->errs[i]);
 
   if (n - m == 1 && !nodefault)
     {
 
   if (n - m == 1 && !nodefault)
     {
-      default_rule = LAruleno[m];
-
-      fp1 = LA + m * tokensetsize;
-      fp2 = shiftset;
-      fp3 = lookaheadset;
-      fp4 = lookaheadset + tokensetsize;
-
-      while (fp3 < fp4)
-       *fp3++ = *fp1++ & *fp2++;
+      int k;
+      int default_rule = LAruleno[m];
 
 
-      mask = 1;
-      fp3 = lookaheadset;
+      for (k = 0; k < tokensetsize; ++k)
+       lookaheadset[k] = LA (m)[k] & shiftset[k];
 
       for (i = 0; i < ntokens; i++)
 
       for (i = 0; i < ntokens; i++)
-       {
-         if (mask & *fp3)
-           fprintf (foutput, _("    %-4s\t[reduce using rule %d (%s)]\n"),
-                    tags[i], default_rule, tags[rlhs[default_rule]]);
-
-         mask <<= 1;
-         if (mask == 0)
-           {
-             mask = 1;
-             fp3++;
-           }
-       }
+       if (BITISSET (lookaheadset, i))
+         fprintf (out, _("    %-4s\t[reduce using rule %d (%s)]\n"),
+                  tags[i], default_rule,
+                  tags[rule_table[default_rule].lhs]);
 
 
-      fprintf (foutput, _("    $default\treduce using rule %d (%s)\n\n"),
-              default_rule, tags[rlhs[default_rule]]);
+      fprintf (out, _("    $default\treduce using rule %d (%s)\n\n"),
+              default_rule, tags[rule_table[default_rule].lhs]);
     }
   else if (n - m >= 1)
     {
     }
   else if (n - m >= 1)
     {
-      cmax = 0;
-      default_LA = -1;
-      fp4 = lookaheadset + tokensetsize;
+      int k;
+
+      int cmax = 0;
+      int default_LA = -1;
+      int default_rule = 0;
 
       if (!nodefault)
        for (i = m; i < n; i++)
          {
 
       if (!nodefault)
        for (i = m; i < n; i++)
          {
-           fp1 = LA + i * tokensetsize;
-           fp2 = shiftset;
-           fp3 = lookaheadset;
+           int count = 0;
 
 
-           while (fp3 < fp4)
-             *fp3++ = *fp1++ & (~(*fp2++));
+           for (k = 0; k < tokensetsize; ++k)
+             lookaheadset[k] = LA (i)[k] & ~shiftset[k];
 
 
-           count = 0;
-           mask = 1;
-           fp3 = lookaheadset;
            for (j = 0; j < ntokens; j++)
            for (j = 0; j < ntokens; j++)
-             {
-               if (mask & *fp3)
-                 count++;
-
-               mask <<= 1;
-               if (mask == 0)
-                 {
-                   mask = 1;
-                   fp3++;
-                 }
-             }
+             if (BITISSET (lookaheadset, j))
+               count++;
 
            if (count > cmax)
              {
 
            if (count > cmax)
              {
@@ -619,56 +482,34 @@ print_reductions (int state)
                default_rule = LAruleno[i];
              }
 
                default_rule = LAruleno[i];
              }
 
-           fp2 = shiftset;
-           fp3 = lookaheadset;
-
-           while (fp3 < fp4)
-             *fp2++ |= *fp3++;
+           for (k = 0; k < tokensetsize; ++k)
+             shiftset[k] |= lookaheadset[k];
          }
 
       for (i = 0; i < tokensetsize; i++)
        shiftset[i] = 0;
 
          }
 
       for (i = 0; i < tokensetsize; i++)
        shiftset[i] = 0;
 
-      if (shiftp)
-       {
-         k = shiftp->nshifts;
-         for (i = 0; i < k; i++)
-           {
-             if (!shiftp->shifts[i])
-               continue;
-             symbol = accessing_symbol[shiftp->shifts[i]];
-             if (ISVAR (symbol))
-               break;
-             SETBIT (shiftset, symbol);
-           }
-       }
+      for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
+       if (!SHIFT_IS_DISABLED (shiftp, i))
+         SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
 
 
-      mask = 1;
-      fp1 = LA + m * tokensetsize;
-      fp2 = shiftset;
       for (i = 0; i < ntokens; i++)
        {
          int defaulted = 0;
       for (i = 0; i < ntokens; i++)
        {
          int defaulted = 0;
+         int count = BITISSET (shiftset, i);
 
 
-         if (mask & *fp2)
-           count = 1;
-         else
-           count = 0;
-
-         fp3 = fp1;
          for (j = m; j < n; j++)
            {
          for (j = m; j < n; j++)
            {
-             if (mask & *fp3)
+             if (BITISSET (LA (m), j))
                {
                  if (count == 0)
                    {
                      if (j != default_LA)
                {
                  if (count == 0)
                    {
                      if (j != default_LA)
-                       {
-                         rule = LAruleno[j];
-                         fprintf (foutput,
-                                  _("    %-4s\treduce using rule %d (%s)\n"),
-                                  tags[i], rule, tags[rlhs[rule]]);
-                       }
+                       fprintf (out,
+                                _("    %-4s\treduce using rule %d (%s)\n"),
+                                tags[i],
+                                LAruleno[j],
+                                tags[rule_table[LAruleno[j]].lhs]);
                      else
                        defaulted = 1;
 
                      else
                        defaulted = 1;
 
@@ -677,49 +518,33 @@ print_reductions (int state)
                  else
                    {
                      if (defaulted)
                  else
                    {
                      if (defaulted)
-                       {
-                         rule = LAruleno[default_LA];
-                         fprintf (foutput,
-                                  _("    %-4s\treduce using rule %d (%s)\n"),
-                                  tags[i], rule, tags[rlhs[rule]]);
-                         defaulted = 0;
-                       }
-                     rule = LAruleno[j];
-                     fprintf (foutput,
+                       fprintf (out,
+                                _("    %-4s\treduce using rule %d (%s)\n"),
+                                tags[i],
+                                LAruleno[default_LA],
+                                tags[rule_table[LAruleno[default_LA]].lhs]);
+                     defaulted = 0;
+                     fprintf (out,
                               _("    %-4s\t[reduce using rule %d (%s)]\n"),
                               _("    %-4s\t[reduce using rule %d (%s)]\n"),
-                              tags[i], rule, tags[rlhs[rule]]);
+                              tags[i],
+                              LAruleno[j],
+                              tags[rule_table[LAruleno[j]].lhs]);
                    }
                }
                    }
                }
-
-             fp3 += tokensetsize;
-           }
-
-         mask <<= 1;
-         if (mask == 0)
-           {
-             mask = 1;
-             /* We tried incrementing just fp1, and just fp2; both seem wrong.
-                It seems necessary to increment both in sync.  */
-             fp1++;
-             fp2++;
            }
        }
 
       if (default_LA >= 0)
            }
        }
 
       if (default_LA >= 0)
-       {
-         fprintf (foutput, _("    $default\treduce using rule %d (%s)\n"),
-                  default_rule, tags[rlhs[default_rule]]);
-       }
-
-      putc ('\n', foutput);
+       fprintf (out, _("    $default\treduce using rule %d (%s)\n"),
+                default_rule, tags[rule_table[default_rule].lhs]);
     }
 }
 
 
 void
     }
 }
 
 
 void
-finalize_conflicts (void)
+free_conflicts (void)
 {
 {
-  FREE (conflicts);
-  FREE (shiftset);
-  FREE (lookaheadset);
+  XFREE (conflicts);
+  XFREE (shiftset);
+  XFREE (lookaheadset);
 }
 }