]> git.saurik.com Git - bison.git/commitdiff
Copy BYacc's nice way to report the grammar.
authorAkim Demaille <akim@epita.fr>
Sat, 15 Jun 2002 18:23:12 +0000 (18:23 +0000)
committerAkim Demaille <akim@epita.fr>
Sat, 15 Jun 2002 18:23:12 +0000 (18:23 +0000)
* src/gram.h, src/gram.c (grammar_rhs_print, grammar_rules_print):
New.
Don't print the rules' location, it is confusing and useless.
(rule_print): Use grammar_rhs_print.
* src/print.c (print_grammar): Use grammar_rules_print.

16 files changed:
ChangeLog
NEWS
src/LR0.c
src/closure.c
src/gram.c
src/gram.h
src/lalr.c
src/output.c
src/print.c
src/print_graph.c
src/reduce.c
src/symtab.c
src/symtab.h
tests/conflicts.at
tests/reduce.at
tests/regression.at

index 27a927b0a6d253e37dcb41dcb7aa6dc52f4c20a6..4995682a312f347e23ad1daa4120b966a1e83a49 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2002-06-15  Akim Demaille  <akim@epita.fr>
+
+       Copy BYacc's nice way to report the grammar.
+
+       * src/gram.h, src/gram.c (grammar_rhs_print, grammar_rules_print):
+       New.
+       Don't print the rules' location, it is confusing and useless.
+       (rule_print): Use grammar_rhs_print.
+       * src/print.c (print_grammar): Use grammar_rules_print.
+
+       
+2002-06-15  Akim Demaille  <akim@epita.fr>
+
+       Complete and rationalize `useless thing' warnings.
+
+       * src/symtab.h, src/symtab.c (symbol_tag_get, symbol_tag_get_n)
+       (symbol_tag_print): New.
+       Use them everywhere in place of accessing directly the tag member.
+       * src/gram.h, src/gram.c (rule_print): New.
+       Use it where a rule used to be printed `by hand'.
+       * src/reduce.c (nonterminals_reduce): Report the use nonterminals.
+       (reduce_grammar_tables): Report the useless rules.
+       (reduce_print): Useless things are a warning, not an error.
+       Report it as such.
+       * tests/reduce.at (Useless Nonterminals, Useless Rules):
+       (Reduced Automaton, Underivable Rules): Adjust.
+       * tests/regression.at (Web2c Report, Web2c Report): Adjust.
+       * tests/conflicts.at (Unresolved SR Conflicts)
+       (Solved SR Conflicts): Adjust.
+
+       
 2002-06-15  Akim Demaille  <akim@epita.fr>
 
        Let symbols have a location.
 2002-06-15  Akim Demaille  <akim@epita.fr>
 
        Let symbols have a location.
diff --git a/NEWS b/NEWS
index 64258f23752c46f941e11eedb1b4aa9434630390..0dc405427086f70fc03682821e6d498b71747fe0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -42,6 +42,9 @@ Changes in version 1.49b:
   Before, Bison reported the useless rules, but, although not used,
   included them in the parsers.  They are now actually removed.
 
   Before, Bison reported the useless rules, but, although not used,
   included them in the parsers.  They are now actually removed.
 
+* Useless rules, useless nonterminals
+  They are now reported, as a warning, with their locations.
+
 * Incorrect `Token not used'
   On a grammar such as
 
 * Incorrect `Token not used'
   On a grammar such as
 
index efe9589ac946e7f657bf6ba39abec5da42566642..95200d53d8b27f1f5869cece72912e4bbd42f17c 100644 (file)
--- a/src/LR0.c
+++ b/src/LR0.c
@@ -191,8 +191,7 @@ new_state (symbol_number_t symbol, size_t core_size, item_number_t *core)
 
   if (trace_flag)
     fprintf (stderr, "Entering new_state, state = %d, symbol = %d (%s)\n",
 
   if (trace_flag)
     fprintf (stderr, "Entering new_state, state = %d, symbol = %d (%s)\n",
-            nstates, symbol, quotearg_style (escape_quoting_style,
-                                             symbols[symbol]->tag));
+            nstates, symbol, symbol_tag_get (symbols[symbol]));
 
   if (nstates >= SHRT_MAX)
     fatal (_("too many states (max %d)"), SHRT_MAX);
 
   if (nstates >= SHRT_MAX)
     fatal (_("too many states (max %d)"), SHRT_MAX);
@@ -237,8 +236,8 @@ get_state (symbol_number_t symbol, size_t core_size, item_number_t *core)
 
   if (trace_flag)
     fprintf (stderr, "Entering get_state, state = %d, symbol = %d (%s)\n",
 
   if (trace_flag)
     fprintf (stderr, "Entering get_state, state = %d, symbol = %d (%s)\n",
-            this_state->number, symbol, quotearg_style (escape_quoting_style,
-                                             symbols[symbol]->tag));
+            this_state->number, symbol,
+            symbol_tag_get (symbols[symbol]));
 
   /* Add up the target state's active item numbers to get a hash key.
      */
 
   /* Add up the target state's active item numbers to get a hash key.
      */
