]> git.saurik.com Git - bison.git/commitdiff
fix warnings for useless %printer/%destructor
authorAkim Demaille <akim@lrde.epita.fr>
Wed, 20 Jun 2012 10:33:34 +0000 (12:33 +0200)
committerAkim Demaille <akim@lrde.epita.fr>
Wed, 20 Jun 2012 19:53:27 +0000 (21:53 +0200)
The previous commit, which turns into a warning what used to be an
error:

    %printer {} foo;
    %%
    exp: '0';

has two shortcomings: the warning is way too long (foo is reported
to be useless later), and besides, it also turns into a warning much
more serious errors:

   %printer {} foo;
   %%
   exp: foo;

Reduce the amount to warnings in the first case, restore the error in
the second.

* src/symtab.h (status): Add a new inital state: undeclared.
* src/symtab.c (symbol_new): Initialize to undeclared.
(symbol_class_set): Simplify the logic of the code that neutralize
the "redeclared" warning after the "redefined" one.
(symbol_check_defined): "undeclared" is also an error.
* src/reader.c (grammar_current_rule_symbol_append): Symbols appearing
in a rule are "needed".
* src/symlist.c (symbol_list_destructor_set, symbol_list_printer_set):
An unknown symbol appearing in a %printer/%destructor is "used".
* src/reduce.c (nonterminals_reduce): Do not report as "useless" symbols
that are not used (e.g., those that for instance appeared only in a
%printer).
* tests/input.at (Undeclared symbols used for a printer or destructor):
Improve the cover the cases described above.

src/reader.c
src/reduce.c
src/symlist.c
src/symtab.c
src/symtab.h
tests/input.at

index 27ddad0835422b13bf7e9fdc7df7b69b1428c5cc..9bb9d7b6a6ce4a35e5c1d895c8c541e3e34d3fde 100644 (file)
@@ -470,6 +470,8 @@ grammar_current_rule_symbol_append (symbol *sym, location loc,
   p = grammar_symbol_append (sym, loc);
   if (name)
     assign_named_ref(p, name);
+  if (sym->status == undeclared || sym->status == used)
+    sym->status = needed;
 }
 
 /* Attach an ACTION to the current rule.  */
index 0bc1d8c7f90bbe4dbeda8cb732200d4deb7b2f4c..736cbb6a7149ad2ab8179f3102bf5c923a6c83a3 100644 (file)
@@ -298,8 +298,10 @@ nonterminals_reduce (void)
     if (!bitset_test (V, i))
       {
         nontermmap[i - ntokens] = n++;
-        warn_at (symbols[i]->location, _("nonterminal useless in grammar: %s"),
-                 symbols[i]->tag);
+        if (symbols[i]->status != used)
+          warn_at (symbols[i]->location,
+                   _("nonterminal useless in grammar: %s"),
+                   symbols[i]->tag);
       }
 
 
