]> git.saurik.com Git - bison.git/blobdiff - src/print.c
* data/lalr1.cc (parser::token_number_type, parser::rhs_number_type)
[bison.git] / src / print.c
index ec5a12ad8fa60a37f0d3b80c6f2cc1a8d3903919..7d16da5f1d2229e46bd11b9c67adfc7f7d94a067 100644 (file)
@@ -1,5 +1,6 @@
 /* Print information on generated parser, for bison,
 /* Print information on generated parser, for bison,
-   Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002
+
+   Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
 #include "system.h"
 
 
 #include "system.h"
-#include "quotearg.h"
-#include "files.h"
-#include "symtab.h"
-#include "gram.h"
+
+#include <bitset.h>
+#include <quotearg.h>
+
 #include "LR0.h"
 #include "LR0.h"
-#include "lalr.h"
+#include "closure.h"
 #include "conflicts.h"
 #include "conflicts.h"
+#include "files.h"
 #include "getargs.h"
 #include "getargs.h"
-#include "state.h"
-#include "reader.h"
+#include "gram.h"
+#include "lalr.h"
 #include "print.h"
 #include "print.h"
+#include "reader.h"
 #include "reduce.h"
 #include "reduce.h"
-#include "closure.h"
-#include "bitset.h"
+#include "state.h"
+#include "symtab.h"
 
 
-static bitset shiftset;
-static bitset lookaheadset;
+static bitset shift_set;
+static bitset look_ahead_set;
 
 #if 0
 static void
 
 #if 0
 static void
@@ -47,299 +50,382 @@ print_token (int extnum, int token)
 }
 #endif
 
 }
 #endif
 
-static inline const char *
-escape (const char *s)
-{
-  return quotearg_n_style (1, escape_quoting_style, s);
-}
+\f
+
+/*---------------------------------------.
+| *WIDTH := max (*WIDTH, strlen (STR)).  |
+`---------------------------------------*/
 
 
-/* Be cautious not to use twice the same slot in a single expression. */
-static inline const char *
-escape2 (const char *s)
+static void
+max_length (size_t *width, const char *str)
 {
 {
-  return quotearg_n_style (2, escape_quoting_style, s);
+  size_t len = strlen (str);
+  if (len > *width)
+    *width = len;
 }
 
 }
 
-\f
 /*--------------------------------.
 | Report information on a state.  |
 `--------------------------------*/
 
 static void
 /*--------------------------------.
 | Report information on a state.  |
 `--------------------------------*/
 
 static void
-print_core (FILE *out, state_t *state)
+print_core (FILE *out, state *s)
 {
 {
-  int i;
-  item_number_t *sitems = state->items;
-  int snritems   = state->nitems;
+  size_t i;
+  item_number *sitems = s->items;
+  size_t snritems = s->nitems;
+  symbol *previous_lhs = NULL;
 
 
-  /* New experimental feature: if TRACE_FLAGS output all the items of
-     a state, not only its kernel.  */
-  if (trace_flag)
+  /* Output all the items of a state, not only its kernel.  */
+  if (report_flag & report_itemsets)
     {
       closure (sitems, snritems);
       sitems = itemset;
       snritems = nritemset;
     }
 
     {
       closure (sitems, snritems);
       sitems = itemset;
       snritems = nritemset;
     }
 
-  if (snritems)
-    {
-      for (i = 0; i < snritems; i++)
-       {
-         item_number_t *sp;
-         item_number_t *sp1;
-         int rule;
+  if (!snritems)
+    return;
 
 
-         sp1 = sp = ritem + sitems[i];
+  fputc ('\n', out);
 
 
-         while (*sp >= 0)
-           sp++;
+  for (i = 0; i < snritems; i++)
+    {
+      item_number *sp;
+      item_number *sp1;
+      rule_number r;
 
 
-         rule = -(*sp);
-         fprintf (out, "    %s  ->  ", escape (rules[rule].lhs->tag));
+      sp1 = sp = ritem + sitems[i];
 
 
-         for (sp = rules[rule].rhs; sp < sp1; sp++)
-           fprintf (out, "%s ", escape (symbols[*sp]->tag));
+      while (*sp >= 0)
+       sp++;
 
 
-         fputc ('.', out);
+      r = item_number_as_rule_number (*sp);
 
 
-         for (/* Nothing */; *sp >= 0; ++sp)
-           fprintf (out, " %s", escape (symbols[*sp]->tag));
+      rule_lhs_print (&rules[r], previous_lhs, out);
+      previous_lhs = rules[r].lhs;
 
 
-         fprintf (out, _("   (rule %d)"), rule - 1);
-         fputc ('\n', out);
-       }
+      for (sp = rules[r].rhs; sp < sp1; sp++)
+       fprintf (out, " %s", symbols[*sp]->tag);
+      fputs (" .", out);
+      for (/* Nothing */; *sp >= 0; ++sp)
+       fprintf (out, " %s", symbols[*sp]->tag);
+
+      /* Display the look-ahead tokens?  */
+      if (report_flag & report_look_ahead_tokens)
+       state_rule_look_ahead_tokens_print (s, &rules[r], out);
 
       fputc ('\n', out);
     }
 }
 
 
 
       fputc ('\n', out);
     }
 }
 
 