@@ -424,8 +423,7 @@ generate_states (void)
       if (trace_flag)
        fprintf (stderr, "Processing state %d (reached by %s)\n",
                 this_state->number,
       if (trace_flag)
        fprintf (stderr, "Processing state %d (reached by %s)\n",
                 this_state->number,
-                quotearg_style (escape_quoting_style,
-                                symbols[this_state->accessing_symbol]->tag));
+                symbol_tag_get (symbols[this_state->accessing_symbol]));
       /* Set up ruleset and itemset for the transitions out of this
          state.  ruleset gets a 1 bit for each rule that could reduce
          now.  itemset gets a vector of all the items that could be
       /* Set up ruleset and itemset for the transitions out of this
          state.  ruleset gets a 1 bit for each rule that could reduce
          now.  itemset gets a vector of all the items that could be
index 928b686747127ab507e902a0cc754fdedbcd3d99..ea64250ea5aa9cf1741b26bc6a81c058f5974fac 100644 (file)
@@ -59,8 +59,7 @@ print_closure (const char *title, item_number_t *array, size_t size)
       item_number_t *rp;
       fprintf (stderr, "  %2d: .", array[i]);
       for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
       item_number_t *rp;
       fprintf (stderr, "  %2d: .", array[i]);
       for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
-       fprintf (stderr, " %s",
-                quotearg_style (escape_quoting_style, symbols[*rp]->tag));
+       fprintf (stderr, " %s", symbol_tag_get (symbols[*rp]));
       fprintf (stderr, "  (rule %d)\n", -*rp - 1);
     }
   fputs ("\n\n", stderr);
       fprintf (stderr, "  (rule %d)\n", -*rp - 1);
     }
   fputs ("\n\n", stderr);
@@ -75,13 +74,11 @@ print_firsts (void)
   fprintf (stderr, "FIRSTS\n");
   for (i = ntokens; i < nsyms; i++)
     {
   fprintf (stderr, "FIRSTS\n");
   for (i = ntokens; i < nsyms; i++)
     {
-      fprintf (stderr, "\t%s firsts\n",
-              quotearg_style (escape_quoting_style, symbols[i]->tag));
+      fprintf (stderr, "\t%s firsts\n", symbol_tag_get (symbols[i]));
       for (j = 0; j < nvars; j++)
        if (bitset_test (FIRSTS (i), j))
          fprintf (stderr, "\t\t%s\n",
       for (j = 0; j < nvars; j++)
        if (bitset_test (FIRSTS (i), j))
          fprintf (stderr, "\t\t%s\n",
-                  quotearg_style (escape_quoting_style,
-                                  symbols[j + ntokens]->tag));
+                  symbol_tag_get (symbols[j + ntokens]));
     }
   fprintf (stderr, "\n\n");
 }
     }
   fprintf (stderr, "\n\n");
 }
@@ -95,17 +92,14 @@ print_fderives (void)
   fprintf (stderr, "FDERIVES\n");
   for (i = ntokens; i < nsyms; i++)
     {
   fprintf (stderr, "FDERIVES\n");
   for (i = ntokens; i < nsyms; i++)
     {
-      fprintf (stderr, "\t%s derives\n",
-              quotearg_style (escape_quoting_style, symbols[i]->tag));
+      fprintf (stderr, "\t%s derives\n", symbol_tag_get (symbols[i]));
       for (j = 0; j < nrules + 1; j++)
        if (bitset_test (FDERIVES (i), j))
          {
            item_number_t *rhsp;
            fprintf (stderr, "\t\t%d:", j - 1);
            for (rhsp = rules[j].rhs; *rhsp >= 0; ++rhsp)
       for (j = 0; j < nrules + 1; j++)
        if (bitset_test (FDERIVES (i), j))
          {
            item_number_t *rhsp;
            fprintf (stderr, "\t\t%d:", j - 1);
            for (rhsp = rules[j].rhs; *rhsp >= 0; ++rhsp)
-             fprintf (stderr, " %s",
-                      quotearg_style (escape_quoting_style,
-                                      symbols[*rhsp]->tag));
+             fprintf (stderr, " %s", symbol_tag_get (symbols[*rhsp]));
            fputc ('\n', stderr);
          }
     }
            fputc ('\n', stderr);
          }
     }
index 90a0b527cb29c1e435d40d27419a497c6231228e..a1a0630853becd869f8466bfefead9b215eb454b 100644 (file)
@@ -26,7 +26,7 @@
 #include "reduce.h"
 #include "reader.h"
 
 #include "reduce.h"
 #include "reader.h"
 
-/* comments for these variables are in gram.h  */
+/* Comments for these variables are in gram.h.  */
 
 item_number_t *ritem = NULL;
 unsigned int nritems = 0;
 
 item_number_t *ritem = NULL;
 unsigned int nritems = 0;
@@ -61,6 +61,39 @@ rule_rhs_length (rule_t *rule)
 }
 
 
 }
 
 
+/*-------------------------------.
+| Print this RULE's RHS on OUT.  |
+`-------------------------------*/
+
+void
+rule_rhs_print (rule_t *rule, FILE *out)
+{
+  if (*rule->rhs >= 0)
+    {
+      item_number_t *r;
+      for (r = rule->rhs; *r >= 0; r++)
+       fprintf (out, " %s", symbol_tag_get (symbols[*r]));
+      fputc ('\n', out);
+    }
+  else
+    {
+      fprintf (out, " /* %s */\n", _("empty"));
+    }
+}
+
+
+/*-------------------------.
+| Print this RULE on OUT.  |
+`-------------------------*/
+
+void
+rule_print (rule_t *rule, FILE *out)
+{
+  fprintf (out, "%s:", symbol_tag_get (rule->lhs));
+  rule_rhs_print (rule, out);
+}
+
+
 /*------------------------.
 | Dump RITEM for traces.  |
 `------------------------*/
 /*------------------------.
 | Dump RITEM for traces.  |
 `------------------------*/
@@ -72,8 +105,7 @@ ritem_print (FILE *out)
   fputs ("RITEM\n", out);
   for (i = 0; i < nritems; ++i)
     if (ritem[i] >= 0)
   fputs ("RITEM\n", out);
   for (i = 0; i < nritems; ++i)
     if (ritem[i] >= 0)
-      fprintf (out, "  %s", quotearg_style (escape_quoting_style,
-                                           symbols[ritem[i]]->tag));
+      fprintf (out, "  %s", symbol_tag_get (symbols[ritem[i]]));
     else
       fprintf (out, "  (rule %d)\n", -ritem[i] - 1);
   fputs ("\n\n", out);
     else
       fprintf (out, "  (rule %d)\n", -ritem[i] - 1);
   fputs ("\n\n", out);
@@ -101,6 +133,46 @@ ritem_longest_rhs (void)
 }
 
 
 }
 
 
+/*-----------------------------------.
+| Print the grammar's rules on OUT.  |
+`-----------------------------------*/
+
+static inline void
+blanks_print (unsigned n, FILE *out)
+{
+  for (/* Nothing*/; n > 0; --n)
+    fputc (' ', out);
+}
+
+void
+grammar_rules_print (FILE *out)
+{
+  int r;
+  symbol_t *last_lhs = NULL;
+
+  /* rule # : LHS -> RHS */
+  fprintf (out, "%s\n\n", _("Grammar"));
+  for (r = 1; r < nrules + 1; r++)
+    {
+      if (last_lhs && last_lhs != rules[r].lhs)
+       fputc ('\n', out);
+
+      fprintf (out, "  %3d ", r - 1);
+      if (last_lhs != rules[r].lhs)
+       {
+         last_lhs = rules[r].lhs;
+         fprintf (out, "%s:", symbol_tag_get (last_lhs));
+       }
+      else
+       {
+         blanks_print (strlen (symbol_tag_get (last_lhs)), out);
+         fputc ('|', out);
+       }
+      rule_rhs_print (&rules[r], out);
+    }
+  fputs ("\n\n", out);
+}
+
 /*-------------------.
 | Dump the grammar.  |
 `-------------------*/
 /*-------------------.
 | Dump the grammar.  |
 `-------------------*/
