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: empty rule without %empty [-Wempty-rule]
12 | b:{
| ^
-input.y:14.2: warning: empty rule without %empty [-Wempty-rule]
- 14 | c:
- | ^
-input.y:15.2: warning: empty rule without %empty [-Wempty-rule]
- 15 | d
- | ^
-input.y:17.2: warning: empty rule without %empty [-Wempty-rule]
- 17 | e:
+input.y:14.3: warning: empty rule without %empty [-Wempty-rule]
+ 14 | c:
+ | ^
+input.y:16.2: warning: empty rule without %empty [-Wempty-rule]
+ 16 | :
| ^
+input.y:17.3: warning: empty rule without %empty [-Wempty-rule]
+ 17 | e:
+ | ^
]])
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]