]> git.saurik.com Git - bison.git/blobdiff - src/print.c
Version 2.4.1.
[bison.git] / src / print.c
index 9ed6919e5b42b04f48f2c8e1e59cbc609cc50cd5..ddd76a60ff01e539ce953ce8af950cce5b15f5c8 100644 (file)
@@ -1,43 +1,44 @@
 /* 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, 2005, 2007
    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.
 
-   Bison is free software; you can redistribute it and/or modify
+   This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
 
-   Bison is distributed in the hope that it will be useful,
+   This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
+#include <config.h>
 #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"
+#include "tables.h"
 
 
-static bitset shiftset;
-static bitset lookaheadset;
+static bitset no_reduce_set;
 
 #if 0
 static void
 
 #if 0
 static void
@@ -48,298 +49,321 @@ print_token (int extnum, int token)
 #endif
 
 \f
 #endif
 
 \f
+
+/*---------------------------------------.
+| *WIDTH := max (*WIDTH, strlen (STR)).  |
+`---------------------------------------*/
+
+static void
+max_length (size_t *width, const char *str)
+{
+  size_t len = strlen (str);
+  if (len > *width)
+    *width = len;
+}
+
 /*--------------------------------.
 | 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;
 
   /* Output all the items of a state, not only its kernel.  */
   if (report_flag & report_itemsets)
     {
       closure (sitems, snritems);
       sitems = itemset;
 
   /* Output all the items of a state, not only its kernel.  */
   if (report_flag & report_itemsets)
     {
       closure (sitems, snritems);
       sitems = itemset;
-      snritems = nritemset;
+      snritems = nitemset;
     }
 
     }
 