@@ -121,7 +193,7 @@ grammar_dump (FILE *out, const char *title)
     fprintf (out, "%5d  %5d   %5d  %s\n",
             i,
             symbols[i]->prec, symbols[i]->assoc,
     fprintf (out, "%5d  %5d   %5d  %s\n",
             i,
             symbols[i]->prec, symbols[i]->assoc,
-            quotearg_style (escape_quoting_style, symbols[i]->tag));
+            symbol_tag_get (symbols[i]));
   fprintf (out, "\n\n");
   fprintf (out, "Rules\n-----\n\n");
   fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n");
   fprintf (out, "\n\n");
   fprintf (out, "Rules\n-----\n\n");
   fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n");
@@ -148,12 +220,8 @@ grammar_dump (FILE *out, const char *title)
   fprintf (out, "Rules interpreted\n-----------------\n\n");
   for (i = 1; i < nrules + nuseless_productions + 1; i++)
     {
   fprintf (out, "Rules interpreted\n-----------------\n\n");
   for (i = 1; i < nrules + nuseless_productions + 1; i++)
     {
-      fprintf (out, "%-5d  %s :",
-              i, quotearg_style (escape_quoting_style, rules[i].lhs->tag));
-      for (r = rules[i].rhs; *r >= 0; r++)
-       fprintf (out, " %s",
-                quotearg_style (escape_quoting_style, symbols[*r]->tag));
-      fputc ('\n', out);
+      fprintf (out, "%-5d  ", i);
+      rule_print (&rules[i], out);
     }
   fprintf (out, "\n\n");
 }
     }
   fprintf (out, "\n\n");
 }
index ff43ab8f4063c7d02c5d2e0e1933c9001c6219b2..962b9adbf1c2ad2e9e76e9625510563bef1f5282 100644 (file)
@@ -168,15 +168,24 @@ extern int max_user_token_number;
 
 extern int pure_parser;
 
 
 extern int pure_parser;
 
-/* Report the length of the RHS. */
+/* Return the length of the RHS.  */
 int rule_rhs_length PARAMS ((rule_t *rule));
 
 int rule_rhs_length PARAMS ((rule_t *rule));
 
+/* Print this RULE's RHS on OUT.  */
+void rule_rhs_print PARAMS ((rule_t *rule, FILE *out));
+
+/* Print this RULE on OUT.  */
+void rule_print PARAMS ((rule_t *rule, FILE *out));
+
 /* Dump RITEM for traces. */
 void ritem_print PARAMS ((FILE *out));
 
 /* Return the size of the longest rule RHS.  */
 size_t ritem_longest_rhs PARAMS ((void));
 
 /* Dump RITEM for traces. */
 void ritem_print PARAMS ((FILE *out));
 
 /* Return the size of the longest rule RHS.  */
 size_t ritem_longest_rhs PARAMS ((void));
 
+/* Print the grammar's rules on OUT.  */
+void grammar_rules_print PARAMS ((FILE *out));
+
 /* Dump the grammar. */
 void grammar_dump PARAMS ((FILE *out, const char *title));
 
 /* Dump the grammar. */
 void grammar_dump PARAMS ((FILE *out, const char *title));
 
index f3f37a7312028182167271cda6e5d072179d6d3a..dfc06bc9105343a7017facb8437fcb59003b7b23 100644 (file)
@@ -565,7 +565,7 @@ lookaheads_print (FILE *out)
        for (k = 0; k < ntokens; ++k)
          if (bitset_test (LA[states[i]->lookaheadsp + j], k))
            fprintf (out, "   on %d (%s) -> rule %d\n",
        for (k = 0; k < ntokens; ++k)
          if (bitset_test (LA[states[i]->lookaheadsp + j], k))
            fprintf (out, "   on %d (%s) -> rule %d\n",
-                    k, quotearg_style (escape_quoting_style, symbols[k]->tag),
+                    k, symbol_tag_get (symbols[k]),
                     LArule[states[i]->lookaheadsp + j]->number - 1);
     }
   fprintf (out, "Lookaheads: END\n");
                     LArule[states[i]->lookaheadsp + j]->number - 1);
     }
   fprintf (out, "Lookaheads: END\n");
index 832f4ed9037319e98ccab02cc09b99ef951151f6..7ee3214cab0b577e284062e0db82b7ae466529f1 100644 (file)
@@ -235,11 +235,11 @@ prepare_tokens (void)
     int j = 0;
     for (i = 0; i < nsyms; i++)
       {
     int j = 0;
     for (i = 0; i < nsyms; i++)
       {
-       /* Be sure not to use twice the same quotearg slot. */
+       /* Be sure not to use twice the same QUOTEARG slot:
+          SYMBOL_TAG_GET uses slot 0.  */
        const char *cp =
          quotearg_n_style (1, c_quoting_style,
        const char *cp =
          quotearg_n_style (1, c_quoting_style,
-                           quotearg_style (escape_quoting_style,
-                                           symbols[i]->tag));
+                           symbol_tag_get (symbols[i]));
        /* Width of the next token, including the two quotes, the coma
           and the space.  */
        int strsize = strlen (cp) + 2;
        /* Width of the next token, including the two quotes, the coma
           and the space.  */
        int strsize = strlen (cp) + 2;
index bcf71cc6deff48a7404f246e5b76c4370e503c45..280ac8d8417acbe5c4ffe8def58090df8968d31c 100644 (file)
@@ -47,19 +47,6 @@ 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);
-}
-
-/* Be cautious not to use twice the same slot in a single expression. */
-static inline const char *
-escape2 (const char *s)
-{
-  return quotearg_n_style (2, escape_quoting_style, s);
-}
-
 \f
 /*--------------------------------.
 | Report information on a state.  |
 \f
 /*--------------------------------.
 | Report information on a state.  |
@@ -94,15 +81,15 @@ print_core (FILE *out, state_t *state)
            sp++;
 
          rule = -(*sp);
            sp++;
 
          rule = -(*sp);
-         fprintf (out, "    %s  ->  ", escape (rules[rule].lhs->tag));
+         fprintf (out, "    %s  ->  ", symbol_tag_get (rules[rule].lhs));
 
          for (sp = rules[rule].rhs; sp < sp1; sp++)
 
          for (sp = rules[rule].rhs; sp < sp1; sp++)
-           fprintf (out, "%s ", escape (symbols[*sp]->tag));
+           fprintf (out, "%s ", symbol_tag_get (symbols[*sp]));
 
          fputc ('.', out);
 
          for (/* Nothing */; *sp >= 0; ++sp)
 
          fputc ('.', out);
 
          for (/* Nothing */; *sp >= 0; ++sp)
