From f68a49ed4942714616e692f0fa2a8315368bae3b Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sat, 9 Feb 2013 18:26:38 +0100 Subject: [PATCH 1/1] -Wempty-rule: diagnose empty rules without %empty * src/complain.h, src/complain.c (warning_empty_rule, Wempty_rule): New warning category. (warnings_args, warnings_types): Adjust. * src/reader.c (grammar_rule_check): Check the empty rules are flagged by %empty. * tests/actions.at (Implicitly empty rule): New. * tests/existing.at: Add expected warnings. --- src/complain.c | 2 ++ src/complain.h | 2 ++ src/getargs.c | 1 + src/reader.c | 6 ++++ tests/actions.at | 22 +++++++++++++ tests/existing.at | 79 ++++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 107 insertions(+), 5 deletions(-) diff --git a/src/complain.c b/src/complain.c index 1162da29..cdc88030 100644 --- a/src/complain.c +++ b/src/complain.c @@ -63,6 +63,7 @@ static const char * const warnings_args[] = "conflicts-sr", "conflicts-rr", "deprecated", + "empty-rule", "precedence", "other", "all", @@ -78,6 +79,7 @@ static const int warnings_types[] = Wconflicts_sr, Wconflicts_rr, Wdeprecated, + Wempty_rule, Wprecedence, Wother, Wall, diff --git a/src/complain.h b/src/complain.h index 10ea19bf..422c48f4 100644 --- a/src/complain.h +++ b/src/complain.h @@ -35,6 +35,7 @@ typedef enum warning_yacc, /**< POSIXME. */ warning_conflicts_sr, /**< S/R conflicts. */ warning_conflicts_rr, /**< R/R conflicts. */ + warning_empty_rule, /**< Implicitly empty rules. */ warning_deprecated, /**< Obsolete constructs. */ warning_precedence, /**< Useless precedence and associativity. */ warning_other, /**< All other warnings. */ @@ -85,6 +86,7 @@ typedef enum Wconflicts_sr = 1 << warning_conflicts_sr, Wconflicts_rr = 1 << warning_conflicts_rr, Wdeprecated = 1 << warning_deprecated, + Wempty_rule = 1 << warning_empty_rule, Wprecedence = 1 << warning_precedence, Wother = 1 << warning_other, diff --git a/src/getargs.c b/src/getargs.c index 82c12983..15c765a4 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -327,6 +327,7 @@ Warning categories include:\n\ `conflicts-sr' S/R conflicts (enabled by default)\n\ `conflicts-rr' R/R conflicts (enabled by default)\n\ `deprecated' obsolete constructs\n\ + `empty-rule' empty rules without %empty\n\ `precedence' useless precedence and associativity\n\ `other' all other warnings (enabled by default)\n\ `all' all the warnings\n\ diff --git a/src/reader.c b/src/reader.c index a83f11c1..0422d204 100644 --- a/src/reader.c +++ b/src/reader.c @@ -339,6 +339,12 @@ grammar_rule_check (const symbol_list *r) complain (&r->percent_empty_loc, complaint, _("%%empty on non-empty rule")); + /* Check that empty rule => %empty. */ + if (!(r->next && r->next->content.sym) + && !r->midrule_parent_rule + && !r->percent_empty_loc.start.file) + complain (&r->location, Wempty_rule, _("empty rule without %%empty")); + /* See comments in grammar_current_rule_prec_set for how POSIX mandates this complaint. It's only for identifiers, so skip it for char literals and strings, which are always tokens. */ diff --git a/tests/actions.at b/tests/actions.at index 8a545dc0..1f6630a9 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -64,6 +64,28 @@ AT_PARSER_CHECK([./input], 0, AT_CLEANUP +## ----------------------- ## +## Implicitly empty rule. ## +## ----------------------- ## + +AT_SETUP([Implicitly empty rule]) + +AT_DATA_GRAMMAR([[1.y]], +[[%% +exp: a b; +a: /* empty. */ {}; +// A mid-rule action does not count as an empty rule. +b: {} {}; +]]) + +AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [], +[[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule] + a: /* empty. */ {}; + ^^ +]]) + +AT_CLEANUP + ## ------------------------ ## ## Invalid uses of %empty. ## ## ------------------------ ## diff --git a/tests/existing.at b/tests/existing.at index cd80c50a..6aa7a398 100644 --- a/tests/existing.at +++ b/tests/existing.at @@ -427,7 +427,17 @@ dnl don't like even `print $!4;'. dnl BISON-STDERR [AT_COND_CASE([[canonical LR]], -[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr] +[[input.y:66.10: warning: empty rule without %empty [-Wempty-rule] +input.y:169.8: warning: empty rule without %empty [-Wempty-rule] +input.y:174.12: warning: empty rule without %empty [-Wempty-rule] +input.y:179.13: warning: empty rule without %empty [-Wempty-rule] +input.y:187.15: warning: empty rule without %empty [-Wempty-rule] +input.y:201.8: warning: empty rule without %empty [-Wempty-rule] +input.y:206.21: warning: empty rule without %empty [-Wempty-rule] +input.y:220.20: warning: empty rule without %empty [-Wempty-rule] +input.y:299.13: warning: empty rule without %empty [-Wempty-rule] +input.y:322.9: warning: empty rule without %empty [-Wempty-rule] +input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr] input.y:19.8-16: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence] input.y:21.8-14: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence] input.y:21.16-22: warning: useless associativity for YSTRING, use %precedence [-Wprecedence] @@ -446,7 +456,17 @@ input.y:47.12-16: warning: useless associativity for UNARY, use %precedence [-Wp input.y:50.7-9: warning: useless associativity for '$', use %precedence [-Wprecedence] input.y:51.7-9: warning: useless associativity for '(', use %precedence [-Wprecedence] input.y:51.11-13: warning: useless precedence and associativity for ')' [-Wprecedence]]], -[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr] +[[input.y:66.10: warning: empty rule without %empty [-Wempty-rule] +input.y:169.8: warning: empty rule without %empty [-Wempty-rule] +input.y:174.12: warning: empty rule without %empty [-Wempty-rule] +input.y:179.13: warning: empty rule without %empty [-Wempty-rule] +input.y:187.15: warning: empty rule without %empty [-Wempty-rule] +input.y:201.8: warning: empty rule without %empty [-Wempty-rule] +input.y:206.21: warning: empty rule without %empty [-Wempty-rule] +input.y:220.20: warning: empty rule without %empty [-Wempty-rule] +input.y:299.13: warning: empty rule without %empty [-Wempty-rule] +input.y:322.9: warning: empty rule without %empty [-Wempty-rule] +input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr] input.y:19.8-16: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence] input.y:21.8-14: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence] input.y:21.16-22: warning: useless associativity for YSTRING, use %precedence [-Wprecedence] @@ -1404,7 +1424,29 @@ dnl INPUT dnl BISON-STDERR [AT_COND_CASE([[canonical LR]], -[[input.y: warning: 1876 shift/reduce conflicts [-Wconflicts-sr] +[[input.y:128.12: warning: empty rule without %empty [-Wempty-rule] +input.y:137.10: warning: empty rule without %empty [-Wempty-rule] +input.y:142.8: warning: empty rule without %empty [-Wempty-rule] +input.y:161.15: warning: empty rule without %empty [-Wempty-rule] +input.y:179.17: warning: empty rule without %empty [-Wempty-rule] +input.y:205.16: warning: empty rule without %empty [-Wempty-rule] +input.y:213.9: warning: empty rule without %empty [-Wempty-rule] +input.y:225.6: warning: empty rule without %empty [-Wempty-rule] +input.y:292.18: warning: empty rule without %empty [-Wempty-rule] +input.y:294.19: warning: empty rule without %empty [-Wempty-rule] +input.y:367.16: warning: empty rule without %empty [-Wempty-rule] +input.y:373.11: warning: empty rule without %empty [-Wempty-rule] +input.y:387.15: warning: empty rule without %empty [-Wempty-rule] +input.y:401.18: warning: empty rule without %empty [-Wempty-rule] +input.y:413.15: warning: empty rule without %empty [-Wempty-rule] +input.y:443.15: warning: empty rule without %empty [-Wempty-rule] +input.y:471.15: warning: empty rule without %empty [-Wempty-rule] +input.y:474.15: warning: empty rule without %empty [-Wempty-rule] +input.y:489.15: warning: empty rule without %empty [-Wempty-rule] +input.y:506.14: warning: empty rule without %empty [-Wempty-rule] +input.y:587.9: warning: empty rule without %empty [-Wempty-rule] +input.y:591.14: warning: empty rule without %empty [-Wempty-rule] +input.y: warning: 1876 shift/reduce conflicts [-Wconflicts-sr] input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr] input.y:32.9-12: warning: useless associativity for HQUA, use %precedence [-Wprecedence] input.y:53.8-14: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence] @@ -1412,7 +1454,29 @@ input.y:54.9-15: warning: useless associativity for HORELSE, use %precedence [-W input.y:55.9-16: warning: useless associativity for HANDTHEN, use %precedence [-Wprecedence] input.y:61.9-12: warning: useless associativity for HNOT, use %precedence [-Wprecedence] input.y:68.7-11: warning: useless associativity for UNEAR, use %precedence [-Wprecedence]]], -[[input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr] +[[input.y:128.12: warning: empty rule without %empty [-Wempty-rule] +input.y:137.10: warning: empty rule without %empty [-Wempty-rule] +input.y:142.8: warning: empty rule without %empty [-Wempty-rule] +input.y:161.15: warning: empty rule without %empty [-Wempty-rule] +input.y:179.17: warning: empty rule without %empty [-Wempty-rule] +input.y:205.16: warning: empty rule without %empty [-Wempty-rule] +input.y:213.9: warning: empty rule without %empty [-Wempty-rule] +input.y:225.6: warning: empty rule without %empty [-Wempty-rule] +input.y:292.18: warning: empty rule without %empty [-Wempty-rule] +input.y:294.19: warning: empty rule without %empty [-Wempty-rule] +input.y:367.16: warning: empty rule without %empty [-Wempty-rule] +input.y:373.11: warning: empty rule without %empty [-Wempty-rule] +input.y:387.15: warning: empty rule without %empty [-Wempty-rule] +input.y:401.18: warning: empty rule without %empty [-Wempty-rule] +input.y:413.15: warning: empty rule without %empty [-Wempty-rule] +input.y:443.15: warning: empty rule without %empty [-Wempty-rule] +input.y:471.15: warning: empty rule without %empty [-Wempty-rule] +input.y:474.15: warning: empty rule without %empty [-Wempty-rule] +input.y:489.15: warning: empty rule without %empty [-Wempty-rule] +input.y:506.14: warning: empty rule without %empty [-Wempty-rule] +input.y:587.9: warning: empty rule without %empty [-Wempty-rule] +input.y:591.14: warning: empty rule without %empty [-Wempty-rule] +input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr] input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr] input.y:32.9-12: warning: useless associativity for HQUA, use %precedence [-Wprecedence] input.y:53.8-14: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence] @@ -2001,7 +2065,12 @@ dnl without being followed by "of".) [[VARIABLE, '=', LABEL, LEFT, DOT_X]], dnl BISON-STDERR -[[input.y:471.11-48: warning: rule useless in parser due to conflicts [-Wother] +[[input.y:202.19: warning: empty rule without %empty [-Wempty-rule] +input.y:270.6: warning: empty rule without %empty [-Wempty-rule] +input.y:292.12: warning: empty rule without %empty [-Wempty-rule] +input.y:309.17: warning: empty rule without %empty [-Wempty-rule] +input.y:382.13: warning: empty rule without %empty [-Wempty-rule] +input.y:471.11-48: warning: rule useless in parser due to conflicts [-Wother] input.y:19.8-12: warning: useless associativity for LABEL, use %precedence [-Wprecedence] input.y:20.8-15: warning: useless associativity for VARIABLE, use %precedence [-Wprecedence] input.y:21.8-13: warning: useless associativity for NUMBER, use %precedence [-Wprecedence] -- 2.45.2