-  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  ->  ", symbol_tag_get (rules[rule].lhs));
+      sp1 = sp = ritem + sitems[i];
 
 
-         for (sp = rules[rule].rhs; sp < sp1; sp++)
-           fprintf (out, "%s ", symbol_tag_get (symbols[*sp]));
+      while (*sp >= 0)
+       sp++;
 
 
-         fputc ('.', out);
+      r = item_number_as_rule_number (*sp);
 
 
-         for (/* Nothing */; *sp >= 0; ++sp)
-           fprintf (out, " %s", symbol_tag_get (symbols[*sp]));
+      rule_lhs_print (&rules[r], previous_lhs, out);
+      previous_lhs = rules[r].lhs;
 
 
-         /* Display the lookaheads?  */
-         if (report_flag & report_lookaheads)
-           state_rule_lookaheads_print (state, &rules[rule], 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);
 
 
-         fprintf (out, _("   (rule %d)"), rule - 1);
-         fputc ('\n', out);
-       }
+      /* Display the lookahead tokens?  */
+      if (report_flag & report_lookahead_tokens
+          && item_number_is_rule_number (*sp1))
+       state_rule_lookahead_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_t *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 lookahead token column.  */
+  for (i = 0; i < trans->num; i++)
+    if (!TRANSITION_IS_DISABLED (trans, i)
+       && TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
       {
       {
-       state_number_t state1 = shiftp->shifts[i];
-       symbol_number_t symbol = states[state1]->accessing_symbol;
-       fprintf (out,
-                _("    %-4s\tshift, and go to state %d\n"),
-                symbol_tag_get (symbols[symbol]), state1);
+       symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
+       max_length (&width, sym->tag);
       }
 
       }
 
-  if (i > 0)
-    fputc ('\n', out);
-}
-
-
-static void
-print_errs (FILE *out, state_t *state)
-{
-  errs_t *errp = state->errs;
-  int i;
+  /* Nothing to report. */
+  if (!width)
+    return;
 
 
-  for (i = 0; i < errp->nerrs; ++i)
-    if (errp->errs[i])
-      fprintf (out, _("    %-4s\terror (nonassociative)\n"),
-              symbol_tag_get (symbols[errp->errs[i]]));
+  fputc ('\n', out);
+  width += 2;
 
 
-  if (i > 0)
-    fputc ('\n', out);
+  /* Report lookahead 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_gotos (FILE *out, state_t *state)
+print_errs (FILE *out, state *s)
 {
 {
+  errs *errp = s->errs;
+  size_t width = 0;
   int i;
   int i;
-  shifts_t *shiftp = state->shifts;
 
 
-  for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
-    /* Skip token shifts.  */;
+  /* Compute the width of the lookahead token column.  */
+  for (i = 0; i < errp->num; ++i)
+    if (errp->symbols[i])
+      max_length (&width, errp->symbols[i]->tag);
 
 
-  if (i < shiftp->nshifts)
-    {
-      for (; i < shiftp->nshifts; i++)
-       if (!SHIFT_IS_DISABLED (shiftp, i))
-         {
-           state_number_t state1 = shiftp->shifts[i];
-           symbol_number_t symbol = states[state1]->accessing_symbol;
-           fprintf (out, _("    %-4s\tgo to state %d\n"),
-                    symbol_tag_get (symbols[symbol]), state1);
-         }
+  /* Nothing to report. */
+  if (!width)
+    return;
 
 
-      fputc ('\n', out);
-    }
+  fputc ('\n', out);
+  width += 2;
+
+  /* Report lookahead 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);
+      }
 }
 
 
 }
 
 
-/*----------------------------------------------------------.
-| Return the default rule of this STATE if it has one, NULL |
-| otherwise.                                                |
-`----------------------------------------------------------*/
+/*-------------------------------------------------------------------------.
+| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default').  |
+| If not ENABLED, the rule is masked by a shift or a reduce (S/R and       |
+| R/R conflicts).                                                          |
+`-------------------------------------------------------------------------*/
 
 
-static rule_t *
-state_default_rule_compute (state_t *state)
+static void
+print_reduction (FILE *out, size_t width,
+                const char *lookahead_token,
+                rule *r, bool enabled)
 {
 {
-  reductions_t *redp = state->reductions;
-  rule_t *default_rule = NULL;
-  int cmax = 0;
-  int i;
+  int j;
+  fprintf (out, "    %s", lookahead_token);
+  for (j = width - strlen (lookahead_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);
+}
 
 
-  /* No need for a lookahead.  */
-  if (state->consistent)
-    return &rules[redp->rules[0]];
-
-  /* 1. Each reduction is possibly masked by the lookaheads on which
-     we shift (S/R conflicts)...  */
-  bitset_zero (shiftset);
-  {
-    shifts_t *shiftp = state->shifts;
-    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))
-           return NULL;
-         bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
-       }
-  }
-
-  /* 2. Each reduction is possibly masked by the lookaheads on which
-     we raise an error (due to %nonassoc).  */
-  {
-    errs_t *errp = state->errs;
-    for (i = 0; i < errp->nerrs; i++)
-      if (errp->errs[i])
-       bitset_set (shiftset, errp->errs[i]);
-  }
-
-  for (i = 0; i < state->nlookaheads; ++i)
-    {
-      int count = 0;
 
 
-      /* How many non-masked lookaheads are there for this reduction?
-        */
-      bitset_andn (lookaheadset, state->lookaheads[i], shiftset);
-      count = bitset_count (lookaheadset);
+/*-------------------------------------------.
+| Report on OUT the reduction actions of S.  |
+`-------------------------------------------*/
 
 
-      if (count > cmax)
-       {
-         cmax = count;
-         default_rule = state->lookaheads_rule[i];
-       }
+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;
 
 
-      /* 3. And finally, each reduction is possibly masked by previous
-        reductions (in R/R conflicts, we keep the first reductions).
-        */
-      bitset_or (shiftset, shiftset, state->lookaheads[i]);
-    }
+  if (reds->num == 0)
+    return;
 
 
-  return default_rule;
-}
+  if (yydefact[s->number] != 0)
+    default_rule = &rules[yydefact[s->number] - 1];
 
 
+  bitset_zero (no_reduce_set);
+  FOR_EACH_SHIFT (trans, i)
+    bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
+  for (i = 0; i < s->errs->num; ++i)
+    if (s->errs->symbols[i])
+      bitset_set (no_reduce_set, s->errs->symbols[i]->number);
 
 
-/*----------------------------------------------------.
-| Report on OUT the reduction actions of this STATE.  |
-`----------------------------------------------------*/
+  /* Compute the width of the lookahead token column.  */
+  if (default_rule)
+    width = strlen (_("$default"));
 
 
-static void
-print_reductions (FILE *out, state_t *state)
-{
-  int i;
-  shifts_t *shiftp = state->shifts;
-  reductions_t *redp = state->reductions;
-  rule_t *default_rule = NULL;
+  if (reds->lookahead_tokens)
+    for (i = 0; i < ntokens; i++)
+      {
+       bool count = bitset_test (no_reduce_set, i);
+
+       for (j = 0; j < reds->num; ++j)
+         if (bitset_test (reds->lookahead_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);
+               }
+           }
+      }
 
 
-  if (redp->nreds == 0)
+  /* Nothing to report. */
+  if (!width)
     return;
 
     return;
 