-           fprintf (out, " %s", escape (symbols[*sp]->tag));
+           fprintf (out, " %s", symbol_tag_get (symbols[*sp]));
 
          /* Display the lookaheads?  */
          if (report_flag & report_lookaheads)
 
          /* Display the lookaheads?  */
          if (report_flag & report_lookaheads)
@@ -123,8 +110,7 @@ print_core (FILE *out, state_t *state)
                      if (bitset_test (LA[state->lookaheadsp + j], k)
                          && LArule[state->lookaheadsp + j]->number == rule)
                        fprintf (out, "%s%s",
                      if (bitset_test (LA[state->lookaheadsp + j], k)
                          && LArule[state->lookaheadsp + j]->number == rule)
                        fprintf (out, "%s%s",
-                                quotearg_style (escape_quoting_style,
-                                                symbols[k]->tag),
+                                symbol_tag_get (symbols[k]),
                                 --nlookaheads ? ", " : "");
                  fprintf (out, "]");
                }
                                 --nlookaheads ? ", " : "");
                  fprintf (out, "]");
                }
@@ -152,7 +138,7 @@ print_shifts (FILE *out, state_t *state)
        symbol_number_t symbol = states[state1]->accessing_symbol;
        fprintf (out,
                 _("    %-4s\tshift, and go to state %d\n"),
        symbol_number_t symbol = states[state1]->accessing_symbol;
        fprintf (out,
                 _("    %-4s\tshift, and go to state %d\n"),
-                escape (symbols[symbol]->tag), state1);
+                symbol_tag_get (symbols[symbol]), state1);
       }
 
   if (i > 0)
       }
 
   if (i > 0)
@@ -169,7 +155,7 @@ print_errs (FILE *out, state_t *state)
   for (i = 0; i < errp->nerrs; ++i)
     if (errp->errs[i])
       fprintf (out, _("    %-4s\terror (nonassociative)\n"),
   for (i = 0; i < errp->nerrs; ++i)
     if (errp->errs[i])
       fprintf (out, _("    %-4s\terror (nonassociative)\n"),
-              escape (symbols[errp->errs[i]]->tag));
+              symbol_tag_get (symbols[errp->errs[i]]));
 
   if (i > 0)
     fputc ('\n', out);
 
   if (i > 0)
     fputc ('\n', out);
@@ -193,7 +179,7 @@ print_gotos (FILE *out, state_t *state)
            int state1 = shiftp->shifts[i];
            symbol_number_t symbol = states[state1]->accessing_symbol;
            fprintf (out, _("    %-4s\tgo to state %d\n"),
            int state1 = shiftp->shifts[i];
            symbol_number_t symbol = states[state1]->accessing_symbol;
            fprintf (out, _("    %-4s\tgo to state %d\n"),
-                    escape (symbols[symbol]->tag), state1);
+                    symbol_tag_get (symbols[symbol]), state1);
          }
 
       fputc ('\n', out);
          }
 
       fputc ('\n', out);
@@ -217,7 +203,7 @@ print_reductions (FILE *out, state_t *state)
       int rule = redp->rules[0];
       symbol_number_t symbol = rules[rule].lhs->number;
       fprintf (out, _("    $default\treduce using rule %d (%s)\n\n"),
       int rule = redp->rules[0];
       symbol_number_t symbol = rules[rule].lhs->number;
       fprintf (out, _("    $default\treduce using rule %d (%s)\n\n"),
-              rule - 1, escape (symbols[symbol]->tag));
+              rule - 1, symbol_tag_get (symbols[symbol]));
       return;
     }
 
       return;
     }
 
@@ -246,13 +232,13 @@ print_reductions (FILE *out, state_t *state)
       for (i = 0; i < ntokens; i++)
        if (bitset_test (lookaheadset, i))
          fprintf (out, _("    %-4s\t[reduce using rule %d (%s)]\n"),
       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),
+                  symbol_tag_get (symbols[i]),
                   default_rule->number - 1,
                   default_rule->number - 1,
-                  escape2 (default_rule->lhs->tag));
+                  symbol_tag_get_n (default_rule->lhs, 1));
 
       fprintf (out, _("    $default\treduce using rule %d (%s)\n\n"),
               default_rule->number - 1,
 
       fprintf (out, _("    $default\treduce using rule %d (%s)\n\n"),
               default_rule->number - 1,
-              escape (default_rule->lhs->tag));
+              symbol_tag_get (default_rule->lhs));
     }
   else if (state->nlookaheads >= 1)
     {
     }
   else if (state->nlookaheads >= 1)
     {
@@ -302,9 +288,9 @@ print_reductions (FILE *out, state_t *state)
                    if (state->lookaheadsp + j != default_LA)
                      fprintf (out,
                               _("    %-4s\treduce using rule %d (%s)\n"),
                    if (state->lookaheadsp + j != default_LA)
                      fprintf (out,
                               _("    %-4s\treduce using rule %d (%s)\n"),
-                              escape (symbols[i]->tag),
+                              symbol_tag_get (symbols[i]),
                               LArule[state->lookaheadsp + j]->number - 1,
                               LArule[state->lookaheadsp + j]->number - 1,
-                              escape2 (LArule[state->lookaheadsp + j]->lhs->tag));
+                              symbol_tag_get_n (LArule[state->lookaheadsp + j]->lhs, 1));
                    else
                      defaulted = 1;
 
                    else
                      defaulted = 1;
 
@@ -315,15 +301,15 @@ print_reductions (FILE *out, state_t *state)
                    if (defaulted)
                      fprintf (out,
                               _("    %-4s\treduce using rule %d (%s)\n"),
                    if (defaulted)
                      fprintf (out,
                               _("    %-4s\treduce using rule %d (%s)\n"),
-                              escape (symbols[i]->tag),
+                              symbol_tag_get (symbols[i]),
                               LArule[default_LA]->number - 1,
                               LArule[default_LA]->number - 1,
-                              escape2 (LArule[default_LA]->lhs->tag));
+                              symbol_tag_get_n (LArule[default_LA]->lhs, 1));
                    defaulted = 0;
                    fprintf (out,
                             _("    %-4s\t[reduce using rule %d (%s)]\n"),
                    defaulted = 0;
                    fprintf (out,
                             _("    %-4s\t[reduce using rule %d (%s)]\n"),
-                            escape (symbols[i]->tag),
+                            symbol_tag_get (symbols[i]),
                             LArule[state->lookaheadsp + j]->number - 1,
                             LArule[state->lookaheadsp + j]->number - 1,
-                            escape2 (LArule[state->lookaheadsp + j]->lhs->tag));
+                            symbol_tag_get_n (LArule[state->lookaheadsp + j]->lhs, 1));
                  }
              }
        }
                  }
              }
        }
