From: Akim Demaille Date: Wed, 20 Jun 2012 10:33:34 +0000 (+0200) Subject: fix warnings for useless %printer/%destructor X-Git-Tag: v2.7.90~428 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/3b0b682fd6c55c0387aacbb86bc708da09ad2ae3 fix warnings for useless %printer/%destructor 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. --- diff --git a/src/reader.c b/src/reader.c index 27ddad08..9bb9d7b6 100644 --- a/src/reader.c +++ b/src/reader.c @@ -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. */ diff --git a/src/reduce.c b/src/reduce.c index 0bc1d8c7..736cbb6a 100644 --- a/src/reduce.c +++ b/src/reduce.c @@ -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); } diff --git a/src/symlist.c b/src/symlist.c index 03169450..abb58674 100644 --- a/src/symlist.c +++ b/src/symlist.c @@ -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: diff --git a/src/symtab.c b/src/symtab.c index 719cb9fd..ad8820f4 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -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++; diff --git a/src/symtab.h b/src/symtab.h index d9ee96ef..480d6ca3 100644 --- a/src/symtab.h +++ b/src/symtab.h @@ -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 diff --git a/tests/input.at b/tests/input.at index 0e0b0041..200fa076 100644 --- a/tests/input.at +++ b/tests/input.at @@ -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