-  default_rule = state_default_rule_compute (state);
+  fputc ('\n', out);
+  width += 2;
 
 
-  bitset_zero (shiftset);
-  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));
+  /* Report lookahead tokens (or $default) and reductions.  */
+  if (reds->lookahead_tokens)
+    for (i = 0; i < ntokens; i++)
+      {
+       bool defaulted = false;
+       bool count = bitset_test (no_reduce_set, i);
 
 
-  for (i = 0; i < ntokens; i++)
-    {
-      int j;
-      int defaulted = 0;
-      int count = bitset_test (shiftset, i);
-
-      for (j = 0; j < state->nlookaheads; ++j)
-       if (bitset_test (state->lookaheads[j], i))
-         {
-           if (count == 0)
-             {
-               if (state->lookaheads_rule[j] != default_rule)
-                 fprintf (out,
-                          _("    %-4s\treduce using rule %d (%s)\n"),
-                          symbol_tag_get (symbols[i]),
-                          state->lookaheads_rule[j]->number - 1,
-                          symbol_tag_get_n (state->lookaheads_rule[j]->lhs, 1));
-               else
-                 defaulted = 1;
-               count++;
-             }
-           else
-             {
-               if (defaulted)
-                 fprintf (out,
-                          _("    %-4s\treduce using rule %d (%s)\n"),
-                          symbol_tag_get (symbols[i]),
-                          default_rule->number - 1,
-                          symbol_tag_get_n (default_rule->lhs, 1));
-               defaulted = 0;
-               fprintf (out,
-                        _("    %-4s\t[reduce using rule %d (%s)]\n"),
-                        symbol_tag_get (symbols[i]),
-                        state->lookaheads_rule[j]->number - 1,
-                        symbol_tag_get_n (state->lookaheads_rule[j]->lhs, 1));
-             }
-         }
-    }
+       for (j = 0; j < reds->num; ++j)
+         if (bitset_test (reds->lookahead_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)
 
   if (default_rule)
-    fprintf (out, _("    $default\treduce using rule %d (%s)\n"),
-            default_rule->number - 1,
-            symbol_tag_get (default_rule->lhs));
-  fputc ('\n', out);
+    print_reduction (out, width,
+                    _("$default"), default_rule, true);
 }
 
 
 /*--------------------------------------------------------------.
 | Report on OUT all the actions (shifts, gotos, reductions, and |
 }
 
 
 /*--------------------------------------------------------------.
 | Report on OUT all the actions (shifts, gotos, reductions, and |
-| explicit erros from %nonassoc) of STATE.                      |
+| explicit erros from %nonassoc) of S.                          |
 `--------------------------------------------------------------*/
 
 static void
 `--------------------------------------------------------------*/
 
 static void
-print_actions (FILE *out, state_t *state)
+print_actions (FILE *out, state *s)
 {
 {
-  reductions_t *redp = state->reductions;
-  shifts_t *shiftp = state->shifts;
-
-  if (shiftp->nshifts == 0 && redp->nreds == 0)
-    {
-      if (state->number == final_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);
+  /* Print shifts.  */
+  print_transitions (s, out, true);
+  print_errs (out, s);
+  print_reductions (out, s);
+  /* Print gotos.  */
+  print_transitions (s, out, false);
 }
 
 
 }
 
 
+/*----------------------------------.
+| 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);
-  if ((report_flag & report_solved_conflicts)
-      && state->solved_conflicts)
-    fputs (state->solved_conflicts, out);
   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,7 +384,7 @@ do {                                                \
 static void
 print_grammar (FILE *out)
 {
 static void
 print_grammar (FILE *out)
 {
-  symbol_number_t i;
+  symbol_number i;
   char buffer[90];
   int column = 0;
 
   char buffer[90];
   int column = 0;
 
@@ -371,22 +395,22 @@ print_grammar (FILE *out)
   for (i = 0; i < max_user_token_number + 1; i++)
     if (token_translations[i] != undeftoken->number)
       {
   for (i = 0; i < max_user_token_number + 1; i++)
     if (token_translations[i] != undeftoken->number)
       {
-       const char *tag = symbol_tag_get (symbols[token_translations[i]]);
-       rule_number_t r;
-       item_number_t *rhsp;
+       const char *tag = symbols[token_translations[i]]->tag;
+       rule_number r;
+       item_number *rhsp;
 
        buffer[0] = 0;
        column = strlen (tag);
        fputs (tag, out);
 
        buffer[0] = 0;
        column = strlen (tag);
        fputs (tag, out);
-       END_TEST (50);
+       END_TEST (65);
        sprintf (buffer, " (%d)", i);
 
        sprintf (buffer, " (%d)", i);
 
-       for (r = 1; r < nrules + 1; r++)
+       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);
          for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
            if (item_number_as_symbol_number (*rhsp) == token_translations[i])
              {
                END_TEST (65);
-               sprintf (buffer + strlen (buffer), " %d", r - 1);
+               sprintf (buffer + strlen (buffer), " %d", r);
                break;
              }
        fprintf (out, "%s\n", buffer);
                break;
              }
        fprintf (out, "%s\n", buffer);
@@ -398,12 +422,12 @@ 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_t r;
-      const char *tag = symbol_tag_get (symbols[i]);
+      rule_number r;
+      const char *tag = symbols[i]->tag;
 
 
-      for (r = 1; r < nrules + 1; r++)
+      for (r = 0; r < nrules; r++)
        {
        {
-         item_number_t *rhsp;
+         item_number *rhsp;
          if (rules[r].lhs->number == i)
            left_count++;
          for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
          if (rules[r].lhs->number == i)
            left_count++;
          for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
@@ -422,14 +446,16 @@ print_grammar (FILE *out)
 
       if (left_count > 0)
        {
 
       if (left_count > 0)
        {
-         END_TEST (50);
+         END_TEST (65);
          sprintf (buffer + strlen (buffer), _(" on left:"));
 
          sprintf (buffer + strlen (buffer), _(" on left:"));
 
-         for (r = 1; r < nrules + 1; r++)
+         for (r = 0; r < nrules; r++)
            {
            {
-             END_TEST (65);
              if (rules[r].lhs->number == i)
              if (rules[r].lhs->number == i)
-               sprintf (buffer + strlen (buffer), " %d", r - 1);
+               {
+                 END_TEST (65);
+                 sprintf (buffer + strlen (buffer), " %d", r);
+               }
            }
        }
 
            }
        }
 
@@ -437,35 +463,37 @@ print_grammar (FILE *out)
        {
          if (left_count > 0)
            sprintf (buffer + strlen (buffer), ",");
        {
          if (left_count > 0)
            sprintf (buffer + strlen (buffer), ",");
-         END_TEST (50);
+         END_TEST (65);
          sprintf (buffer + strlen (buffer), _(" on right:"));
          sprintf (buffer + strlen (buffer), _(" on right:"));
-         for (r = 1; r < nrules + 1; r++)
+         for (r = 0; r < nrules; r++)
            {
            {
-             item_number_t *rhsp;
+             item_number *rhsp;
              for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
                if (item_number_as_symbol_number (*rhsp) == i)
                  {
                    END_TEST (65);
              for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
                if (item_number_as_symbol_number (*rhsp) == i)
                  {
                    END_TEST (65);
-                   sprintf (buffer + strlen (buffer), " %d", r - 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)
 {
-  state_number_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");
 
   reduce_output (out);
 
   /* 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");
 
   reduce_output (out);
+  grammar_rules_partial_print (out,
+                              _("Rules useless in parser due to conflicts"),
+                                 rule_useless_in_parser_p);
   conflicts_output (out);
 
   print_grammar (out);
   conflicts_output (out);
 
   print_grammar (out);
@@ -475,12 +503,10 @@ print_results (void)
   if (report_flag & report_itemsets)
     new_closure (nritems);
   /* Storage for print_reductions.  */
   if (report_flag & report_itemsets)
     new_closure (nritems);
   /* Storage for print_reductions.  */
-  shiftset =  bitset_create (ntokens, BITSET_FIXED);
-  lookaheadset = bitset_create (ntokens, BITSET_FIXED);
+  no_reduce_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);
+  bitset_free (no_reduce_set);
   if (report_flag & report_itemsets)
     free_closure ();
 
   if (report_flag & report_itemsets)
     free_closure ();