@@ -331,7 +317,7 @@ print_reductions (FILE *out, state_t *state)
       if (default_LA >= 0)
        fprintf (out, _("    $default\treduce using rule %d (%s)\n"),
                 default_rule->number - 1,
       if (default_LA >= 0)
        fprintf (out, _("    $default\treduce using rule %d (%s)\n"),
                 default_rule->number - 1,
-                escape (default_rule->lhs->tag));
+                symbol_tag_get (default_rule->lhs));
     }
 }
 
     }
 }
 
@@ -389,47 +375,31 @@ static void
 print_grammar (FILE *out)
 {
   symbol_number_t i;
 print_grammar (FILE *out)
 {
   symbol_number_t i;
-  int j;
   item_number_t *rule;
   char buffer[90];
   int column = 0;
 
   item_number_t *rule;
   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].location.first_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 = symbol_tag_get (symbols[token_translations[i]]);
+       int r;
        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++)
+       for (r = 1; r < nrules + 1; r++)
+         for (rule = rules[r].rhs; *rule >= 0; rule++)
            if (item_number_as_symbol_number (*rule) == token_translations[i])
              {
                END_TEST (65);
            if (item_number_as_symbol_number (*rule) == token_translations[i])
              {
                END_TEST (65);
-               sprintf (buffer + strlen (buffer), " %d", j - 1);
+               sprintf (buffer + strlen (buffer), " %d", r - 1);
                break;
              }
        fprintf (out, "%s\n", buffer);
                break;
              }
        fprintf (out, "%s\n", buffer);
@@ -441,12 +411,14 @@ 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;
+      int r;
+      const char *tag = symbol_tag_get (symbols[i]);
 
 
-      for (j = 1; j < nrules + 1; j++)
+      for (r = 1; r < nrules + 1; r++)
        {
        {
-         if (rules[j].lhs->number == i)
+         if (rules[r].lhs->number == i)
            left_count++;
            left_count++;
-         for (rule = rules[j].rhs; *rule >= 0; rule++)
+         for (rule = rules[r].rhs; *rule >= 0; rule++)
            if (item_number_as_symbol_number (*rule) == i)
              {
                right_count++;
            if (item_number_as_symbol_number (*rule) == i)
              {
                right_count++;
@@ -455,8 +427,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);
 
@@ -465,11 +437,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 = 1; r < nrules + 1; 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 - 1);
            }
        }
 
            }
        }
 
@@ -479,13 +451,13 @@ 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 = 1; r < nrules + 1; r++)
            {
            {
-             for (rule = rules[j].rhs; *rule >= 0; rule++)
+             for (rule = rules[r].rhs; *rule >= 0; rule++)
                if (item_number_as_symbol_number (*rule) == i)
                  {
                    END_TEST (65);
                if (item_number_as_symbol_number (*rule) == i)
                  {
                    END_TEST (65);
-                   sprintf (buffer + strlen (buffer), " %d", j - 1);
+                   sprintf (buffer + strlen (buffer), " %d", r - 1);
                    break;
                  }
            }
                    break;
                  }
            }
index 6cd92ec9f58ab5792c93a2a8b89d6a184a354f7a..49acaa7ea460eca75f82c3206c4193c86d9c2d08 100644 (file)
 static graph_t graph;
 static FILE *fgraph = NULL;
 
 static graph_t graph;
 static FILE *fgraph = NULL;
 
-static inline const char *
-escape (const char *s)
-{
-  return quotearg_n_style (1, escape_quoting_style, s);
-}
 
 
+/*----------------------------.
+| Construct the node labels.  |
+`----------------------------*/
 
 
-/* This part will construct the label of nodes. */
 static void
 print_core (struct obstack *oout, state_t *state)
 {
 static void
 print_core (struct obstack *oout, state_t *state)
 {
@@ -78,15 +75,15 @@ print_core (struct obstack *oout, state_t *state)
       if (i)
        obstack_1grow (oout, '\n');
       obstack_fgrow1 (oout, " %s -> ",
       if (i)
        obstack_1grow (oout, '\n');
       obstack_fgrow1 (oout, " %s -> ",
-                     escape (rules[rule].lhs->tag));
+                     symbol_tag_get (rules[rule].lhs));
 
       for (sp = rules[rule].rhs; sp < sp1; sp++)
 
       for (sp = rules[rule].rhs; sp < sp1; sp++)
-       obstack_fgrow1 (oout, "%s ", escape (symbols[*sp]->tag));
+       obstack_fgrow1 (oout, "%s ", symbol_tag_get (symbols[*sp]));
 
       obstack_1grow (oout, '.');
 
       for (/* Nothing */; *sp >= 0; ++sp)
 
       obstack_1grow (oout, '.');
 
       for (/* Nothing */; *sp >= 0; ++sp)
-       obstack_fgrow1 (oout, " %s", escape (symbols[*sp]->tag));
+       obstack_fgrow1 (oout, " %s", symbol_tag_get (symbols[*sp]));
 
       /* Experimental feature: display the lookaheads. */
       if (trace_flag && state->nlookaheads)
 
       /* Experimental feature: display the lookaheads. */
       if (trace_flag && state->nlookaheads)
@@ -107,8 +104,7 @@ print_core (struct obstack *oout, state_t *state)
                  if (bitset_test (LA[state->lookaheadsp + j], k)
                      && LArule[state->lookaheadsp + j]->number == rule)
                    obstack_fgrow2 (oout, "%s%s",
                  if (bitset_test (LA[state->lookaheadsp + j], k)
                      && LArule[state->lookaheadsp + j]->number == rule)
                    obstack_fgrow2 (oout, "%s%s",
-                                   quotearg_style (escape_quoting_style,
-                                                   symbols[k]->tag),
+                                   symbol_tag_get (symbols[k]),
                                    --nlookaheads ? ", " : "");
              obstack_sgrow (oout, "]");
            }
                                    --nlookaheads ? ", " : "");
              obstack_sgrow (oout, "]");
            }
