[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]
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- diagnostics: better rule locations,
Akim Demaille <=