1 # Checking GLR Parsing: Regression Tests -*- Autotest -*-
3 # Copyright (C) 2002-2003, 2005-2007, 2009-2015, 2018-2020 Free Software
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 AT_BANNER([[GLR Regression Tests]])
21 ## ---------------------------- ##
22 ## Badly Collapsed GLR States. ##
23 ## ---------------------------- ##
25 AT_SETUP([Badly Collapsed GLR States])
27 AT_BISON_OPTION_PUSHDEFS
28 AT_DATA_GRAMMAR([glr-regr1.y],
29 [[/* Regression Test: Improper state compression */
30 /* Reported by Scott McPeak */
38 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
47 /* -------- productions ------ */
50 StartSymbol: E { $$=0; } %merge <exprMerge>
53 E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); } %merge <exprMerge>
54 | 'B' { $$=2; printf("E -> 'B'\n"); } %merge <exprMerge>
59 /* ---------- C code ----------- */
62 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
70 const char *input = YY_NULLPTR;
73 main (int argc, const char* argv[])
75 assert (argc == 2); (void) argc;
88 AT_BISON_OPTION_POPDEFS
90 AT_BISON_CHECK([[-o glr-regr1.c -rall glr-regr1.y]], 0, [],
91 [[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
92 glr-regr1.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
94 AT_COMPILE([glr-regr1])
95 AT_PARSER_CHECK([[glr-regr1 BPBPB]], 0,
109 ## -------------------------------------------------------------- ##
110 ## Improper handling of embedded actions and $-N in GLR parsers. ##
111 ## -------------------------------------------------------------- ##
113 AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers])
115 AT_BISON_OPTION_PUSHDEFS
116 AT_DATA_GRAMMAR([glr-regr2a.y],
117 [[/* Regression Test: Improper handling of embedded actions and $-N */
118 /* Reported by S. Eken */
121 #define YYSTYPE char *
139 { printf ("Variable: '%s'\n", $2); }
142 | 's' var_list 't' 'e'
143 { printf ("Varlist: '%s'\n", $2); free ($2); }
144 | 's' var 't' var_printer 'x'
158 char *s = YY_CAST (char *, realloc ($1, strlen ($1) + 1 + strlen ($3) + 1));
167 { printf ("Variable: '%s'\n", $-1); }
177 assert (!feof (stdin));
178 switch (fscanf (input, " %1[a-z,]", buf))
185 if (fscanf (input, "%49s", buf) != 1)
190 assert (strlen (buf) < sizeof buf - 1);
191 s = YY_CAST (char *, malloc (strlen (buf) + 1));
201 main (int argc, char **argv)
205 if (argc == 2 && !(input = fopen (argv[1], "r")))
208 if (argc == 2 && fclose (input))
213 AT_BISON_OPTION_POPDEFS
215 AT_BISON_CHECK([[-o glr-regr2a.c -rall glr-regr2a.y]], 0, [],
216 [[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
217 glr-regr2a.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
219 AT_COMPILE([glr-regr2a])
221 AT_DATA([input1.txt],
222 [[s VARIABLE_1 t v x q
224 AT_PARSER_CHECK([[glr-regr2a input1.txt]], 0,
225 [[Variable: 'VARIABLE_1'
228 AT_DATA([input2.txt],
229 [[s VARIABLE_1 , ANOTHER_VARIABLE_2 t e
231 AT_PARSER_CHECK([[glr-regr2a input2.txt]],
233 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
236 AT_DATA([input3.txt],
239 AT_PARSER_CHECK([[glr-regr2a input3.txt]], 0,
240 [[Variable: 'VARIABLE_3'
246 ## --------------------------------------------- ##
247 ## Improper merging of GLR delayed action sets. ##
248 ## --------------------------------------------- ##
250 AT_SETUP([Improper merging of GLR delayed action sets])
252 AT_BISON_OPTION_PUSHDEFS
253 AT_DATA_GRAMMAR([glr-regr3.y],
254 [[/* Regression Test: Improper merging of GLR delayed action sets. */
255 /* Reported by M. Rosien */
263 static int MergeRule (int x0, int x1);
267 #define RULE(x) (1 << (x))
275 %token P1 P2 T1 T2 T3 T4 O1 O2
279 S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
282 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
285 NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
286 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
289 NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
290 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
293 NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
294 | NT2 { $$ = RULE(8); } %merge<MergeRule>
295 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
298 NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
301 NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
302 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
308 MergeRule (int x0, int x1)
314 FILE *input = YY_NULLPTR;
316 int P[] = { P1, P2 };
317 int O[] = { O1, O2 };
318 int T[] = { T1, T2, T3, T4 };
323 assert (!feof (stdin));
324 if (fscanf (input, "%2s", inp) == EOF)
328 case 'p': return P[inp[1] - '1'];
329 case 't': return T[inp[1] - '1'];
330 case 'o': return O[inp[1] - '1'];
336 main (int argc, char* argv[])
340 if (argc == 2 && !(input = fopen (argv[1], "r")))
343 if (argc == 2 && fclose (input))
348 AT_BISON_OPTION_POPDEFS
350 AT_BISON_CHECK([[-o glr-regr3.c -rall glr-regr3.y]], 0, [],
351 [[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
352 glr-regr3.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
353 glr-regr3.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
355 AT_COMPILE([glr-regr3])
358 [[p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2
360 AT_PARSER_CHECK([[glr-regr3 input.txt]],
368 ## ---------------------------------------------------------------------- ##
369 ## Duplicate representation of merged trees. See ##
370 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
371 ## ---------------------------------------------------------------------- ##
373 AT_SETUP([Duplicate representation of merged trees])
375 AT_BISON_OPTION_PUSHDEFS
376 AT_DATA_GRAMMAR([glr-regr4.y],
379 %union { char *ptr; }
380 %type <ptr> S A A1 A2 B
387 static char *merge (YYSTYPE, YYSTYPE);
388 static char *make_value (char const *, char const *);
391 static char *ptrs[100];
392 static char **ptrs_next = ptrs;
397 tree: S { printf ("%s\n", $1); } ;
400 A %merge<merge> { $$ = make_value ("S", $1); }
401 | B %merge<merge> { $$ = make_value ("S", $1); }
405 A1 %merge<merge> { $$ = make_value ("A", $1); }
406 | A2 %merge<merge> { $$ = make_value ("A", $1); }
409 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
410 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
411 B: 'a' { $$ = make_value ("B", "'a'"); } ;
415 ]AT_YYLEX_DEFINE(["a"])[
420 int status = yyparse ();
421 while (ptrs_next != ptrs)
427 make_value (char const *parent, char const *child)
429 char const format[] = "%s <- %s";
430 char *value = *ptrs_next++ =
431 YY_CAST (char *, malloc (strlen (parent) + strlen (child) + sizeof format));
432 sprintf (value, format, parent, child);
437 merge (YYSTYPE s1, YYSTYPE s2)
439 char const format[] = "merge{ %s and %s }";
440 char *value = *ptrs_next++ =
441 YY_CAST (char *, malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format));
442 sprintf (value, format, s1.ptr, s2.ptr);
446 AT_BISON_OPTION_POPDEFS
448 AT_BISON_CHECK([[-o glr-regr4.c -rall glr-regr4.y]], 0, [],
449 [[glr-regr4.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
450 glr-regr4.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
452 AT_COMPILE([glr-regr4])
454 AT_PARSER_CHECK([[glr-regr4]], 0,
455 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
461 ## ------------------------------------------------------------------------- ##
462 ## User destructor for unresolved GLR semantic value. See ##
463 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
464 ## ------------------------------------------------------------------------- ##
466 AT_SETUP([User destructor for unresolved GLR semantic value])
468 AT_BISON_OPTION_PUSHDEFS
469 AT_DATA_GRAMMAR([glr-regr5.y],
476 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
481 %union { int value; }
485 if ($$ != MAGIC_VALUE)
487 fprintf (stderr, "Bad destructor call.\n");
495 'a' { $$ = MAGIC_VALUE; }
496 | 'a' { $$ = MAGIC_VALUE; }
501 ]AT_YYLEX_DEFINE(["a"])[
504 AT_BISON_OPTION_POPDEFS
506 AT_BISON_CHECK([[-o glr-regr5.c -rall glr-regr5.y]], 0, [],
507 [[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
508 glr-regr5.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
510 AT_COMPILE([glr-regr5])
512 AT_PARSER_CHECK([[glr-regr5]], 1, [],
519 ## ------------------------------------------------------------------------- ##
520 ## User destructor after an error during a split parse. See ##
521 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
522 ## ------------------------------------------------------------------------- ##
524 AT_SETUP([User destructor after an error during a split parse])
526 AT_BISON_OPTION_PUSHDEFS
527 AT_DATA_GRAMMAR([glr-regr6.y],
538 %union { int value; }
542 printf ("Destructor called.\n");
551 ]AT_YYLEX_DEFINE(["a"])[
554 AT_BISON_OPTION_POPDEFS
556 AT_BISON_CHECK([[-o glr-regr6.c -rall glr-regr6.y]], 0, [],
557 [[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
558 glr-regr6.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
560 AT_COMPILE([glr-regr6])
562 AT_PARSER_CHECK([[glr-regr6]], 1,
571 ## ------------------------------------------------------------------------- ##
572 ## Duplicated user destructor for lookahead. See ##
573 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
574 ## ------------------------------------------------------------------------- ##
576 AT_SETUP([Duplicated user destructor for lookahead])
578 AT_BISON_OPTION_PUSHDEFS
579 AT_DATA_GRAMMAR([glr-regr7.y],
586 #define YYSTACKEXPANDABLE 0
587 typedef struct count_node {
589 struct count_node *prev;
591 static count_node *tail;
596 %union { count_node *node; }
601 fprintf (stderr, "Destructor called on same value twice.\n");
619 yylval.node = YY_CAST (count_node*, malloc (sizeof *yylval.node));
622 fprintf (stderr, "Test inconclusive.\n");
625 yylval.node->count = 0;
626 yylval.node->prev = tail;
635 int status = yyparse ();
638 count_node *prev = tail->prev;
645 AT_BISON_OPTION_POPDEFS
647 AT_BISON_CHECK([[-o glr-regr7.c -rall glr-regr7.y]], 0, [],
648 [[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
649 glr-regr7.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
651 AT_COMPILE([glr-regr7])
653 AT_PARSER_CHECK([[glr-regr7]], 2, [],
660 ## ------------------------------------------------------------------------- ##
661 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
662 ## report by Claudia Hermann. ##
663 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
664 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
665 ## ------------------------------------------------------------------------- ##
667 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
669 AT_BISON_OPTION_PUSHDEFS
670 AT_DATA_GRAMMAR([glr-regr8.y],
689 PortClause : T_PORT InterfaceDeclaration T_PORT
690 { printf("%d/%d - %d/%d - %d/%d\n",
691 @1.first_column, @1.last_column,
692 @2.first_column, @2.last_column,
693 @3.first_column, @3.last_column); }
696 InterfaceDeclaration : OptConstantWord %dprec 1
697 | OptSignalWord %dprec 2
700 OptConstantWord : %empty
704 OptSignalWord : %empty
705 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
722 yylloc.first_column = 1;
723 yylloc.last_column = 9;
726 yylloc.first_column = 13;
727 yylloc.last_column = 17;
736 AT_BISON_OPTION_POPDEFS
738 AT_BISON_CHECK([[-o glr-regr8.c -rall glr-regr8.y]], 0, [],
739 [[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
740 glr-regr8.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
742 AT_COMPILE([glr-regr8])
744 AT_PARSER_CHECK([[glr-regr8]], 0,
753 ## ------------------------------------------------------------------------- ##
754 ## No users destructors if stack 0 deleted. See ##
755 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
756 ## ------------------------------------------------------------------------- ##
758 AT_SETUP([No users destructors if stack 0 deleted])
760 AT_BISON_OPTION_PUSHDEFS
761 AT_DATA_GRAMMAR([glr-regr9.y],
768 # define YYSTACKEXPANDABLE 0
769 static int tokens = 0;
770 static int destructors = 0;
776 %union { int dummy; }
786 ambig0 'a' { destructors += 2; USE ($2); }
787 | ambig1 start { destructors += 1; }
788 | ambig2 start { destructors += 1; }
809 exit_status = yyparse ();
810 if (tokens != destructors)
812 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
818 AT_BISON_OPTION_POPDEFS
820 AT_BISON_CHECK([[-o glr-regr9.c -rall glr-regr9.y]], 0, [],
821 [[glr-regr9.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
822 glr-regr9.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
824 AT_COMPILE([glr-regr9])
826 AT_PARSER_CHECK([[glr-regr9]], 0, [],
833 ## ------------------------------------------------------ ##
834 ## Corrupted semantic options if user action cuts parse. ##
835 ## ------------------------------------------------------ ##
837 AT_SETUP([Corrupted semantic options if user action cuts parse])
839 AT_BISON_OPTION_PUSHDEFS
840 AT_DATA_GRAMMAR([glr-regr10.y],
847 #define GARBAGE_SIZE 50
848 static char garbage[GARBAGE_SIZE];
853 %union { char *ptr; }
859 %dprec 2 { $$ = garbage; YYACCEPT; }
860 | %dprec 1 { $$ = garbage; YYACCEPT; }
871 for (i = 0; i < GARBAGE_SIZE; i+=1)
876 AT_BISON_OPTION_POPDEFS
878 AT_BISON_CHECK([[-o glr-regr10.c -rall glr-regr10.y]], 0, [],
879 [[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
880 glr-regr10.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
882 AT_COMPILE([glr-regr10])
884 AT_PARSER_CHECK([[glr-regr10]], 0, [], [])
889 ## --------------------------------------------------- ##
890 ## Undesirable destructors if user action cuts parse. ##
891 ## --------------------------------------------------- ##
893 AT_SETUP([Undesirable destructors if user action cuts parse])
895 AT_BISON_OPTION_PUSHDEFS
896 AT_DATA_GRAMMAR([glr-regr11.y],
902 static int destructors = 0;
908 %union { int dummy; }
910 %destructor { destructors += 1; } 'a'
915 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
916 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
922 ]AT_YYLEX_DEFINE(["a"])[
927 int exit_status = yyparse ();
928 if (destructors != 1)
930 fprintf (stderr, "Destructor calls: %d\n", destructors);
936 AT_BISON_OPTION_POPDEFS
938 AT_BISON_CHECK([[-o glr-regr11.c -rall glr-regr11.y]], 0, [],
939 [[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
940 glr-regr11.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
942 AT_COMPILE([glr-regr11])
944 AT_PARSER_CHECK([[glr-regr11]], 0, [], [])
949 ## -------------------------------------------------- ##
950 ## Leaked semantic values if user action cuts parse. ##
951 ## -------------------------------------------------- ##
953 AT_SETUP([Leaked semantic values if user action cuts parse])
955 AT_BISON_OPTION_PUSHDEFS
956 AT_DATA_GRAMMAR([glr-regr12.y],
960 %union { int dummy; }
961 %token PARENT_RHS_AFTER
962 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
963 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
964 %destructor { merged_value = 0; } merged
965 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
970 static int merge (YYSTYPE, YYSTYPE);
973 static int parent_rhs_before_value = 0;
974 static int merged_value = 0;
975 static int parent_rhs_after_value = 0;
989 parent_rhs_after_value = 0;
994 parent_rhs_before merged PARENT_RHS_AFTER {
996 parent_rhs_before_value = 0;
998 parent_rhs_after_value = 0;
1005 parent_rhs_before_value = 1;
1014 | cut %merge<merge> {
1020 cut: { YYACCEPT; } ;
1025 merge (YYSTYPE s1, YYSTYPE s2)
1028 return s1.dummy + s2.dummy;
1032 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1033 [if (res == PARENT_RHS_AFTER)
1034 parent_rhs_after_value = 1;])[
1039 int exit_status = yyparse ();
1040 if (parent_rhs_before_value)
1042 fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1047 fprintf (stderr, "'merged' destructor not called.\n");
1050 if (parent_rhs_after_value)
1052 fprintf (stderr, "'PARENT_RHS_AFTER' destructor not called.\n");
1058 AT_BISON_OPTION_POPDEFS
1060 AT_BISON_CHECK([[-o glr-regr12.c -rall glr-regr12.y]], 0, [],
1061 [[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1062 glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1063 glr-regr12.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1065 AT_COMPILE([glr-regr12])
1067 AT_PARSER_CHECK([[glr-regr12]], 0, [], [])
1072 ## ------------------------------------------------------------------------- ##
1073 ## Incorrect lookahead during deterministic GLR. See ##
1074 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1075 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1076 ## ------------------------------------------------------------------------- ##
1078 AT_SETUP([Incorrect lookahead during deterministic GLR])
1080 AT_BISON_OPTION_PUSHDEFS
1081 AT_DATA_GRAMMAR([glr-regr13.y],
1084 - Defaulted state with initial yychar: yychar == YYEMPTY.
1085 - Nondefaulted state: yychar != YYEMPTY.
1086 - Defaulted state after lookahead: yychar != YYEMPTY.
1087 - Defaulted state after shift: yychar == YYEMPTY.
1088 - User action changing the lookahead. */
1093 ]AT_YYERROR_DECLARE[
1095 static void print_lookahead (char const *);
1099 %define parse.assert
1100 %union { char value; }
1101 %type <value> 'a' 'b'
1108 defstate_init defstate_shift 'b' change_lookahead 'a' {
1110 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1115 print_lookahead ("defstate_init <- empty string");
1119 nondefstate defstate_look 'a' {
1121 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1126 print_lookahead ("defstate_look <- empty string");
1131 print_lookahead ("nondefstate <- empty string");
1135 print_lookahead ("nondefstate <- 'b'");
1147 ]AT_YYLEX_DEFINE(["ab"],
1148 [yylval.value = YY_CAST (char, res + 'A' - 'a')])[
1151 print_lookahead (char const *reduction)
1153 printf ("%s:\n yychar=", reduction);
1154 if (yychar == YYEMPTY)
1156 else if (yychar == YYEOF)
1160 printf ("'%c', yylval='", yychar);
1161 if (yylval.value > ' ')
1162 printf ("%c", yylval.value);
1163 printf ("', yylloc=(%d,%d),(%d,%d)",
1164 yylloc.first_line, yylloc.first_column,
1165 yylloc.last_line, yylloc.last_column);
1173 yychar = '#'; /* Not a token in the grammar. */
1178 AT_BISON_OPTION_POPDEFS
1180 AT_BISON_CHECK([[-o glr-regr13.c -rall glr-regr13.y]], 0, [], [])
1181 AT_COMPILE([glr-regr13])
1183 AT_PARSER_CHECK([[glr-regr13]], 0,
1184 [defstate_init <- empty string:
1186 nondefstate <- empty string:
1187 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1188 defstate_look <- empty string:
1189 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1190 defstate_shift <- nondefstate defstate_look 'a':
1192 start <- defstate_init defstate_shift 'b':
1199 ## ------------------------------------------------- ##
1200 ## Incorrect lookahead during nondeterministic GLR. ##
1201 ## ------------------------------------------------- ##
1203 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1205 AT_BISON_OPTION_PUSHDEFS
1206 AT_DATA_GRAMMAR([glr-regr14.y],
1209 - Conflicting actions (split-off parse, which copies lookahead need,
1210 which is necessarily yytrue) and nonconflicting actions (non-split-off
1211 parse) for nondefaulted state: yychar != YYEMPTY.
1212 - Merged deferred actions (lookahead need and RHS from different stack
1213 than the target state) and nonmerged deferred actions (same stack).
1214 - Defaulted state after lookahead: yychar != YYEMPTY.
1215 - Defaulted state after shift: yychar == YYEMPTY.
1216 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1217 seen the lookahead but current stack has not).
1218 - Exceeding stack capacity (stack explosion), and thus reallocating
1219 lookahead need array.
1220 Note that it does not seem possible to see the initial yychar value during
1221 nondeterministic operation since:
1222 - In order to preserve the initial yychar, only defaulted states may be
1224 - If only defaulted states are entered, there are no conflicts, so
1225 nondeterministic operation does not start. */
1227 %union { char value; }
1233 ]AT_YYERROR_DECLARE[
1235 static void print_lookahead (char const *);
1236 static char merge (union YYSTYPE, union YYSTYPE);
1240 %define parse.assert
1241 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1248 merge 'c' stack_explosion {
1250 print_lookahead ("start <- merge 'c' stack_explosion");
1254 /* When merging the 2 deferred actions, the lookahead needs are different. */
1256 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1258 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1260 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1262 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1269 print_lookahead ("nonconflict1 <- empty string");
1274 print_lookahead ("nonconflict2 <- empty string");
1278 print_lookahead ("nonconflict2 <- 'a'");
1283 print_lookahead ("conflict <- empty string");
1288 print_lookahead ("defstate_look <- empty string");
1292 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1295 print_lookahead ("defstate_shift <- empty string");
1301 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1302 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1303 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1308 if (yychar != 'd' && yychar != YYEOF)
1310 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1317 if (yychar != 'd' && yychar != YYEOF)
1319 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1326 if (yychar != 'd' && yychar != YYEOF)
1328 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1334 if (yychar != YYEMPTY)
1337 "Found lookahead where shouldn't during stack explosion.\n");
1348 static char const input[] = "abcdddd";
1349 static int toknum = 0;
1350 assert (toknum < YY_CAST (int, sizeof input));
1351 yylloc.first_line = yylloc.last_line = 1;
1352 yylloc.first_column = yylloc.last_column = toknum + 1;
1353 yylval.value = YY_CAST (char, input[toknum] + 'A' - 'a');
1354 return input[toknum++];
1358 print_lookahead (char const *reduction)
1360 printf ("%s:\n yychar=", reduction);
1361 if (yychar == YYEMPTY)
1363 else if (yychar == YYEOF)
1367 printf ("'%c', yylval='", yychar);
1368 if (yylval.value > ' ')
1369 printf ("%c", yylval.value);
1370 printf ("', yylloc=(%d,%d),(%d,%d)",
1371 yylloc.first_line, yylloc.first_column,
1372 yylloc.last_line, yylloc.last_column);
1378 merge (union YYSTYPE s1, union YYSTYPE s2)
1380 return YY_CAST (char, s1.value + s2.value);
1386 yychar = '#'; /* Not a token in the grammar. */
1391 AT_BISON_OPTION_POPDEFS
1393 AT_BISON_CHECK([[-o glr-regr14.c -rall glr-regr14.y]], 0, [],
1394 [[glr-regr14.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
1395 glr-regr14.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1397 AT_COMPILE([glr-regr14])
1399 AT_PARSER_CHECK([[glr-regr14]], 0,
1400 [conflict <- empty string:
1401 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1402 defstate_look <- empty string:
1403 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1404 nonconflict2 <- empty string:
1405 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1406 defstate_shift <- empty string:
1408 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1410 start <- merge 'c' stack_explosion:
1417 ## ------------------------------------------------- ##
1418 ## Leaked semantic values when reporting ambiguity. ##
1419 ## ------------------------------------------------- ##
1421 AT_SETUP([Leaked semantic values when reporting ambiguity])
1423 AT_BISON_OPTION_PUSHDEFS
1424 AT_DATA_GRAMMAR([glr-regr15.y],
1426 %define parse.assert
1428 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1431 # include <stdlib.h>
1432 ]AT_YYERROR_DECLARE[
1434 static int parent_rhs_before_value = 0;
1445 /* This stack must be merged into the other stacks *last* (added at the
1446 beginning of the semantic options list) so that yyparse will choose to clean
1447 it up rather than the tree for which some semantic actions have been
1448 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1449 those other trees are not cleaned up. */
1453 parent_rhs_before ambiguity {
1455 parent_rhs_before_value = 0;
1462 parent_rhs_before_value = 1;
1466 ambiguity: ambiguity1 | ambiguity2 ;
1477 int exit_status = yyparse () != 1;
1478 if (parent_rhs_before_value)
1480 fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1486 AT_BISON_OPTION_POPDEFS
1488 AT_BISON_CHECK([[-o glr-regr15.c -rall glr-regr15.y]], 0, [],
1489 [[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1490 glr-regr15.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1492 AT_COMPILE([glr-regr15])
1494 AT_PARSER_CHECK([[glr-regr15]], 0, [],
1495 [syntax is ambiguous
1501 ## ------------------------------------------------------------ ##
1502 ## Leaked lookahead after nondeterministic parse syntax error. ##
1503 ## ------------------------------------------------------------ ##
1505 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1507 AT_BISON_OPTION_PUSHDEFS
1508 AT_DATA_GRAMMAR([glr-regr16.y],
1510 %define parse.assert
1512 %destructor { lookahead_value = 0; } 'b'
1515 # include <stdlib.h>
1516 # include <assert.h>
1517 ]AT_YYERROR_DECLARE[
1519 static int lookahead_value = 0;
1525 start: alt1 'a' | alt2 'a' ;
1532 ]AT_YYLEX_DEFINE(["ab"],
1534 lookahead_value = 1])[
1539 int exit_status = yyparse () != 1;
1540 if (lookahead_value)
1542 fprintf (stderr, "Lookahead destructor not called.\n");
1548 AT_BISON_OPTION_POPDEFS
1550 AT_BISON_CHECK([[-o glr-regr16.c -rall glr-regr16.y]], 0, [],
1551 [[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1552 glr-regr16.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1554 AT_COMPILE([glr-regr16])
1556 AT_PARSER_CHECK([[glr-regr16]], 0, [],
1563 ## ------------------------------------------------- ##
1564 ## Uninitialized location when reporting ambiguity. ##
1565 ## ------------------------------------------------- ##
1567 AT_SETUP([Uninitialized location when reporting ambiguity])
1569 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1571 AT_DATA_GRAMMAR([glr-regr17.y],
1573 %define parse.assert
1577 %define parse.error verbose
1579 %union { int dummy; }
1582 ]AT_YYERROR_DECLARE[
1588 /* Tests the case of an empty RHS that has inherited the location of the
1589 previous nonterminal, which is unresolved. That location is reported as the
1590 last position of the ambiguity. */
1591 start: ambig1 empty1 | ambig2 empty2 ;
1593 /* Tests multiple levels of yyresolveLocations recursion. */
1594 ambig1: sub_ambig1 | sub_ambig2 ;
1595 ambig2: sub_ambig1 | sub_ambig2 ;
1597 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1598 has inherited the initial location. The empty RHS's location is reported as
1599 the first position in the ambiguity. */
1600 sub_ambig1: empty1 'a' 'b' ;
1601 sub_ambig2: empty2 'a' 'b' ;
1606 # include <assert.h>
1610 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1612 static char const input[] = "ab";
1613 static int toknum = 0;
1614 assert (toknum < YY_CAST (int, sizeof input));
1616 llocp->first_line = llocp->last_line = 2;
1617 llocp->first_column = toknum + 1;
1618 llocp->last_column = llocp->first_column + 1;
1619 return input[toknum++];
1624 AT_BISON_OPTION_POPDEFS
1626 AT_BISON_CHECK([[-o glr-regr17.c -rall glr-regr17.y]], 0, [],
1627 [[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1628 glr-regr17.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1630 AT_COMPILE([glr-regr17])
1632 AT_PARSER_CHECK([[glr-regr17]], 1, [],
1633 [1.1-2.2: syntax is ambiguous
1639 ## ------------------------------------------------------------- ##
1640 ## Missed %merge type warnings when LHS type is declared later. ##
1641 ## ------------------------------------------------------------- ##
1643 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1645 AT_BISON_OPTION_PUSHDEFS
1646 AT_DATA_GRAMMAR([glr-regr18.y],
1647 [[%define parse.assert
1652 ]AT_YYERROR_DECLARE[
1663 sym1: sym2 %merge<merge> { $$ = $1; } ;
1664 sym2: sym3 %merge<merge> { $$ = $1; } ;
1665 sym3: %merge<merge> { $$ = 0; } ;
1676 AT_BISON_OPTION_POPDEFS
1678 AT_BISON_CHECK([[-o glr-regr18.c -rall glr-regr18.y]], 1, [],
1679 [[glr-regr18.y:28.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
1680 glr-regr18.y:27.18-24: note: previous declaration
1681 glr-regr18.y:29.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
1682 glr-regr18.y:28.18-24: note: previous declaration
1688 ## ------------------- ##
1689 ## Ambiguity reports. ##
1690 ## ------------------- ##
1692 AT_SETUP([Ambiguity reports])
1694 AT_BISON_OPTION_PUSHDEFS([%debug])
1695 AT_DATA_GRAMMAR([input.y],
1699 ]AT_YYERROR_DECLARE[
1703 %define parse.assert
1716 ]AT_YYLEX_DEFINE(["abc"])[
1720 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1721 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1722 input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1726 AT_PARSER_CHECK([[input --debug]], 1, [],
1730 Next token is token 'a' ()
1731 Shifting token 'a' ()
1734 Next token is token 'b' ()
1735 Shifting token 'b' ()
1737 Reducing stack 0 by rule 3 (line 27):
1742 Next token is token 'c' ()
1743 Shifting token 'c' ()
1745 Reducing stack 0 by rule 4 (line 28):
1749 Now at end of input.
1750 Stack 0 Entering state 7
1751 Now at end of input.
1752 Splitting off stack 1 from 0.
1753 Reduced stack 1 by rule 2 (line 24); action deferred. Now in state 2.
1754 Stack 1 Entering state 2
1755 Now at end of input.
1756 Reduced stack 0 by rule 1 (line 24); action deferred. Now in state 2.
1757 Merging stack 0 into stack 1.
1758 Stack 1 Entering state 2
1759 Now at end of input.
1760 Removing dead stacks.
1761 Rename stack 1 -> 0.
1762 On stack 0, shifting token "end of file" ()
1763 Stack 0 now in state #5
1766 start -> <Rule 1, tokens 1 .. 3>
1773 start -> <Rule 2, tokens 1 .. 3>
1780 Cleanup: popping token "end of file" ()
1781 Cleanup: popping unresolved nterm start ()
1782 Cleanup: popping nterm d ()
1783 Cleanup: popping token 'c' ()
1784 Cleanup: popping nterm b ()
1785 Cleanup: popping token 'a' ()
1788 AT_BISON_OPTION_POPDEFS
1792 ## ----------------------------------------------------------------- ##
1795 ## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ##
1796 ## http://lists.gnu.org/archive/html/bug-bison/2018-05/msg00033.html ##
1797 ## ----------------------------------------------------------------- ##
1799 AT_SETUP([Predicates])
1801 AT_BISON_OPTION_PUSHDEFS
1802 AT_DATA_GRAMMAR([input.y],
1803 [[%define parse.assert
1805 %define parse.error verbose
1810 #include <stdbool.h>
1811 bool new_syntax = false;
1812 const char *input = YY_NULLPTR;
1813 ]AT_YYERROR_DECLARE[
1818 %? {new_syntax} 'w' id new_args { printf("new"); }
1819 | %?{!new_syntax} 'w' id old_args { printf("old"); }
1834 main (int argc, const char* argv[])
1836 assert (argc == 2); (void) argc;
1837 // First char decides whether new, or old syntax.
1839 new_syntax = argv[1][0] == 'N';
1840 input = argv[1] + 1;
1845 AT_BISON_CHECK([[-o input.c input.y]])
1847 AT_PARSER_CHECK([[input Nwin]], [0], [new])
1848 AT_PARSER_CHECK([[input Owin]], [1], [], [[syntax error, unexpected 'n', expecting 'o'
1850 AT_PARSER_CHECK([[input Owio]], [0], [old])
1851 AT_PARSER_CHECK([[input Nwio]], [1], [], [[syntax error, unexpected 'o', expecting 'n'
1854 AT_BISON_OPTION_POPDEFS