@@ -156,7 +152,7 @@ print_actions (state_t *state, const char *node_name)
          edge.color = red;
        else
          edge.color = SHIFT_IS_SHIFT(shiftp, i) ? blue : green;
          edge.color = red;
        else
          edge.color = SHIFT_IS_SHIFT(shiftp, i) ? blue : green;
-       edge.label = escape (symbols[symbol]->tag);
+       edge.label = symbol_tag_get (symbols[symbol]);
        output_edge (&edge, fgraph);
        close_edge (fgraph);
       }
        output_edge (&edge, fgraph);
        close_edge (fgraph);
       }
index 59afff78c01d33c321daef079b19d45c08e9ea27..2319b60bf192104f672ff22b0617b62015217824 100644 (file)
@@ -227,11 +227,19 @@ inaccessable_symbols (void)
 static void
 reduce_grammar_tables (void)
 {
 static void
 reduce_grammar_tables (void)
 {
-  /* Flag useless productions.  */
+  /* Report and flag useless productions.  */
   {
   {
-    int pn;
-    for (pn = 1; pn < nrules + 1; pn++)
-      rules[pn].useful = bitset_test (P, pn);
+    int r;
+    for (r = 1; r < nrules + 1; r++)
+      {
+       rules[r].useful = bitset_test (P, r);
+       if (!rules[r].useful)
+         {
+           LOCATION_PRINT (stderr, rules[r].location);
+           fprintf (stderr, ": %s: %s: ", _("warning"), _("useless rule"));
+           rule_print (&rules[r], stderr);
+         }
+      }
   }
 
   /* Map the nonterminals to their new index: useful first, useless
   }
 
   /* Map the nonterminals to their new index: useful first, useless
@@ -290,7 +298,13 @@ nonterminals_reduce (void)
       nontermmap[i] = n++;
   for (i = ntokens; i < nsyms; i++)
     if (!bitset_test (V, i))
       nontermmap[i] = n++;
   for (i = ntokens; i < nsyms; i++)
     if (!bitset_test (V, i))
-      nontermmap[i] = n++;
+      {
+       nontermmap[i] = n++;
+       LOCATION_PRINT (stderr, symbols[i]->location);
+       fprintf (stderr, ": %s: %s: %s\n",
+                _("warning"), _("useless nonterminal"),
+                symbol_tag_get (symbols[i]));
+      }
 
 
   /* Shuffle elements of tables indexed by symbol number.  */
 
 
   /* Shuffle elements of tables indexed by symbol number.  */
@@ -337,8 +351,7 @@ reduce_output (FILE *out)
       int i;
       fprintf (out, "%s\n\n", _("Useless nonterminals:"));
       for (i = 0; i < nuseless_nonterminals; ++i)
       int i;
       fprintf (out, "%s\n\n", _("Useless nonterminals:"));
       for (i = 0; i < nuseless_nonterminals; ++i)
-       fprintf (out, "   %s\n", quotearg_style (escape_quoting_style,
-                                                symbols[nsyms + i]->tag));
+       fprintf (out, "   %s\n", symbol_tag_get (symbols[nsyms + i]));
       fputs ("\n\n", out);
     }
 
       fputs ("\n\n", out);
     }
 
@@ -351,8 +364,7 @@ reduce_output (FILE *out)
          if (!b)
            fprintf (out, "%s\n\n", _("Terminals which are not used:"));
          b = TRUE;
          if (!b)
            fprintf (out, "%s\n\n", _("Terminals which are not used:"));
          b = TRUE;
-         fprintf (out, "   %s\n", quotearg_style (escape_quoting_style,
-                                                  symbols[i]->tag));
+         fprintf (out, "   %s\n", symbol_tag_get (symbols[i]));
        }
     if (b)
       fputs ("\n\n", out);
        }
     if (b)
       fputs ("\n\n", out);
@@ -366,11 +378,9 @@ reduce_output (FILE *out)
        {
          item_number_t *r;
          fprintf (out, "#%-4d  ", rules[i].user_number - 1);
        {
          item_number_t *r;
          fprintf (out, "#%-4d  ", rules[i].user_number - 1);
-         fprintf (out, "%s:", quotearg_style (escape_quoting_style,
-                                              rules[i].lhs->tag));
+         fprintf (out, "%s:", symbol_tag_get (rules[i].lhs));
          for (r = rules[i].rhs; *r >= 0; r++)
          for (r = rules[i].rhs; *r >= 0; r++)
-           fprintf (out, " %s", quotearg_style (escape_quoting_style,
-                                                symbols[*r]->tag));
+           fprintf (out, " %s", symbol_tag_get (symbols[*r]));
          fputs (";\n", out);
        }
       fputs ("\n\n", out);
          fputs (";\n", out);
        }
       fputs ("\n\n", out);
@@ -394,7 +404,7 @@ reduce_print (void)
                               nuseless_productions),
             nuseless_productions);
 
                               nuseless_productions),
             nuseless_productions);
 