+/*------------------------------------------------------------.
+| Report the shifts iff DISPLAY_SHIFTS_P or the gotos of S on |
+| OUT.                                                        |
+`------------------------------------------------------------*/
+
 static void
 static void
-print_shifts (FILE *out, state_t *state)
+print_transitions (state *s, FILE *out, bool display_transitions_p)
 {
 {
+  transitions *trans = s->transitions;
+  size_t width = 0;
   int i;
   int i;
-  shifts *shiftp = state->shifts;
 
 
-  for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
-    if (!SHIFT_IS_DISABLED (shiftp, i))
+  /* Compute the width of the look-ahead token column.  */
+  for (i = 0; i < trans->num; i++)
+    if (!TRANSITION_IS_DISABLED (trans, i)
+       && TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
       {
       {
-       int state1 = shiftp->shifts[i];
-       token_number_t symbol = states[state1]->accessing_symbol;
-       fprintf (out,
-                _("    %-4s\tshift, and go to state %d\n"),
-                escape (symbols[symbol]->tag), state1);
+       symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
+       max_length (&width, sym->tag);
       }
 
       }
 
-  if (i > 0)
-    fputc ('\n', out);
+  /* Nothing to report. */
+  if (!width)
+    return;
+
+  fputc ('\n', out);
+  width += 2;
+
+  /* Report look-ahead tokens and shifts.  */
+  for (i = 0; i < trans->num; i++)
+    if (!TRANSITION_IS_DISABLED (trans, i)
+       && TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
+      {
+       symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
+       const char *tag = sym->tag;
+       state *s1 = trans->states[i];
+       int j;
+
+       fprintf (out, "    %s", tag);
+       for (j = width - strlen (tag); j > 0; --j)
+         fputc (' ', out);
+       if (display_transitions_p)
+         fprintf (out, _("shift, and go to state %d\n"), s1->number);
+       else
+         fprintf (out, _("go to state %d\n"), s1->number);
+      }
 }
 
 
 }
 
 
+/*--------------------------------------------------------.
+| Report the explicit errors of S raised from %nonassoc.  |
+`--------------------------------------------------------*/
+
 static void
 static void
-print_errs (FILE *out, state_t *state)
+print_errs (FILE *out, state *s)
 {
 {
-  errs *errp = state->errs;
+  errs *errp = s->errs;
+  size_t width = 0;
   int i;
 
   int i;
 
-  for (i = 0; i < errp->nerrs; ++i)
-    if (errp->errs[i])
-      fprintf (out, _("    %-4s\terror (nonassociative)\n"),
-              escape (symbols[errp->errs[i]]->tag));
+  /* Compute the width of the look-ahead token column.  */
+  for (i = 0; i < errp->num; ++i)
+    if (errp->symbols[i])
+      max_length (&width, errp->symbols[i]->tag);
 
 
-  if (i > 0)
-    fputc ('\n', out);
+  /* Nothing to report. */
+  if (!width)
+    return;
+
+  fputc ('\n', out);
+  width += 2;
+
+  /* Report look-ahead tokens and errors.  */
+  for (i = 0; i < errp->num; ++i)
+    if (errp->symbols[i])
+      {
+       const char *tag = errp->symbols[i]->tag;
+       int j;
+       fprintf (out, "    %s", tag);
+       for (j = width - strlen (tag); j > 0; --j)
+         fputc (' ', out);
+       fputs (_("error (nonassociative)\n"), out);
+      }
 }
 
 
 }
 
 
-static void
-print_gotos (FILE *out, state_t *state)
+/*-------------------------------------------------------------.
+| Return the default rule of S if it has one, NULL otherwise.  |
+`-------------------------------------------------------------*/
+
+static rule *
+state_default_rule (state *s)
 {
 {
+  reductions *reds = s->reductions;
+  rule *default_rule = NULL;
+  int cmax = 0;
   int i;
   int i;
-  shifts *shiftp = state->shifts;
 
 
-  for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
-    /* Skip token shifts.  */;
+  /* No need for a look-ahead.  */
+  if (s->consistent)
+    return reds->rules[0];
 
 
-  if (i < shiftp->nshifts)
+  /* 1. Each reduction is possibly masked by the look-ahead tokens on which
+     we shift (S/R conflicts)...  */
+  bitset_zero (shift_set);
+  {
+    transitions *trans = s->transitions;
+    FOR_EACH_SHIFT (trans, i)
+      {
+       /* If this state has a shift for the error token, don't use a
+            default rule.  */
+       if (TRANSITION_IS_ERROR (trans, i))
+         return NULL;
+       bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
+      }
+  }
+
+  /* 2. Each reduction is possibly masked by the look-ahead tokens on which
+     we raise an error (due to %nonassoc).  */
+  {
+    errs *errp = s->errs;
+    for (i = 0; i < errp->num; i++)
+      if (errp->symbols[i])
+       bitset_set (shift_set, errp->symbols[i]->number);
+  }
+
+  for (i = 0; i < reds->num; ++i)
     {
     {
-      for (; i < shiftp->nshifts; i++)
-       if (!SHIFT_IS_DISABLED (shiftp, i))
-         {
-           int state1 = shiftp->shifts[i];
-           token_number_t symbol = states[state1]->accessing_symbol;
-           fprintf (out, _("    %-4s\tgo to state %d\n"),
-                    escape (symbols[symbol]->tag), state1);
-         }
-
-      fputc ('\n', out);
-    }
-}
+      int count = 0;
 
 
-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;
+      /* How many non-masked look-ahead tokens are there for this
+        reduction?  */
+      bitset_andn (look_ahead_set, reds->look_ahead_tokens[i], shift_set);
+      count = bitset_count (look_ahead_set);
 
 
-  if (redp->nreds == 0)
-    return;
+      if (count > cmax)
+       {
+         cmax = count;
+         default_rule = reds->rules[i];
+       }
 
 
-  if (state->consistent)
-    {
-      int rule = redp->rules[0];
-      token_number_t symbol = rules[rule].lhs->number;
-      fprintf (out, _("    $default\treduce using rule %d (%s)\n\n"),
-              rule - 1, escape (symbols[symbol]->tag));
-      return;
+      /* 3. And finally, each reduction is possibly masked by previous
+        reductions (in R/R conflicts, we keep the first reductions).
+        */
+      bitset_or (shift_set, shift_set, reds->look_ahead_tokens[i]);
     }
 
     }
 
-  bitset_zero (shiftset);
+  return default_rule;
+}
 
 
-  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;
-       bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
-      }
 
 
-  for (i = 0; i < errp->nerrs; i++)
-    if (errp->errs[i])
-      bitset_set (shiftset, errp->errs[i]);
+/*--------------------------------------------------------------------------.
+| Report a reduction of RULE on LOOK_AHEAD_TOKEN (which can be `default').  |
+| If not ENABLED, the rule is masked by a shift or a reduce (S/R and        |
+| R/R conflicts).                                                           |
+`--------------------------------------------------------------------------*/
 
 
-  if (state->nlookaheads == 1 && !nodefault)
-    {
-      rule_t *default_rule = LArule[state->lookaheadsp];
+static void
+print_reduction (FILE *out, size_t width,
+                const char *look_ahead_token,
+                rule *r, bool enabled)
+{
+  int j;
+  fprintf (out, "    %s", look_ahead_token);
+  for (j = width - strlen (look_ahead_token); j > 0; --j)
+    fputc (' ', out);
+  if (!enabled)
+    fputc ('[', out);
+  if (r->number)
+    fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
+  else
+    fprintf (out, _("accept"));
+  if (!enabled)
+    fputc (']', out);
+  fputc ('\n', out);
+}
 
 
-      bitset_and (lookaheadset, LA[state->lookaheadsp], shiftset);
 
 
-      for (i = 0; i < ntokens; i++)
-       if (bitset_test (lookaheadset, i))
-         fprintf (out, _("    %-4s\t[reduce using rule %d (%s)]\n"),
-                  escape (symbols[i]->tag),
-                  default_rule->number - 1,
-                  escape2 (default_rule->lhs->tag));
+/*-------------------------------------------.
+| Report on OUT the reduction actions of S.  |
+`-------------------------------------------*/
 
 
-      fprintf (out, _("    $default\treduce using rule %d (%s)\n\n"),
-              default_rule->number - 1,
-              escape (default_rule->lhs->tag));
-    }
-  else if (state->nlookaheads >= 1)
-    {
-      int cmax = 0;
-      int default_LA = -1;
-      rule_t *default_rule = NULL;
+static void
+print_reductions (FILE *out, state *s)
+{
+  transitions *trans = s->transitions;
+  reductions *reds = s->reductions;
+  rule *default_rule = NULL;
+  size_t width = 0;
+  int i, j;
 
 
-      if (!nodefault)
-       for (i = 0; i < state->nlookaheads; ++i)
-         {
-           int count = 0;
-           int j;
+  if (reds->num == 0)
+    return;
 
 
-           bitset_andn (lookaheadset, LA[state->lookaheadsp + i], shiftset);
+  default_rule = state_default_rule (s);
 
 
-           for (j = 0; j < ntokens; j++)
-             if (bitset_test (lookaheadset, j))
-               count++;
+  bitset_zero (shift_set);
+  FOR_EACH_SHIFT (trans, i)
+    bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
 
 
-           if (count > cmax)
-             {
-               cmax = count;
-               default_LA = state->lookaheadsp + i;
-               default_rule = LArule[state->lookaheadsp + i];
-             }
+  /* Compute the width of the look-ahead token column.  */
+  if (default_rule)
+    width = strlen (_("$default"));
 
 
-           bitset_or (shiftset, shiftset, lookaheadset);
-         }
+  if (reds->look_ahead_tokens)
+    for (i = 0; i < ntokens; i++)
+      {
+       bool count = bitset_test (shift_set, i);
 
 
-      bitset_zero (shiftset);
+       for (j = 0; j < reds->num; ++j)
+         if (bitset_test (reds->look_ahead_tokens[j], i))
+           {
+             if (! count)
+               {
+                 if (reds->rules[j] != default_rule)
+                   max_length (&width, symbols[i]->tag);
+                 count = true;
+               }
+             else
+               {
+                 max_length (&width, symbols[i]->tag);
+               }
+           }
+      }
 
 
-      for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
-       if (!SHIFT_IS_DISABLED (shiftp, i))
-         bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
+  /* Nothing to report. */
+  if (!width)
+    return;
 
 
-      for (i = 0; i < ntokens; i++)
-       {
-         int j;
-         int defaulted = 0;
-         int count = bitset_test (shiftset, i);
+  fputc ('\n', out);
+  width += 2;
 
 
-         for (j = 0; j < state->nlookaheads; ++j)
-           if (bitset_test (LA[state->lookaheadsp + j], i))
-             {
-               if (count == 0)
-                 {
-                   if (state->lookaheadsp + j != default_LA)
-                     fprintf (out,
-                              _("    %-4s\treduce using rule %d (%s)\n"),
-                              escape (symbols[i]->tag),
-                              LArule[state->lookaheadsp + j]->number - 1,
-                              escape2 (LArule[state->lookaheadsp + j]->lhs->tag));
-                   else
-                     defaulted = 1;
-
-                   count++;
-                 }
-               else
-                 {
-                   if (defaulted)
-                     fprintf (out,
-                              _("    %-4s\treduce using rule %d (%s)\n"),
-                              escape (symbols[i]->tag),
-                              LArule[default_LA]->number - 1,
-                              escape2 (LArule[default_LA]->lhs->tag));
-                   defaulted = 0;
-                   fprintf (out,
-                            _("    %-4s\t[reduce using rule %d (%s)]\n"),
-                            escape (symbols[i]->tag),
-                            LArule[state->lookaheadsp + j]->number - 1,
-                            escape2 (LArule[state->lookaheadsp + j]->lhs->tag));
-                 }
-             }
-       }
+  /* Report look-ahead tokens (or $default) and reductions.  */
+  if (reds->look_ahead_tokens)
+    for (i = 0; i < ntokens; i++)
+      {
+       bool defaulted = false;
+       bool count = bitset_test (shift_set, i);
 
 
-      if (default_LA >= 0)
-       fprintf (out, _("    $default\treduce using rule %d (%s)\n"),
-                default_rule->number - 1,
-                escape (default_rule->lhs->tag));
-    }
+       for (j = 0; j < reds->num; ++j)
+         if (bitset_test (reds->look_ahead_tokens[j], i))
+           {
+             if (! count)
+               {
+                 if (reds->rules[j] != default_rule)
+                   print_reduction (out, width,
+                                    symbols[i]->tag,
+                                    reds->rules[j], true);
+                 else
+                   defaulted = true;
+                 count = true;
+               }
+             else
+               {
+                 if (defaulted)
+                   print_reduction (out, width,
+                                    symbols[i]->tag,
+                                    default_rule, true);
+                 defaulted = false;
+                 print_reduction (out, width,
+                                  symbols[i]->tag,
+                                  reds->rules[j], false);
+               }
+           }
+      }
+
+  if (default_rule)
+    print_reduction (out, width,
+                    _("$default"), default_rule, true);
 }
 
 
 }
 
 
