bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

diagnostics: better rule locations


From: Akim Demaille
Subject: diagnostics: better rule locations
Date: Wed, 24 Apr 2019 23:08:06 +0200

commit 935d119c82f018a135b424ced986e20299a0db14
Author: Akim Demaille <address@hidden>
Date:   Wed Apr 24 08:04:43 2019 +0200

    diagnostics: better rule locations
    
    The "identifier and colon" of a rule is implemented as a single token,
    but whose location is only that of the identifier (so that messages
    about the lhs of a rule are accurate).  When reducing empty rules, the
    default location is the single point location on the end of the
    previous symbol.  As a consequence, when Bison parses a grammar, the
    location of the right-hand side of an empty rule is based on the
    lhs, *independently of the position of the colon*.  And the colon can
    be way farther, separated by comments, white spaces, including empty
    lines.
    
    As a result, some messages look really bad.  For instance:
    
        $ cat foo.y
        %%
        foo     : /* empty */
        bar
        : /* empty */
    
    gives
    
        $ bison -Wall foo.y
        foo.y:2.4: warning: empty rule without %empty [-Wempty-rule]
            2 | foo     : /* empty */
              |    ^
        foo.y:3.4: warning: empty rule without %empty [-Wempty-rule]
            3 | bar
              |    ^
    
    The carets are not at the right column, not even the right line.
    
    This commit passes the colon "again" after the "id colon" token, which
    gives more accurate locations for these messages:
    
        $ bison -Wall foo.y
        foo.y:2.10: warning: empty rule without %empty [-Wempty-rule]
            2 | foo     : /* empty */
              |          ^
        foo.y:4.2: warning: empty rule without %empty [-Wempty-rule]
            4 | : /* empty */
              |  ^
    
    * src/scan-gram.l (SC_AFTER_IDENTIFIER): Rollback the colon, so that
    we scan it again afterwards.
    (INITIAL): Scan colons.
    * src/parse-gram.y (COLON): New.
    (rules): Parse the colon after the rule's id_colon (and possible
    named reference).
    * tests/actions.at, tests/conflicts.at, tests/diagnostics.at,
    * tests/existing.at: Adjust.

diff --git a/NEWS b/NEWS
index 89821d82..3228a6fd 100644
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,9 @@ GNU Bison NEWS
         3 | expr: expr '+' "number" { $$ = $1 + $2; }
           |                                     ^~
 
+  Other constructs now also have better locations, resulting in more precise
+  diagnostics.
+
 ** New features
 
 *** Colored diagnostics
diff --git a/src/parse-gram.y b/src/parse-gram.y
index 1ac1409c..1c2199dc 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -189,6 +189,7 @@
 %token BRACED_PREDICATE "%?{...}"
 %token BRACKETED_ID    "[identifier]"
 %token CHAR            "char"
+%token COLON           ":"
 %token EPILOGUE        "epilogue"
 %token EQUAL           "="
 %token ID              "identifier"
@@ -627,7 +628,7 @@ rules_or_grammar_declaration:
 ;
 
 rules:
-  id_colon named_ref.opt { current_lhs ($1, @1, $2); } rhses.1
+  id_colon named_ref.opt { current_lhs ($1, @1, $2); } ":" rhses.1
     {
       /* Free the current lhs. */
       current_lhs (0, @1, 0);
@@ -635,8 +636,8 @@ rules:
 ;
 
 rhses.1:
-  rhs                { grammar_current_rule_end (@1); }
-| rhses.1 "|" rhs    { grammar_current_rule_end (@3); }
+  rhs                { grammar_current_rule_end (@rhs); }
+| rhses.1 "|" rhs    { grammar_current_rule_end (@rhs); }
 | rhses.1 ";"
 ;
 
diff --git a/src/scan-gram.l b/src/scan-gram.l
index 96bb3ba0..f03acfd6 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -289,6 +289,7 @@ eqopt    ({sp}=)?
     complain (loc, complaint, _("invalid directive: %s"), quote (yytext));
   }
 
+  ":"                     return COLON;
   "="                     return EQUAL;
   "|"                     return PIPE;
   ";"                     return SEMICOLON;