-  fprintf (stderr, _("%s contains "), infile);
+  fprintf (stderr, "%s: %s: ", infile, _("warning"));
 
   if (nuseless_nonterminals > 0)
     fprintf (stderr, ngettext ("%d useless nonterminal",
 
   if (nuseless_nonterminals > 0)
     fprintf (stderr, ngettext ("%d useless nonterminal",
@@ -437,7 +447,7 @@ reduce_grammar (void)
 
   if (!bitset_test (N, axiom->number - ntokens))
     fatal (_("Start symbol %s does not derive any sentence"),
 
   if (!bitset_test (N, axiom->number - ntokens))
     fatal (_("Start symbol %s does not derive any sentence"),
-          quotearg_style (escape_quoting_style, symbols[axiom->number]->tag));
+          symbol_tag_get (symbols[axiom->number]));
 
   /* First reduce the nonterminals, as they renumber themselves in the
      whole grammar.  If you change the order, nonterms would be
 
   /* First reduce the nonterminals, as they renumber themselves in the
      whole grammar.  If you change the order, nonterms would be
index fddf15e7af0d070419d576f602a626a5a1a7c31e..0f73d30f368398af475d4f6ca71055177c45d0b4 100644 (file)
@@ -20,6 +20,7 @@
 
 
 #include "system.h"
 
 
 #include "system.h"
+#include "quotearg.h"
 #include "hash.h"
 #include "complain.h"
 #include "symtab.h"
 #include "hash.h"
 #include "complain.h"
 #include "symtab.h"
@@ -60,6 +61,41 @@ symbol_new (const char *tag, location_t location)
 }
 
 
 }
 
 
+/*-----------------------------------------------------------------.
+| Return the tag of this SYMBOL in a printable form.  Warning: use |
+| the first QUOTEARG slot: 0.                                      |
+`-----------------------------------------------------------------*/
+
+const char *
+symbol_tag_get (symbol_t *symbol)
+{
+  return quotearg_style (escape_quoting_style, symbol->tag);
+}
+
+
+/*------------------------------------------------------------.
+| Return the tag of this SYMBOL in a printable form.  Use the |
+| QUOTEARG slot number N.                                     |
+`------------------------------------------------------------*/
+
+const char *
+symbol_tag_get_n (symbol_t *symbol, int n)
+{
+  return quotearg_n_style (n, escape_quoting_style, symbol->tag);
+}
+
+
+/*-------------------------------.
+| Print the tag of this SYMBOL.  |
+`-------------------------------*/
+
+void
+symbol_tag_print (symbol_t *symbol, FILE *out)
+{
+  fputs (symbol_tag_get (symbol), out);
+}
+
+
 /*------------------------------------------------------------------.
 | Set the TYPE_NAME associated to SYMBOL.  Does nothing if passed 0 |
 | as TYPE_NAME.                                                     |
 /*------------------------------------------------------------------.
 | Set the TYPE_NAME associated to SYMBOL.  Does nothing if passed 0 |
 | as TYPE_NAME.                                                     |
index 2f53c8b8a12d70a0f48e3bb3b527421baacaa94e..1424a41b7cdd723467eb92f2d309c6d665c02572 100644 (file)
@@ -87,6 +87,17 @@ struct symbol_s
 #define NUMBER_UNDEFINED ((symbol_number_t) -1)
 
 
 #define NUMBER_UNDEFINED ((symbol_number_t) -1)
 
 
+/* Return the tag of this SYMBOL in a printable form.  Warning: uses
+   the QUOTEARG slot 0.  */
+const char *symbol_tag_get PARAMS ((symbol_t *symbol));
+
+/* Return the tag of this SYMBOL in a printable form.  Use the
+   QUOTEARG slot number N.  */
+const char *symbol_tag_get_n PARAMS ((symbol_t *symbol, int n));
+
+/* Print the tag of this SYMBOL.  */
+void symbol_tag_print PARAMS ((symbol_t *symbol, FILE *out));
+
 /* Fetch (or create) the symbol associated to KEY.  */
 symbol_t *getsym PARAMS ((const char *key, location_t location));
 
 /* Fetch (or create) the symbol associated to KEY.  */
 symbol_t *getsym PARAMS ((const char *key, location_t location));
 
index 6d5467838d9a3d656fe44aff28e2e9c8ae4b8b74..3aceda1cc72b5e2b62cad5516a6e30d6a17330da 100644 (file)
@@ -130,6 +130,8 @@ AT_CLEANUP
 
 AT_SETUP([Unresolved SR Conflicts])
 
 
 AT_SETUP([Unresolved SR Conflicts])
 
+AT_KEYWORDS([report])
+
 AT_DATA([input.y],
 [[%token NUM OP
 %%
 AT_DATA([input.y],
 [[%token NUM OP
 %%
@@ -147,10 +149,10 @@ AT_CHECK([cat input.output], [],
 
 Grammar
 
 
 Grammar
 
-  Number, Line, Rule
-    0   3 $axiom -> exp $
-    1   3 exp -> exp OP exp
-    2   3 exp -> NUM
+    0 $axiom: exp $
+
+    1 exp: exp OP exp
+    2    | NUM
 
 
 Terminals, with rules where they appear
 
 
 Terminals, with rules where they appear
@@ -241,6 +243,8 @@ AT_CLEANUP
 
 AT_SETUP([Solved SR Conflicts])
 
 
 AT_SETUP([Solved SR Conflicts])
 
+AT_KEYWORDS([report])
+
 AT_DATA([input.y],
 [[%token NUM OP
 %right OP
 AT_DATA([input.y],
 [[%token NUM OP
 %right OP
@@ -254,10 +258,10 @@ AT_CHECK([bison input.y -o input.c --report=all], 0, [], [])
 AT_CHECK([cat input.output], [],
 [[Grammar
 
 AT_CHECK([cat input.output], [],
 [[Grammar
 
-  Number, Line, Rule
-    0   4 $axiom -> exp $
-    1   4 exp -> exp OP exp
-    2   4 exp -> NUM
+    0 $axiom: exp $
+
+    1 exp: exp OP exp
+    2    | NUM
 
 
 Terminals, with rules where they appear
 
 
 Terminals, with rules where they appear
index 24911943aaa6c5f882e2ae8bccff195283cd92b5..ba9d27edd8e9cbcf0e49ffbf7039a96ac5a05c57 100644 (file)
@@ -89,7 +89,16 @@ exp: useful;
 ]])
 
 AT_CHECK([[bison input.y]], 0, [],
 ]])
 
 AT_CHECK([[bison input.y]], 0, [],
-[[input.y contains 9 useless nonterminals
+[[input.y: warning: 9 useless nonterminals
+input.y:4.8-15: warning: useless nonterminal: useless1
+input.y:5.8-15: warning: useless nonterminal: useless2
+input.y:6.8-15: warning: useless nonterminal: useless3
+input.y:7.8-15: warning: useless nonterminal: useless4
+input.y:8.8-15: warning: useless nonterminal: useless5
+input.y:9.8-15: warning: useless nonterminal: useless6
+input.y:10.8-15: warning: useless nonterminal: useless7
+input.y:11.8-15: warning: useless nonterminal: useless8
+input.y:12.8-15: warning: useless nonterminal: useless9
 ]])
 
 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
 ]])
 
 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
@@ -133,7 +142,25 @@ useless9: '9';
 ]])
 
 AT_CHECK([[bison input.y]], 0, [],
 ]])
 
 AT_CHECK([[bison input.y]], 0, [],
-[[input.y contains 9 useless nonterminals and 9 useless rules
+[[input.y: warning: 9 useless nonterminals and 9 useless rules
+input.y:6.1-8: warning: useless nonterminal: useless1
+input.y:7.1-8: warning: useless nonterminal: useless2
+input.y:8.1-8: warning: useless nonterminal: useless3
+input.y:9.1-8: warning: useless nonterminal: useless4
+input.y:10.1-8: warning: useless nonterminal: useless5
+input.y:11.1-8: warning: useless nonterminal: useless6
+input.y:12.1-8: warning: useless nonterminal: useless7
+input.y:13.1-8: warning: useless nonterminal: useless8
+input.y:14.1-8: warning: useless nonterminal: useless9
+input.y:6.9-13: warning: useless rule: useless1: '1'
+input.y:7.9-13: warning: useless rule: useless2: '2'
+input.y:8.9-13: warning: useless rule: useless3: '3'
+input.y:9.9-13: warning: useless rule: useless4: '4'
+input.y:10.9-13: warning: useless rule: useless5: '5'
+input.y:11.9-13: warning: useless rule: useless6: '6'
+input.y:12.9-13: warning: useless rule: useless7: '7'
+input.y:13.9-13: warning: useless rule: useless8: '8'
+input.y:14.9-13: warning: useless rule: useless9: '9'
 ]])
 
 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
 ]])
 
 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
@@ -208,7 +235,12 @@ non_productive: non_productive useless_token
 ]])
 
 AT_CHECK([[bison not-reduced.y]], 0, [],
 ]])
 
 AT_CHECK([[bison not-reduced.y]], 0, [],
-[[not-reduced.y contains 2 useless nonterminals and 3 useless rules
+[[not-reduced.y: warning: 2 useless nonterminals and 3 useless rules
+not-reduced.y:14.1-13: warning: useless nonterminal: not_reachable
+not-reduced.y:11.6-19: warning: useless nonterminal: non_productive
+not-reduced.y:11.4-57: warning: useless rule: exp: non_productive
+not-reduced.y:14.14-56: warning: useless rule: not_reachable: useful
+not-reduced.y:17.15-18.63: warning: useless rule: non_productive: non_productive useless_token
 ]])
 
 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
 ]])
 
 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
@@ -275,7 +307,12 @@ indirection: underivable;
 ]])
 
 AT_CHECK([[bison input.y]], 0, [],
 ]])
 
 AT_CHECK([[bison input.y]], 0, [],
-[[input.y contains 2 useless nonterminals and 3 useless rules
+[[input.y: warning: 2 useless nonterminals and 3 useless rules
+input.y:5.15-25: warning: useless nonterminal: underivable
+input.y:6.14-24: warning: useless nonterminal: indirection
+input.y:5.13-25: warning: useless rule: exp: underivable
+input.y:6.12-24: warning: useless rule: underivable: indirection
+input.y:7.12-24: warning: useless rule: indirection: underivable
 ]])
 
 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
 ]])
 
 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
