Hi! > Le 28 mai 2018 à 07:23, Rici Lake <ricil...@gmail.com> a écrit : > > Version: 3.04 (also fails on 3.01 and 3.02) > Platform: Linux but I think it would be the same on any platform > > To reproduce, it is possible to use the semantic predicate test snippet > already in the bison test suite: > > %glr-parser > %expect-rr 1 > %% > // Exercise "%?{...}" and "%? {...}". > widget: > %? {new_syntax} "widget" id new_args { $$ = f($3, $4); } > | %?{!new_syntax} "widget" id old_args { $$ = f($3, $4); } > ; > id:; > new_args:; > old_args:; > %% > > produces (at line 789): > > case 2: > if (! (#line 6 "sempred.y" /* glr.c:816 */ > new_syntax)) YYERROR; > #line 793 "sempred.tab.c" /* glr.c:816 */ > break; > > which of course produces a compiler error. > > As a quick workaround, I fixed the problem by altering line 462 of > data/c.m4 to read > > if (! ( > $2)) YYERROR;
FTR, option —no-lines is another possible workaround. I’ll apply the following changes to maint in a couple of days, to leave some time for reviews. Thanks for the report! commit d0447d949b38e653029b1ffb484b361e8ee705f2 Author: Akim Demaille <akim.demai...@gmail.com> Date: Tue May 29 09:00:59 2018 +0200 bison: be git grep friendly * src/output.c (user_actions_output): Make calls to b4_case and b4_predicate_case explicit. diff --git a/src/output.c b/src/output.c index 7c98bb97..d1b90377 100644 --- a/src/output.c +++ b/src/output.c @@ -357,8 +357,8 @@ user_actions_output (FILE *out) for (r = 0; r < nrules; ++r) if (rules[r].action) { - fprintf (out, "b4_%scase(%d, [b4_syncline(%d, ", - rules[r].is_predicate ? "predicate_" : "", + fprintf (out, "%s(%d, [b4_syncline(%d, ", + rules[r].is_predicate ? "b4_predicate_case" : "b4_case", r + 1, rules[r].action_location.start.line); string_output (out, rules[r].action_location.start.file); fprintf (out, ")\n[ %s]])\n\n", rules[r].action); commit 5952fe5abfd2dfa69862791b67086cbd41f185d1 Author: Akim Demaille <akim.demai...@gmail.com> Date: Tue May 29 09:02:21 2018 +0200 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... diff --git a/data/c.m4 b/data/c.m4 index f2006b34..8607f55f 100644 --- a/data/c.m4 +++ b/data/c.m4 @@ -459,7 +459,8 @@ b4_syncline([@oline@], [@ofile@]) # ------------------------------------ m4_define([b4_predicate_case], [ case $1: - if (! ($2)) YYERROR; + if (! ( +$2)) YYERROR; b4_syncline([@oline@], [@ofile@]) break;]) diff --git a/tests/glr-regression.at b/tests/glr-regression.at index 2758b8f6..6ca6813d 100644 --- a/tests/glr-regression.at +++ b/tests/glr-regression.at @@ -1755,27 +1755,60 @@ AT_CLEANUP ## Predicates. ## ## ## ## 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]) -# FIXME: We need genuine test cases with uses of %?. - AT_DATA_GRAMMAR([input.y], [[%glr-parser +%error-verbose %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: - %? {new_syntax} "widget" id new_args { $$ = f($3, $4); } -| %?{!new_syntax} "widget" id old_args { $$ = f($3, $4); } + %? {new_syntax} 'w' id new_args { printf("new"); } +| %?{!new_syntax} 'w' id old_args { printf("old"); } ; -id:; -new_args:; -old_args:; +id: 'i'; +new_args: 'n'; +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