+/*--------------------------------------------------------------.
+| Report on OUT all the actions (shifts, gotos, reductions, and |
+| explicit erros from %nonassoc) of S.                          |
+`--------------------------------------------------------------*/
+
 static void
 static void
-print_actions (FILE *out, state_t *state)
+print_actions (FILE *out, state *s)
 {
 {
-  reductions *redp = state->reductions;
-  shifts *shiftp = state->shifts;
+  /* Print shifts.  */
+  print_transitions (s, out, true);
+  print_errs (out, s);
+  print_reductions (out, s);
+  /* Print gotos.  */
+  print_transitions (s, out, false);
+}
 
 
-  if (shiftp->nshifts == 0 && redp->nreds == 0)
-    {
-      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);
-  print_reductions (out, state);
-  print_gotos (out, state);
-}
+/*----------------------------------.
+| Report all the data on S on OUT.  |
+`----------------------------------*/
 
 static void
 
 static void
-print_state (FILE *out, state_t *state)
+print_state (FILE *out, state *s)
 {
 {
-  fprintf (out, _("state %d"), state->number);
-  fputs ("\n\n", out);
-  print_core (out, state);
-  print_actions (out, state);
   fputs ("\n\n", out);
   fputs ("\n\n", out);
+  fprintf (out, _("state %d"), s->number);
+  fputc ('\n', out);
+  print_core (out, s);
+  print_actions (out, s);
+  if ((report_flag & report_solved_conflicts) && s->solved_conflicts)
+    {
+      fputc ('\n', out);
+      fputs (s->solved_conflicts, out);
+    }
 }
 \f
 /*-----------------------------------------.
 }
 \f
 /*-----------------------------------------.
@@ -360,47 +446,33 @@ do {                                              \
 static void
 print_grammar (FILE *out)
 {
 static void
 print_grammar (FILE *out)
 {
-  token_number_t i;
-  int j;
-  item_number_t *rule;
+  symbol_number i;
   char buffer[90];
   int column = 0;
 
   char buffer[90];
   int column = 0;
 
-  /* rule # : LHS -> RHS */
-  fprintf (out, "%s\n\n", _("Grammar"));
-  fprintf (out, "  %s\n", _("Number, Line, Rule"));
-  for (j = 1; j < nrules + 1; j++)
-    {
-      fprintf (out, _("  %3d %3d %s ->"),
-              j - 1, rules[j].line, escape (rules[j].lhs->tag));
-      rule = rules[j].rhs;
-      if (*rule >= 0)
-       while (*rule >= 0)
-         fprintf (out, " %s", escape (symbols[*rule++]->tag));
-      else
-       fprintf (out, " /* %s */", _("empty"));
-      fputc ('\n', out);
-    }
-  fputs ("\n\n", out);
-
+  grammar_rules_print (out);
 
   /* TERMINAL (type #) : rule #s terminal is on RHS */
   fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
   for (i = 0; i < max_user_token_number + 1; i++)
     if (token_translations[i] != undeftoken->number)
       {
 
   /* TERMINAL (type #) : rule #s terminal is on RHS */
   fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
   for (i = 0; i < max_user_token_number + 1; i++)
     if (token_translations[i] != undeftoken->number)
       {
+       const char *tag = symbols[token_translations[i]]->tag;
+       rule_number r;
+       item_number *rhsp;
+
        buffer[0] = 0;
        buffer[0] = 0;
-       column = strlen (escape (symbols[token_translations[i]]->tag));
-       fputs (escape (symbols[token_translations[i]]->tag), out);
+       column = strlen (tag);
+       fputs (tag, out);
        END_TEST (50);
        sprintf (buffer, " (%d)", i);
 
        END_TEST (50);
        sprintf (buffer, " (%d)", i);
 
-       for (j = 1; j < nrules + 1; j++)
-         for (rule = rules[j].rhs; *rule >= 0; rule++)
-           if (item_number_as_token_number (*rule) == token_translations[i])
+       for (r = 0; r < nrules; r++)
+         for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
+           if (item_number_as_symbol_number (*rhsp) == token_translations[i])
              {
                END_TEST (65);
              {
                END_TEST (65);
-               sprintf (buffer + strlen (buffer), " %d", j - 1);
+               sprintf (buffer + strlen (buffer), " %d", r);
                break;
              }
        fprintf (out, "%s\n", buffer);
                break;
              }
        fprintf (out, "%s\n", buffer);
@@ -412,13 +484,16 @@ print_grammar (FILE *out)
   for (i = ntokens; i < nsyms; i++)
     {
       int left_count = 0, right_count = 0;
   for (i = ntokens; i < nsyms; i++)
     {
       int left_count = 0, right_count = 0;
+      rule_number r;
+      const char *tag = symbols[i]->tag;
 
 
-      for (j = 1; j < nrules + 1; j++)
+      for (r = 0; r < nrules; r++)
        {
        {
-         if (rules[j].lhs->number == i)
+         item_number *rhsp;
+         if (rules[r].lhs->number == i)
            left_count++;
            left_count++;
-         for (rule = rules[j].rhs; *rule >= 0; rule++)
-           if (item_number_as_token_number (*rule) == i)
+         for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
+           if (item_number_as_symbol_number (*rhsp) == i)
              {
                right_count++;
                break;
              {
                right_count++;
                break;
@@ -426,8 +501,8 @@ print_grammar (FILE *out)
        }
 
       buffer[0] = 0;
        }
 
       buffer[0] = 0;
-      fputs (escape (symbols[i]->tag), out);
-      column = strlen (escape (symbols[i]->tag));
+      fputs (tag, out);
+      column = strlen (tag);
       sprintf (buffer, " (%d)", i);
       END_TEST (0);
 
       sprintf (buffer, " (%d)", i);
       END_TEST (0);
 
@@ -436,11 +511,11 @@ print_grammar (FILE *out)
          END_TEST (50);
          sprintf (buffer + strlen (buffer), _(" on left:"));
 
          END_TEST (50);
          sprintf (buffer + strlen (buffer), _(" on left:"));
 
-         for (j = 1; j < nrules + 1; j++)
+         for (r = 0; r < nrules; r++)
            {
              END_TEST (65);
            {
              END_TEST (65);
-             if (rules[j].lhs->number == i)
-               sprintf (buffer + strlen (buffer), " %d", j - 1);
+             if (rules[r].lhs->number == i)
+               sprintf (buffer + strlen (buffer), " %d", r);
            }
        }
 
            }
        }
 
@@ -450,56 +525,50 @@ print_grammar (FILE *out)
            sprintf (buffer + strlen (buffer), ",");
          END_TEST (50);
          sprintf (buffer + strlen (buffer), _(" on right:"));
            sprintf (buffer + strlen (buffer), ",");
          END_TEST (50);
          sprintf (buffer + strlen (buffer), _(" on right:"));
-         for (j = 1; j < nrules + 1; j++)
+         for (r = 0; r < nrules; r++)
            {
            {
-             for (rule = rules[j].rhs; *rule >= 0; rule++)
-               if (item_number_as_token_number (*rule) == i)
+             item_number *rhsp;
+             for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
+               if (item_number_as_symbol_number (*rhsp) == i)
                  {
                    END_TEST (65);
                  {
                    END_TEST (65);
-                   sprintf (buffer + strlen (buffer), " %d", j - 1);
+                   sprintf (buffer + strlen (buffer), " %d", r);
                    break;
                  }
            }
        }
       fprintf (out, "%s\n", buffer);
     }
                    break;
                  }
            }
        }
       fprintf (out, "%s\n", buffer);
     }
-  fputs ("\n\n", out);
 }
 \f
 void
 print_results (void)
 {
 }
 \f
 void
 print_results (void)
 {
-  size_t i;
+  state_number 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);
-  obstack_free (&output_obstack, NULL);
-
-  if (size)
-    fputs ("\n\n", out);
-
   reduce_output (out);
   reduce_output (out);