index 6d5594684b148258b6f7313b883149c4502c158a..3620200af6415cca7f136e87f71524ca74082fbb 100644 (file)
@@ -112,6 +112,8 @@ AT_CLEANUP
 
 AT_SETUP([Rule Line Numbers])
 
 
 AT_SETUP([Rule Line Numbers])
 
+AT_KEYWORDS([report])
+
 AT_DATA([input.y],
 [[%%
 expr:
 AT_DATA([input.y],
 [[%%
 expr:
@@ -148,12 +150,15 @@ AT_CHECK([bison input.y -o input.c -v])
 AT_CHECK([cat input.output], [],
 [[Grammar
 
 AT_CHECK([cat input.output], [],
 [[Grammar
 
-  Number, Line, Rule
-    0   5 $axiom -> expr $
-    1   5 @1 -> /* empty */
-    2   2 expr -> 'a' @1 'b'
-    3  18 @2 -> /* empty */
-    4  15 expr -> @2 'c'
+    0 $axiom: expr $
+
+    1 @1: /* empty */
+
+    2 expr: 'a' @1 'b'
+
+    3 @2: /* empty */
+
+    4 expr: @2 'c'
 
 
 Terminals, with rules where they appear
 
 
 Terminals, with rules where they appear
@@ -349,6 +354,8 @@ AT_CLEANUP
 
 AT_SETUP([Web2c Report])
 
 
 AT_SETUP([Web2c Report])
 
+AT_KEYWORDS([report])
+
 AT_DATA([input.y],
 [[%token       undef_id_tok const_id_tok
 
 AT_DATA([input.y],
 [[%token       undef_id_tok const_id_tok
 
@@ -375,13 +382,12 @@ AT_CHECK([bison -v input.y])
 
 AT_CHECK([sed -n 's/  *$//;/^$/!p' input.output], 0,
 [[Grammar
 
 AT_CHECK([sed -n 's/  *$//;/^$/!p' input.output], 0,
 [[Grammar
-  Number, Line, Rule
-    0   6 $axiom -> CONST_DEC_PART $
-    1   6 CONST_DEC_PART -> CONST_DEC_LIST
-    2  10 CONST_DEC_LIST -> CONST_DEC
-    3  12 CONST_DEC_LIST -> CONST_DEC_LIST CONST_DEC
-    4  16 @1 -> /* empty */
-    5  15 CONST_DEC -> @1 undef_id_tok '=' const_id_tok ';'
+    0 $axiom: CONST_DEC_PART $
+    1 CONST_DEC_PART: CONST_DEC_LIST
+    2 CONST_DEC_LIST: CONST_DEC
+    3               | CONST_DEC_LIST CONST_DEC
+    4 @1: /* empty */
+    5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';'
 Terminals, with rules where they appear
 $ (0) 0
 ';' (59) 5
 Terminals, with rules where they appear
 $ (0) 0
 ';' (59) 5
@@ -470,6 +476,8 @@ AT_CLEANUP
 
 AT_SETUP([Web2c Actions])
 
 
 AT_SETUP([Web2c Actions])
 
+AT_KEYWORDS([report])
+
 AT_DATA([input.y],
 [[%%
 statement:  struct_stat;
 AT_DATA([input.y],
 [[%%
 statement:  struct_stat;