@@ -402,6 +403,7 @@ eqopt    ({sp}=)?
       }
   }
   ":" {
+    ROLLBACK_CURRENT_TOKEN;
     BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
     *loc = id_loc;
     return ID_COLON;
diff --git a/tests/actions.at b/tests/actions.at
index f9fa20c8..ec2e8836 100644
--- a/tests/actions.at
+++ b/tests/actions.at
@@ -114,6 +114,7 @@ AT_PARSER_CHECK([input], 0,
 
 AT_CLEANUP
 
+
 ## ----------------------- ##
 ## Implicitly empty rule.  ##
 ## ----------------------- ##
@@ -158,6 +159,7 @@ AT_BISON_OPTION_POPDEFS
 AT_CLEANUP
 
 
+
 ## ------------------------ ##
 ## Invalid uses of %empty.  ##
 ## ------------------------ ##
diff --git a/tests/conflicts.at b/tests/conflicts.at
index 4bc6eba4..44edb0bf 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -1526,7 +1526,7 @@ input.y: warning: 1 reduce/reduce conflict 
[-Wconflicts-rr]
 input.y:12.5-20: warning: rule useless in parser due to conflicts [-Wother]
 input.y:20.5-20: warning: rule useless in parser due to conflicts [-Wother]
 input.y:21.4: warning: rule useless in parser due to conflicts [-Wother]
-input.y:25.13: warning: rule useless in parser due to conflicts [-Wother]
+input.y:25.14: warning: rule useless in parser due to conflicts [-Wother]
 input.y:25.16: warning: rule useless in parser due to conflicts [-Wother]
 input.y:31.5-7: warning: rule useless in parser due to conflicts [-Wother]
 input.y:32.4: warning: rule useless in parser due to conflicts [-Wother]
diff --git a/tests/diagnostics.at b/tests/diagnostics.at
index 8fc3aa66..ab5fde38 100644
--- a/tests/diagnostics.at
+++ b/tests/diagnostics.at
@@ -103,15 +103,15 @@ e:
 input.y:12.3-13.1: <warning>warning:</warning> empty rule without %empty 
[<warning>-Wempty-rule</warning>]
    12 | b:<warning>{</warning>
       |   <warning>^</warning>
-input.y:14.2: <warning>warning:</warning> empty rule without %empty 
[<warning>-Wempty-rule</warning>]
-   14 | c<warning>:</warning>
-      |  <warning>^</warning>
-input.y:15.2: <warning>warning:</warning> empty rule without %empty 
[<warning>-Wempty-rule</warning>]
-   15 | d
-      |  <warning>^</warning>
-input.y:17.2: <warning>warning:</warning> empty rule without %empty 
[<warning>-Wempty-rule</warning>]
-   17 | e<warning>:</warning>
+input.y:14.3: <warning>warning:</warning> empty rule without %empty 
[<warning>-Wempty-rule</warning>]
+   14 | c:
+      |   <warning>^</warning>
+input.y:16.2: <warning>warning:</warning> empty rule without %empty 
[<warning>-Wempty-rule</warning>]
+   16 | :
       |  <warning>^</warning>
+input.y:17.3: <warning>warning:</warning> empty rule without %empty 
[<warning>-Wempty-rule</warning>]
+   17 | e:
+      |   <warning>^</warning>
 ]])
 
 
diff --git a/tests/existing.at b/tests/existing.at
index 27bd0be3..782633ad 100644
--- a/tests/existing.at
+++ b/tests/existing.at
@@ -427,15 +427,15 @@ dnl don't like even 'print $!4;'.
 
 dnl BISON-STDERR
 [[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:170.10: warning: empty rule without %empty [-Wempty-rule]
+input.y:175.10: warning: empty rule without %empty [-Wempty-rule]
+input.y:180.10: warning: empty rule without %empty [-Wempty-rule]
+input.y:188.10: warning: empty rule without %empty [-Wempty-rule]
+input.y:202.10: warning: empty rule without %empty [-Wempty-rule]
+input.y:207.10: warning: empty rule without %empty [-Wempty-rule]
+input.y:221.10: warning: empty rule without %empty [-Wempty-rule]
+input.y:300.10: warning: empty rule without %empty [-Wempty-rule]
+input.y:323.10: warning: empty rule without %empty [-Wempty-rule]
 ]AT_COND_CASE([[canonical LR]],
 [[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]]],
 [[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]]])[
@@ -1395,28 +1395,28 @@ dnl INPUT
 [[]],
 
 dnl BISON-STDERR
-[[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:128.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:137.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:142.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:161.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:179.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:205.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:213.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:225.18: 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:294.20: warning: empty rule without %empty [-Wempty-rule]
+input.y:367.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:373.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:387.18: 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:413.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:443.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:471.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:474.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:489.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:506.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:587.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:591.18: warning: empty rule without %empty [-Wempty-rule]
 ]AT_COND_CASE([[canonical LR]],
 [[input.y: warning: 1876 shift/reduce conflicts [-Wconflicts-sr]
 input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]]],
@@ -2009,11 +2009,11 @@ dnl without being followed by "of".)
 [[VARIABLE, '=', LABEL, LEFT, DOT_X]],
 
 dnl BISON-STDERR
-[[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:202.20: warning: empty rule without %empty [-Wempty-rule]
+input.y:270.7: warning: empty rule without %empty [-Wempty-rule]
+input.y:292.13: warning: empty rule without %empty [-Wempty-rule]
+input.y:309.18: warning: empty rule without %empty [-Wempty-rule]
+input.y:382.14: warning: empty rule without %empty [-Wempty-rule]
 input.y:471.11-48: warning: rule useless in parser due to conflicts [-Wother]
 input.y:154.1-5: warning: useless associativity for LABEL, use %precedence 
[-Wprecedence]
 input.y:156.1-5: warning: useless associativity for VARIABLE, use %precedence 
[-Wprecedence]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]