glr: fix improperly placed synclines

Predicates with GLR are issued with synclines in the middle of C code:

          case 2:
      if (! (#line 6 "sempred.y" /* glr.c:816  */
      new_syntax)) YYERROR;
    #line 793 "sempred.tab.c" /* glr.c:816  */
      break;

Reported by Rici Lake.
http://lists.gnu.org/archive/html/bug-bison/2018-05/msg00033.html

* data/c.m4 (b4_predicate_case): Be sure to start on column 0.
It would be nicer if b4_syncline could ensure this by itself
(that would avoid ugly code when synclines are disabled), but that's
way more work.
* tests/glr-regression.at (Predicates): Be a real end-to-end test.
This would have caught this error years ago...
This commit is contained in:
Akim Demaille
2018-05-29 09:02:21 +02:00
parent d0447d949b
commit 5952fe5abf
2 changed files with 44 additions and 10 deletions

View File

@@ -459,7 +459,8 @@ b4_syncline([@oline@], [@ofile@])
# ------------------------------------ # ------------------------------------
m4_define([b4_predicate_case], m4_define([b4_predicate_case],
[ case $1: [ case $1:
if (! ($2)) YYERROR; if (! (
$2)) YYERROR;
b4_syncline([@oline@], [@ofile@]) b4_syncline([@oline@], [@ofile@])
break;]) break;])

View File

@@ -1755,27 +1755,60 @@ AT_CLEANUP
## Predicates. ## ## Predicates. ##
## ## ## ##
## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ## ## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ##
## http://lists.gnu.org/archive/html/bug-bison/2018-05/msg00033.html ##
## ----------------------------------------------------------------- ## ## ----------------------------------------------------------------- ##
AT_SETUP([Predicates]) AT_SETUP([Predicates])
# FIXME: We need genuine test cases with uses of %?.
AT_DATA_GRAMMAR([input.y], AT_DATA_GRAMMAR([input.y],
[[%glr-parser [[%glr-parser
%error-verbose
%expect-rr 1 %expect-rr 1
%code requires
{
#include <assert.h>
#include <stdbool.h>
bool new_syntax = false;
const char *input = YY_NULLPTR;
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%% %%
// Exercise "%?{...}" and "%? {...}".
widget: widget:
%? {new_syntax} "widget" id new_args { $$ = f($3, $4); } %? {new_syntax} 'w' id new_args { printf("new"); }
| %?{!new_syntax} "widget" id old_args { $$ = f($3, $4); } | %?{!new_syntax} 'w' id old_args { printf("old"); }
; ;
id:; id: 'i';
new_args:; new_args: 'n';
old_args:; old_args: 'o';
%% %%
]AT_YYERROR_DEFINE[
int
yylex (void)
{
return *input++;
}
int
main (int argc, const char* argv[])
{
assert (argc == 2); (void) argc;
// First char decides whether new, or old syntax.
// Then the input.
new_syntax = argv[1][0] == 'N';
input = argv[1] + 1;
return yyparse ();
}
]]) ]])
AT_BISON_CHECK([[input.y]]) AT_BISON_CHECK([[-o input.c input.y]])
AT_COMPILE([input])
AT_PARSER_CHECK([[./input Nwin]], [0], [new])
AT_PARSER_CHECK([[./input Owin]], [1], [], [[syntax error, unexpected 'n', expecting 'o'
]])
AT_PARSER_CHECK([[./input Owio]], [0], [old])
AT_PARSER_CHECK([[./input Nwio]], [1], [], [[syntax error, unexpected 'o', expecting 'n'
]])
AT_CLEANUP AT_CLEANUP