diff --git a/NEWS b/NEWS index 18771946..e64c6e89 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,50 @@ GNU Bison NEWS * Noteworthy changes in release ?.? (????-??-??) [?] +** Diagnostics about useless rules + + In the following grammar, the 'exp' nonterminal is trivially useless. So, + of course, its rules are useless too. + + %% + input: '0' | exp + exp: exp '+' exp | exp '-' exp | '(' exp ')' + + Previously all the useless rules were reported, including those whose + left-hand side is the 'exp' nonterminal: + + warning: 1 nonterminal useless in grammar [-Wother] + warning: 4 rules useless in grammar [-Wother] + 2.14-16: warning: nonterminal useless in grammar: exp [-Wother] + input: '0' | exp + ^^^ + 2.14-16: warning: rule useless in grammar [-Wother] + input: '0' | exp + ^^^ + 3.6-16: warning: rule useless in grammar [-Wother] + exp: exp '+' exp | exp '-' exp | '(' exp ')' + ^^^^^^^^^^^ + 3.20-30: warning: rule useless in grammar [-Wother] + exp: exp '+' exp | exp '-' exp | '(' exp ')' + ^^^^^^^^^^^ + 3.34-44: warning: rule useless in grammar [-Wother] + exp: exp '+' exp | exp '-' exp | '(' exp ')' + ^^^^^^^^^^^ + + Now, rules whose left-hand side symbol is useless are no longer reported + as useless. + + warning: 1 nonterminal useless in grammar [-Wother] + warning: 4 rules useless in grammar [-Wother] + 2.14-16: warning: nonterminal useless in grammar: exp [-Wother] + input: '0' | exp + ^^^ + 2.14-16: warning: rule useless in grammar [-Wother] + input: '0' | exp + ^^^ + +* Noteworthy changes in release ?.? (????-??-??) [?] + ** Bug fixes *** C++ with Variants (lalr1.cc) diff --git a/src/gram.c b/src/gram.c index abd1872f..594d835f 100644 --- a/src/gram.c +++ b/src/gram.c @@ -293,7 +293,10 @@ grammar_rules_useless_report (const char *message) { rule_number r; for (r = 0; r < nrules ; ++r) - if (!rules[r].useful) + /* Don't complain about rules whose LHS is useless, we already + complained about it. */ + if (!reduce_nonterminal_useless_in_grammar (rules[r].lhs) + && !rules[r].useful) complain (&rules[r].location, Wother, "%s", message); } diff --git a/src/print-xml.c b/src/print-xml.c index 81a491c2..f1564244 100644 --- a/src/print-xml.c +++ b/src/print-xml.c @@ -417,7 +417,7 @@ print_grammar (FILE *out, int level) "", i, xml_escape (tag), - reduce_nonterminal_useless_in_grammar (i) + reduce_nonterminal_useless_in_grammar (symbols[i]->content) ? "useless-in-grammar" : "useful"); } xml_puts (out, level + 1, ""); diff --git a/src/reduce.c b/src/reduce.c index 46b38ffc..316833bb 100644 --- a/src/reduce.c +++ b/src/reduce.c @@ -442,10 +442,11 @@ reduce_token_unused_in_grammar (symbol_number i) } bool -reduce_nonterminal_useless_in_grammar (symbol_number i) +reduce_nonterminal_useless_in_grammar (const sym_content *sym) { - aver (ntokens <= i && i < nsyms + nuseless_nonterminals); - return nsyms <= i; + symbol_number n = sym->number; + aver (ntokens <= n && n < nsyms + nuseless_nonterminals); + return nsyms <= n; } /*-----------------------------------------------------------. diff --git a/src/reduce.h b/src/reduce.h index 0dab504c..254f7bc2 100644 --- a/src/reduce.h +++ b/src/reduce.h @@ -24,7 +24,12 @@ void reduce_grammar (void); void reduce_output (FILE *out); bool reduce_token_unused_in_grammar (symbol_number i); -bool reduce_nonterminal_useless_in_grammar (symbol_number i); + +/** Whether symbol \a i is useless in the grammar. + * \pre reduce_grammar was called before. + */ +bool reduce_nonterminal_useless_in_grammar (const sym_content *sym); + void reduce_free (void); extern unsigned nuseless_nonterminals; diff --git a/tests/reduce.at b/tests/reduce.at index c28635eb..c7edb10b 100644 --- a/tests/reduce.at +++ b/tests/reduce.at @@ -172,33 +172,6 @@ input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother] input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother] useless9: '9'; ^^^^^^^^ -input.y:6.11-13: warning: rule useless in grammar [-Wother] - useless1: '1'; - ^^^ -input.y:7.11-13: warning: rule useless in grammar [-Wother] - useless2: '2'; - ^^^ -input.y:8.11-13: warning: rule useless in grammar [-Wother] - useless3: '3'; - ^^^ -input.y:9.11-13: warning: rule useless in grammar [-Wother] - useless4: '4'; - ^^^ -input.y:10.11-13: warning: rule useless in grammar [-Wother] - useless5: '5'; - ^^^ -input.y:11.11-13: warning: rule useless in grammar [-Wother] - useless6: '6'; - ^^^ -input.y:12.11-13: warning: rule useless in grammar [-Wother] - useless7: '7'; - ^^^ -input.y:13.11-13: warning: rule useless in grammar [-Wother] - useless8: '8'; - ^^^ -input.y:14.11-13: warning: rule useless in grammar [-Wother] - useless9: '9'; - ^^^ ]]) @@ -287,12 +260,6 @@ not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [ not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother] | non_productive { /* A non productive action. */ } ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother] - not_reachable: useful { /* A not reachable action. */ } - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother] - non_productive: non_productive useless_token - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ]]) AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0, @@ -360,14 +327,18 @@ underivable: indirection; indirection: underivable; ]]) -AT_BISON_CHECK([[input.y]], 0, [], +AT_BISON_CHECK([[-fcaret input.y]], 0, [], [[input.y: warning: 2 nonterminals useless in grammar [-Wother] input.y: warning: 3 rules useless in grammar [-Wother] input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother] + exp: useful | underivable; + ^^^^^^^^^^^ input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother] + underivable: indirection; + ^^^^^^^^^^^ input.y:5.15-25: warning: rule useless in grammar [-Wother] -input.y:6.14-24: warning: rule useless in grammar [-Wother] -input.y:7.14-24: warning: rule useless in grammar [-Wother] + exp: useful | underivable; + ^^^^^^^^^^^ ]]) AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,