+  grammar_rules_partial_print (out,
+                              _("Rules never reduced"), rule_never_reduced_p);
   conflicts_output (out);
 
   print_grammar (out);
 
   conflicts_output (out);
 
   print_grammar (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)
+  /* If the whole state item sets, not only the kernels, are wanted,
+     `closure' will be run, which needs memory allocation/deallocation.   */
+  if (report_flag & report_itemsets)
     new_closure (nritems);
   /* Storage for print_reductions.  */
     new_closure (nritems);
   /* Storage for print_reductions.  */
-  shiftset =  bitset_create (ntokens, BITSET_FIXED);
-  lookaheadset = bitset_create (ntokens, BITSET_FIXED);
+  shift_set =  bitset_create (ntokens, BITSET_FIXED);
+  look_ahead_set = bitset_create (ntokens, BITSET_FIXED);
   for (i = 0; i < nstates; i++)
     print_state (out, states[i]);
   for (i = 0; i < nstates; i++)
     print_state (out, states[i]);
-  bitset_free (shiftset);
-  bitset_free (lookaheadset);
-  if (trace_flag)
+  bitset_free (shift_set);
+  bitset_free (look_ahead_set);
+  if (report_flag & report_itemsets)
     free_closure ();
 
   xfclose (out);
     free_closure ();
 
   xfclose (out);