index 03169450d32b86940f7d85cc157e9f383144b51f..abb58674f1c80a5b935cbcdbd316463df83e4fff 100644 (file)
@@ -232,7 +232,7 @@ symbol_list_destructor_set (symbol_list *node, char const *code, location loc)
     {
       case SYMLIST_SYMBOL:
         symbol_destructor_set (node->content.sym, &destructor);
-        if (node->content.sym->status == needed)
+        if (node->content.sym->status == undeclared)
           node->content.sym->status = used;
         break;
       case SYMLIST_TYPE:
@@ -258,7 +258,7 @@ symbol_list_printer_set (symbol_list *node, char const *code, location loc)
     {
       case SYMLIST_SYMBOL:
         symbol_printer_set (node->content.sym, &printer);
-        if (node->content.sym->status == needed)
+        if (node->content.sym->status == undeclared)
           node->content.sym->status = used;
         break;
       case SYMLIST_TYPE:
index 719cb9fd3a30e12366fd542d3cc7347a63aa5254..ad8820f423e2efbbacb83087bf63980b15e47e00 100644 (file)
@@ -85,7 +85,7 @@ symbol_new (uniqstr tag, location loc)
 
   res->alias = NULL;
   res->class = unknown_sym;
-  res->status = needed;
+  res->status = undeclared;
 
   if (nsyms == SYMBOL_NUMBER_MAXIMUM)
     fatal (_("too many symbols in input grammar (limit is %d)"),
@@ -358,10 +358,12 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
 void
 symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
 {
+  bool warned = false;
   if (sym->class != unknown_sym && sym->class != class)
     {
       complain_at (loc, _("symbol %s redefined"), sym->tag);
-      sym->status = needed;
+      // Don't report both "redefined" and "redeclared".
+      warned = true;
     }
 
   if (class == nterm_sym && sym->class != nterm_sym)
@@ -373,7 +375,7 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
 
   if (declaring)
     {
-      if (sym->status == declared)
+      if (sym->status == declared && !warned)
         warn_at (loc, _("symbol %s redeclared"), sym->tag);
       sym->status = declared;
     }
@@ -421,18 +423,25 @@ symbol_check_defined (symbol *sym)
 {
   if (sym->class == unknown_sym)
     {
-      if (sym->status == needed)
-        complain_at
-          (sym->location,
-           _("symbol %s is used, but is not defined as a token and has no"
-             " rules"),
-           sym->tag);
-      else
-        warn_at
-          (sym->location,
-           _("symbol %s is used, but is not defined as a token and has no"
-             " rules"),
-           sym->tag);
+      switch (sym->status)
+        {
+        case used:
+          warn_at (sym->location,
+                   _("symbol %s is used, but is not defined as a token"
+                     " and has no rules"),
+                   sym->tag);
+          break;
+        case undeclared:
+        case needed:
+          complain_at (sym->location,
+                       _("symbol %s is used, but is not defined as a token"
+                         " and has no rules"),
+                       sym->tag);
+          break;
+        case declared:
+          /* If declared, then sym->class != unknown_sym. */
+          assert (0);
+        }
 
       sym->class = nterm_sym;
       sym->number = nvars++;
index d9ee96efa23e2167a9c24ac8d091ba738bc69967..480d6ca3d7bafa3b1b2ee1bcf2324e74428e0c45 100644 (file)
@@ -51,11 +51,27 @@ typedef int symbol_number;
 
 typedef struct symbol symbol;
 
+/* Declaration status of a symbol.
+
+   First, it is "undeclared".  Then, if "undeclared" and used in a
+   %printer/%destructor, it is "used".  If not "declared" by used in a
+   rule, it is "needed".  Finally, if declared (via a rule for
+   nonterminals, or %oken), it is "declared".
+
+   When status are checked at the end, "declared" symbols are fine,
+   "used" symbols trigger warnings, otherwise it's an error.
+*/
+
 typedef enum
   {
-    needed,   /**< found but not "defined".  */
-    used,     /**< used by %printer but not declared.  */
-    declared, /**< defined with %type or %token.  */
+    /** Used in the input file for an unknown reason (error).  */
+    undeclared,
+    /** Used by %destructor/%printer but not defined (warning).  */
+    used,
+    /** Used in the gramar (rules) but not defined (error).  */
+    needed,
+    /** Defined with %type or %token (good).  */
+    declared,
   } status;
 
 /* When extending this structure, be sure to complete
index 0e0b0041ec8fb6bee5efea5aac5861a3dd754248..200fa076fa00fed03ac6daaa101c6075b5046333 100644 (file)
@@ -271,26 +271,24 @@ input.y:5.10-24: previous declaration
 
 AT_CLEANUP
 
-## ---------------------------------------------------- ##
-## Undeclared symbols used for a printer or destructor. ##
-## ---------------------------------------------------- ##
+## ----------------------------------------------------- ##
+## Undeclared symbols used for a printer or destructor.  ##
+## ----------------------------------------------------- ##
 
 AT_SETUP([Undeclared symbols used for a printer or destructor])
 
 AT_DATA([[input.y]],
-[[%printer {} token1
-%destructor {} token2
+[[%printer {} foo baz
+%destructor {} bar
 
 %%
-exp: "a";
+exp: bar;
 ]])
 
-AT_BISON_CHECK([input.y], [0], [],
-[[input.y:1.13-18: warning: symbol token1 is used, but is not defined as a token and has no rules
-input.y:2.16-21: warning: symbol token2 is used, but is not defined as a token and has no rules
-input.y: warning: 2 nonterminals useless in grammar
-input.y:1.13-18: warning: nonterminal useless in grammar: token1
-input.y:2.16-21: warning: nonterminal useless in grammar: token2
+AT_BISON_CHECK([input.y], [1], [],
+[[input.y:2.16-18: symbol bar is used, but is not defined as a token and has no rules
+input.y:1.17-19: warning: symbol baz is used, but is not defined as a token and has no rules
+input.y:1.13-15: warning: symbol foo is used, but is not defined as a token and has no rules
 ]])
 
 AT_CLEANUP