]> git.saurik.com Git - bison.git/blobdiff - src/print.c
* src/state.h, src/state.c (errs_new, errs_dup): New.
[bison.git] / src / print.c
index 93021fa58dee48041438c939daad3795b007178b..b9c518f7dd1bd6f3ca35c46ba7821eab712de174 100644 (file)
@@ -32,6 +32,9 @@
 #include "reduce.h"
 #include "closure.h"
 
+static unsigned *shiftset = NULL;
+static unsigned *lookaheadset = NULL;
+
 #if 0
 static void
 print_token (int extnum, int token)
@@ -46,11 +49,11 @@ print_token (int extnum, int token)
 `--------------------------------*/
 
 static void
-print_core (FILE *out, int state)
+print_core (FILE *out, state_t *state)
 {
   int i;
-  short *sitems = state_table[state].state->items;
-  int snitems   = state_table[state].state->nitems;
+  short *sitems = state->items;
+  int snitems   = state->nitems;
 
   /* New experimental feature: if TRACE_FLAGS output all the items of
      a state, not only its kernel.  */
@@ -93,91 +96,232 @@ print_core (FILE *out, int state)
     }
 }
 
+
 static void
-print_actions (FILE *out, int state)
+print_shifts (FILE *out, state_t *state)
 {
   int i;
+  shifts *shiftp = state->shifts;
 
-  shifts   *shiftp = state_table[state].shifts;
-  reductions *redp = state_table[state].reductions;
-  errs       *errp = state_table[state].errs;
-
-  if (!shiftp->nshifts && !redp)
-    {
-      if (final_state == state)
-       fprintf (out, _("    $default\taccept\n"));
-      else
-       fprintf (out, _("    NO ACTIONS\n"));
-      return;
-    }
-
-  for (i = 0; i < shiftp->nshifts; i++)
+  for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
     if (!SHIFT_IS_DISABLED (shiftp, i))
       {
        int state1 = shiftp->shifts[i];
-       int symbol = state_table[state1].accessing_symbol;
-       /* The following line used to be turned off.  */
-       if (ISVAR (symbol))
-         break;
-       if (symbol == 0)        /* I.e. strcmp(tags[symbol],"$")==0 */
-         fprintf (out,
-                  _("    $   \tgo to state %d\n"), state1);
-       else
-         fprintf (out,
-                  _("    %-4s\tshift, and go to state %d\n"),
-                  tags[symbol], state1);
+       int symbol = state_table[state1]->accessing_symbol;
+       fprintf (out,
+                _("    %-4s\tshift, and go to state %d\n"),
+                tags[symbol], state1);
       }
 
   if (i > 0)
     fputc ('\n', out);
+}
+
+
+static void
+print_errs (FILE *out, state_t *state)
+{
+  errs *errp = state->errs;
+  int i;
+
+  for (i = 0; i < errp->nerrs; ++i)
+    if (errp->errs[i])
+      fprintf (out, _("    %-4s\terror (nonassociative)\n"),
+              tags[errp->errs[i]]);
+
+  if (i > 0)
+    fputc ('\n', out);
+}
+
+
+static void
+print_gotos (FILE *out, state_t *state)
+{
+  int i;
+  shifts *shiftp = state->shifts;
 
-  if (errp)
+  for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
+    /* Skip token shifts.  */;
+
+  if (i < shiftp->nshifts)
     {
-      int j;
-      for (j = 0; j < errp->nerrs; j++)
-       {
-         int symbol = errp->errs[j];
-         if (!symbol)
-           continue;
-         fprintf (out, _("    %-4s\terror (nonassociative)\n"),
-                  tags[symbol]);
-       }
+      for (; i < shiftp->nshifts; i++)
+       if (!SHIFT_IS_DISABLED (shiftp, i))
+         {
+           int state1 = shiftp->shifts[i];
+           int symbol = state_table[state1]->accessing_symbol;
+           fprintf (out, _("    %-4s\tgo to state %d\n"),
+                    tags[symbol], state1);
+         }
 
-      if (j > 0)
-       fputc ('\n', out);
+      fputc ('\n', out);
     }
+}
+
+static void
+print_reductions (FILE *out, state_t *state)
+{
+  int i;
+  shifts *shiftp = state->shifts;
+  reductions *redp = state->reductions;
+  errs *errp = state->errs;
+  int nodefault = 0;
 
-  if (state_table[state].consistent && redp)
+  if (state->consistent)
     {
       int rule = redp->rules[0];
       int symbol = rule_table[rule].lhs;
       fprintf (out, _("    $default\treduce using rule %d (%s)\n\n"),
               rule, tags[symbol]);
+      return;
     }
-  else if (redp)
+
+  for (i = 0; i < tokensetsize; i++)
+    shiftset[i] = 0;
+
+  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));
+      }
+
+  for (i = 0; i < errp->nerrs; i++)
+    if (errp->errs[i])
+      SETBIT (shiftset, errp->errs[i]);
+
+  if (state->nlookaheads == 1 && !nodefault)
     {
-      print_reductions (out, state);
-    }
+      int k;
+      int default_rule = LAruleno[state->lookaheadsp];
 
-  if (i < shiftp->nshifts)
+      for (k = 0; k < tokensetsize; ++k)
+       lookaheadset[k] = LA (state->lookaheadsp)[k] & shiftset[k];
+
+      for (i = 0; i < ntokens; i++)
+       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 (out, _("    $default\treduce using rule %d (%s)\n\n"),
+              default_rule, tags[rule_table[default_rule].lhs]);
+    }
+  else if (state->nlookaheads >= 1)
     {
-      for (; i < shiftp->nshifts; i++)
-       if (!SHIFT_IS_DISABLED (shiftp, i))
+      int cmax = 0;
+      int default_LA = -1;
+      int default_rule = 0;
+
+      if (!nodefault)
+       for (i = 0; i < state->nlookaheads; ++i)
          {
-           int state1 = shiftp->shifts[i];
-           int symbol = state_table[state1].accessing_symbol;
-           fprintf (out, _("    %-4s\tgo to state %d\n"),
-                    tags[symbol], state1);
+           int count = 0;
+           int j, k;
+
+           for (k = 0; k < tokensetsize; ++k)
+             lookaheadset[k] = LA (state->lookaheadsp + i)[k] & ~shiftset[k];
+
+           for (j = 0; j < ntokens; j++)
+             if (BITISSET (lookaheadset, j))
+               count++;
+
+           if (count > cmax)
+             {
+               cmax = count;
+               default_LA = state->lookaheadsp + i;
+               default_rule = LAruleno[state->lookaheadsp + i];
+             }
+
+           for (k = 0; k < tokensetsize; ++k)
+             shiftset[k] |= lookaheadset[k];
          }
 
-      fputc ('\n', out);
+      for (i = 0; i < tokensetsize; i++)
+       shiftset[i] = 0;
+
+      for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
+       if (!SHIFT_IS_DISABLED (shiftp, i))
+         SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
+
+      for (i = 0; i < ntokens; i++)
+       {
+         int j;
+         int defaulted = 0;
+         int count = BITISSET (shiftset, i);
+
+         for (j = 0; j < state->nlookaheads; ++j)
+           {
+             if (BITISSET (LA (state->lookaheadsp + j), i))
+               {
+                 if (count == 0)
+                   {
+                     if (state->lookaheadsp + j != default_LA)
+                       fprintf (out,
+                                _("    %-4s\treduce using rule %d (%s)\n"),
+                                tags[i],
+                                LAruleno[state->lookaheadsp + j],
+                                tags[rule_table[LAruleno[state->lookaheadsp + j]].lhs]);
+                     else
+                       defaulted = 1;
+
+                     count++;
+                   }
+                 else
+                   {
+                     if (defaulted)
+                       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"),
+                              tags[i],
+                              LAruleno[state->lookaheadsp + j],
+                              tags[rule_table[LAruleno[state->lookaheadsp + j]].lhs]);
+                   }
+               }
+           }
+       }
+
+      if (default_LA >= 0)
+       fprintf (out, _("    $default\treduce using rule %d (%s)\n"),
+                default_rule, tags[rule_table[default_rule].lhs]);
+    }
+}
+
+
+static void
+print_actions (FILE *out, state_t *state)
+{
+  reductions *redp = state->reductions;
+  shifts *shiftp = state->shifts;
+
+  if (!shiftp->nshifts && !redp)
+    {
+      if (final_state == state->number)
+       fprintf (out, _("    $default\taccept\n"));
+      else
+       fprintf (out, _("    NO ACTIONS\n"));
+      return;
     }
+
+  print_shifts (out, state);
+  print_errs (out, state);
+  if (redp)
+    print_reductions (out, state);
+  print_gotos (out, state);
 }
 
 static void
-print_state (FILE *out, int state)
+print_state (FILE *out, state_t *state)
 {
-  fprintf (out, _("state %d"), state);
+  fprintf (out, _("state %d"), state->number);
   fputs ("\n\n", out);
   print_core (out, state);
   print_actions (out, state);
@@ -314,35 +458,38 @@ print_grammar (FILE *out)
 void
 print_results (void)
 {
-  if (verbose_flag)
-    {
-      int i;
+  int i;
 
-      /* We used to use just .out if spec_name_prefix (-p) was used, but
-        that conflicts with Posix.  */
-      FILE *out = xfopen (spec_verbose_file, "w");
+  /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
+     that conflicts with Posix.  */
+  FILE *out = xfopen (spec_verbose_file, "w");
 
-      size_t size = obstack_object_size (&output_obstack);
-      fwrite (obstack_finish (&output_obstack), 1, size, out);
-      if (size)
-       fputs ("\n\n", out);
+  size_t size = obstack_object_size (&output_obstack);
+  fwrite (obstack_finish (&output_obstack), 1, size, out);
+  obstack_free (&output_obstack, NULL);
 
-      reduce_output (out);
-      conflicts_output (out);
+  if (size)
+    fputs ("\n\n", out);
 
-      print_grammar (out);
+  reduce_output (out);
+  conflicts_output (out);
 
-      /* New experimental feature: output all the items of a state,
-        not only its kernel.  Requires to run closure, which need
-        memory allocation/deallocation.  */
-      if (trace_flag)
-       new_closure (nitems);
-      for (i = 0; i < nstates; i++)
-       print_state (out, i);
-      if (trace_flag)
-       free_closure ();
+  print_grammar (out);
 
-      xfclose (out);
-    }
-  obstack_free (&output_obstack, NULL);
+  /* New experimental feature: output all the items of a state, not
+     only its kernel.  Requires to run closure, which need memory
+     allocation/deallocation.  */
+  if (trace_flag)
+    new_closure (nitems);
+  /* Storage for print_reductions.  */
+  shiftset = XCALLOC (unsigned, tokensetsize);
+  lookaheadset = XCALLOC (unsigned, tokensetsize);
+  for (i = 0; i < nstates; i++)
+    print_state (out, state_table[i]);
+  free (shiftset);
+  free (lookaheadset);
+  if (trace_flag)
+    free_closure ();
+
+  xfclose (out);
 }