1 # Checking GLR Parsing: Regression Tests -*- Autotest -*-
3 # Copyright (C) 2002-2003, 2005-2007, 2009-2014 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[])
88 AT_BISON_OPTION_POPDEFS
90 AT_BISON_CHECK([[-o glr-regr1.c glr-regr1.y]], 0, [],
91 [[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
93 AT_COMPILE([glr-regr1])
94 AT_PARSER_CHECK([[./glr-regr1 BPBPB]], 0,
108 ## -------------------------------------------------------------- ##
109 ## Improper handling of embedded actions and $-N in GLR parsers. ##
110 ## -------------------------------------------------------------- ##
112 AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers])
114 AT_BISON_OPTION_PUSHDEFS
115 AT_DATA_GRAMMAR([glr-regr2a.y],
116 [[/* Regression Test: Improper handling of embedded actions and $-N */
117 /* Reported by S. Eken */
120 #define YYSTYPE char *
137 { printf ("Variable: '%s'\n", $2); }
140 | 's' var_list 't' 'e'
141 { printf ("Varlist: '%s'\n", $2); free ($2); }
142 | 's' var 't' var_printer 'x'
156 char *s = (char *) realloc ($1, strlen ($1) + 1 + strlen ($3) + 1);
165 { printf ("Variable: '%s'\n", $-1); }
176 assert (!feof (stdin));
177 switch (fscanf (input, " %1[a-z,]", buf))
186 if (fscanf (input, "%49s", buf) != 1)
188 assert (strlen (buf) < sizeof buf - 1);
189 s = (char *) malloc (strlen (buf) + 1);
196 main (int argc, char **argv)
200 if (argc == 2 && !(input = fopen (argv[1], "r")))
203 if (argc == 2 && fclose (input))
208 AT_BISON_OPTION_POPDEFS
210 AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [],
211 [[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
213 AT_COMPILE([glr-regr2a])
215 AT_DATA([input1.txt],
216 [[s VARIABLE_1 t v x q
218 AT_PARSER_CHECK([[./glr-regr2a input1.txt]], 0,
219 [[Variable: 'VARIABLE_1'
222 AT_DATA([input2.txt],
223 [[s VARIABLE_1 , ANOTHER_VARIABLE_2 t e
225 AT_PARSER_CHECK([[./glr-regr2a input2.txt]],
227 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
230 AT_DATA([input3.txt],
233 AT_PARSER_CHECK([[./glr-regr2a input3.txt]], 0,
234 [[Variable: 'VARIABLE_3'
240 ## --------------------------------------------- ##
241 ## Improper merging of GLR delayed action sets. ##
242 ## --------------------------------------------- ##
244 AT_SETUP([Improper merging of GLR delayed action sets])
246 AT_BISON_OPTION_PUSHDEFS
247 AT_DATA_GRAMMAR([glr-regr3.y],
248 [[/* Regression Test: Improper merging of GLR delayed action sets. */
249 /* Reported by M. Rosien */
257 static int MergeRule (int x0, int x1);
261 #define RULE(x) (1 << (x))
268 %token P1 P2 T1 T2 T3 T4 O1 O2
272 S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
275 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
278 NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
279 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
282 NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
283 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
286 NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
287 | NT2 { $$ = RULE(8); } %merge<MergeRule>
288 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
291 NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
294 NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
295 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
301 MergeRule (int x0, int x1)
307 FILE *input = YY_NULLPTR;
309 int P[] = { P1, P2 };
310 int O[] = { O1, O2 };
311 int T[] = { T1, T2, T3, T4 };
316 assert (!feof (stdin));
317 if (fscanf (input, "%2s", inp) == EOF)
321 case 'p': return P[inp[1] - '1'];
322 case 't': return T[inp[1] - '1'];
323 case 'o': return O[inp[1] - '1'];
329 main (int argc, char* argv[])
333 if (argc == 2 && !(input = fopen (argv[1], "r")))
336 if (argc == 2 && fclose (input))
341 AT_BISON_OPTION_POPDEFS
343 AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
344 [[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
345 glr-regr3.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
347 AT_COMPILE([glr-regr3])
350 [[p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2
352 AT_PARSER_CHECK([[./glr-regr3 input.txt]],
360 ## ---------------------------------------------------------------------- ##
361 ## Duplicate representation of merged trees. See ##
362 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
363 ## ---------------------------------------------------------------------- ##
365 AT_SETUP([Duplicate representation of merged trees])
367 AT_BISON_OPTION_PUSHDEFS
368 AT_DATA_GRAMMAR([glr-regr4.y],
370 %union { char *ptr; }
371 %type <ptr> S A A1 A2 B
378 static char *merge (YYSTYPE, YYSTYPE);
379 static char *make_value (char const *, char const *);
382 static char *ptrs[100];
383 static char **ptrs_next = ptrs;
388 tree: S { printf ("%s\n", $1); } ;
391 A %merge<merge> { $$ = make_value ("S", $1); }
392 | B %merge<merge> { $$ = make_value ("S", $1); }
396 A1 %merge<merge> { $$ = make_value ("A", $1); }
397 | A2 %merge<merge> { $$ = make_value ("A", $1); }
400 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
401 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
402 B: 'a' { $$ = make_value ("B", "'a'"); } ;
406 ]AT_YYLEX_DEFINE(["a"])[
411 int status = yyparse ();
412 while (ptrs_next != ptrs)
418 make_value (char const *parent, char const *child)
420 char const format[] = "%s <- %s";
421 char *value = *ptrs_next++ =
422 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
423 sprintf (value, format, parent, child);
428 merge (YYSTYPE s1, YYSTYPE s2)
430 char const format[] = "merge{ %s and %s }";
431 char *value = *ptrs_next++ =
432 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
433 sprintf (value, format, s1.ptr, s2.ptr);
437 AT_BISON_OPTION_POPDEFS
439 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
440 [[glr-regr4.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
442 AT_COMPILE([glr-regr4])
444 AT_PARSER_CHECK([[./glr-regr4]], 0,
445 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
451 ## ------------------------------------------------------------------------- ##
452 ## User destructor for unresolved GLR semantic value. See ##
453 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
454 ## ------------------------------------------------------------------------- ##
456 AT_SETUP([User destructor for unresolved GLR semantic value])
458 AT_BISON_OPTION_PUSHDEFS
459 AT_DATA_GRAMMAR([glr-regr5.y],
466 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
470 %union { int value; }
474 if ($$ != MAGIC_VALUE)
476 fprintf (stderr, "Bad destructor call.\n");
484 'a' { $$ = MAGIC_VALUE; }
485 | 'a' { $$ = MAGIC_VALUE; }
490 ]AT_YYLEX_DEFINE(["a"])[
493 AT_BISON_OPTION_POPDEFS
495 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
496 [[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
498 AT_COMPILE([glr-regr5])
500 AT_PARSER_CHECK([[./glr-regr5]], 1, [],
507 ## ------------------------------------------------------------------------- ##
508 ## User destructor after an error during a split parse. See ##
509 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
510 ## ------------------------------------------------------------------------- ##
512 AT_SETUP([User destructor after an error during a split parse])
514 AT_BISON_OPTION_PUSHDEFS
515 AT_DATA_GRAMMAR([glr-regr6.y],
525 %union { int value; }
529 printf ("Destructor called.\n");
538 ]AT_YYLEX_DEFINE(["a"])[
541 AT_BISON_OPTION_POPDEFS
543 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
544 [[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
546 AT_COMPILE([glr-regr6])
548 AT_PARSER_CHECK([[./glr-regr6]], 1,
557 ## ------------------------------------------------------------------------- ##
558 ## Duplicated user destructor for lookahead. See ##
559 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
560 ## ------------------------------------------------------------------------- ##
562 AT_SETUP([Duplicated user destructor for lookahead])
564 AT_BISON_OPTION_PUSHDEFS
565 AT_DATA_GRAMMAR([glr-regr7.y],
572 #define YYSTACKEXPANDABLE 0
573 typedef struct count_node {
575 struct count_node *prev;
577 static count_node *tail;
581 %union { count_node *node; }
586 fprintf (stderr, "Destructor called on same value twice.\n");
604 yylval.node = (count_node*) malloc (sizeof *yylval.node);
607 fprintf (stderr, "Test inconclusive.\n");
610 yylval.node->count = 0;
611 yylval.node->prev = tail;
620 int status = yyparse ();
623 count_node *prev = tail->prev;
630 AT_BISON_OPTION_POPDEFS
632 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
633 [[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
635 AT_COMPILE([glr-regr7])
637 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
644 ## ------------------------------------------------------------------------- ##
645 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
646 ## report by Claudia Hermann. ##
647 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
648 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
649 ## ------------------------------------------------------------------------- ##
651 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
653 AT_BISON_OPTION_PUSHDEFS
654 AT_DATA_GRAMMAR([glr-regr8.y],
672 PortClause : T_PORT InterfaceDeclaration T_PORT
673 { printf("%d/%d - %d/%d - %d/%d\n",
674 @1.first_column, @1.last_column,
675 @2.first_column, @2.last_column,
676 @3.first_column, @3.last_column); }
679 InterfaceDeclaration : OptConstantWord %dprec 1
680 | OptSignalWord %dprec 2
683 OptConstantWord : /* empty */
687 OptSignalWord : /* empty */
688 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
705 yylloc.first_column = 1;
706 yylloc.last_column = 9;
709 yylloc.first_column = 13;
710 yylloc.last_column = 17;
719 AT_BISON_OPTION_POPDEFS
721 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
722 [[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
724 AT_COMPILE([glr-regr8])
726 AT_PARSER_CHECK([[./glr-regr8]], 0,
735 ## ------------------------------------------------------------------------- ##
736 ## No users destructors if stack 0 deleted. See ##
737 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
738 ## ------------------------------------------------------------------------- ##
740 AT_SETUP([No users destructors if stack 0 deleted])
742 AT_BISON_OPTION_PUSHDEFS
743 AT_DATA_GRAMMAR([glr-regr9.y],
750 # define YYSTACKEXPANDABLE 0
751 static int tokens = 0;
752 static int destructors = 0;
757 %union { int dummy; }
767 ambig0 'a' { destructors += 2; USE ($2); }
768 | ambig1 start { destructors += 1; }
769 | ambig2 start { destructors += 1; }
790 exit_status = yyparse ();
791 if (tokens != destructors)
793 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
799 AT_BISON_OPTION_POPDEFS
801 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
802 [[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
804 AT_COMPILE([glr-regr9])
806 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
813 ## ------------------------------------------------------ ##
814 ## Corrupted semantic options if user action cuts parse. ##
815 ## ------------------------------------------------------ ##
817 AT_SETUP([Corrupted semantic options if user action cuts parse])
819 AT_BISON_OPTION_PUSHDEFS
820 AT_DATA_GRAMMAR([glr-regr10.y],
827 #define GARBAGE_SIZE 50
828 static char garbage[GARBAGE_SIZE];
832 %union { char *ptr; }
838 %dprec 2 { $$ = garbage; YYACCEPT; }
839 | %dprec 1 { $$ = garbage; YYACCEPT; }
850 for (i = 0; i < GARBAGE_SIZE; i+=1)
855 AT_BISON_OPTION_POPDEFS
857 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
858 [[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
860 AT_COMPILE([glr-regr10])
862 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
867 ## --------------------------------------------------- ##
868 ## Undesirable destructors if user action cuts parse. ##
869 ## --------------------------------------------------- ##
871 AT_SETUP([Undesirable destructors if user action cuts parse])
873 AT_BISON_OPTION_PUSHDEFS
874 AT_DATA_GRAMMAR([glr-regr11.y],
880 static int destructors = 0;
885 %union { int dummy; }
887 %destructor { destructors += 1; } 'a'
892 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
893 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
899 ]AT_YYLEX_DEFINE(["a"])[
904 int exit_status = yyparse ();
905 if (destructors != 1)
907 fprintf (stderr, "Destructor calls: %d\n", destructors);
913 AT_BISON_OPTION_POPDEFS
915 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
916 [[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
918 AT_COMPILE([glr-regr11])
920 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
925 ## -------------------------------------------------- ##
926 ## Leaked semantic values if user action cuts parse. ##
927 ## -------------------------------------------------- ##
929 AT_SETUP([Leaked semantic values if user action cuts parse])
931 AT_BISON_OPTION_PUSHDEFS
932 AT_DATA_GRAMMAR([glr-regr12.y],
935 %union { int dummy; }
936 %token PARENT_RHS_AFTER
937 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
938 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
939 %destructor { merged_value = 0; } merged
940 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
945 static int merge (YYSTYPE, YYSTYPE);
948 static int parent_rhs_before_value = 0;
949 static int merged_value = 0;
950 static int parent_rhs_after_value = 0;
964 parent_rhs_after_value = 0;
969 parent_rhs_before merged PARENT_RHS_AFTER {
971 parent_rhs_before_value = 0;
973 parent_rhs_after_value = 0;
980 parent_rhs_before_value = 1;
989 | cut %merge<merge> {
1000 merge (YYSTYPE s1, YYSTYPE s2)
1003 char dummy = s1.dummy + s2.dummy;
1008 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1009 [if (res == PARENT_RHS_AFTER)
1010 parent_rhs_after_value = 1;])[
1015 int exit_status = yyparse ();
1016 if (parent_rhs_before_value)
1018 fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1023 fprintf (stderr, "'merged' destructor not called.\n");
1026 if (parent_rhs_after_value)
1028 fprintf (stderr, "'PARENT_RHS_AFTER' destructor not called.\n");
1034 AT_BISON_OPTION_POPDEFS
1036 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1037 [[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1038 glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1040 AT_COMPILE([glr-regr12])
1042 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1047 ## ------------------------------------------------------------------------- ##
1048 ## Incorrect lookahead during deterministic GLR. See ##
1049 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1050 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1051 ## ------------------------------------------------------------------------- ##
1053 AT_SETUP([Incorrect lookahead during deterministic GLR])
1055 AT_BISON_OPTION_PUSHDEFS
1056 AT_DATA_GRAMMAR([glr-regr13.y],
1059 - Defaulted state with initial yychar: yychar == YYEMPTY.
1060 - Nondefaulted state: yychar != YYEMPTY.
1061 - Defaulted state after lookahead: yychar != YYEMPTY.
1062 - Defaulted state after shift: yychar == YYEMPTY.
1063 - User action changing the lookahead. */
1068 ]AT_YYERROR_DECLARE[
1070 static void print_lookahead (char const *);
1074 %union { char value; }
1075 %type <value> 'a' 'b'
1082 defstate_init defstate_shift 'b' change_lookahead 'a' {
1084 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1089 print_lookahead ("defstate_init <- empty string");
1093 nondefstate defstate_look 'a' {
1095 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1100 print_lookahead ("defstate_look <- empty string");
1105 print_lookahead ("nondefstate <- empty string");
1109 print_lookahead ("nondefstate <- 'b'");
1121 ]AT_YYLEX_DEFINE(["ab"],
1122 [yylval.value = res + 'A' - 'a'])[
1125 print_lookahead (char const *reduction)
1127 printf ("%s:\n yychar=", reduction);
1128 if (yychar == YYEMPTY)
1130 else if (yychar == YYEOF)
1134 printf ("'%c', yylval='", yychar);
1135 if (yylval.value > ' ')
1136 printf ("%c", yylval.value);
1137 printf ("', yylloc=(%d,%d),(%d,%d)",
1138 yylloc.first_line, yylloc.first_column,
1139 yylloc.last_line, yylloc.last_column);
1147 yychar = '#'; /* Not a token in the grammar. */
1152 AT_BISON_OPTION_POPDEFS
1154 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1155 AT_COMPILE([glr-regr13])
1157 AT_PARSER_CHECK([[./glr-regr13]], 0,
1158 [defstate_init <- empty string:
1160 nondefstate <- empty string:
1161 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1162 defstate_look <- empty string:
1163 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1164 defstate_shift <- nondefstate defstate_look 'a':
1166 start <- defstate_init defstate_shift 'b':
1173 ## ------------------------------------------------- ##
1174 ## Incorrect lookahead during nondeterministic GLR. ##
1175 ## ------------------------------------------------- ##
1177 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1179 AT_BISON_OPTION_PUSHDEFS
1180 AT_DATA_GRAMMAR([glr-regr14.y],
1183 - Conflicting actions (split-off parse, which copies lookahead need,
1184 which is necessarily yytrue) and nonconflicting actions (non-split-off
1185 parse) for nondefaulted state: yychar != YYEMPTY.
1186 - Merged deferred actions (lookahead need and RHS from different stack
1187 than the target state) and nonmerged deferred actions (same stack).
1188 - Defaulted state after lookahead: yychar != YYEMPTY.
1189 - Defaulted state after shift: yychar == YYEMPTY.
1190 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1191 seen the lookahead but current stack has not).
1192 - Exceeding stack capacity (stack explosion), and thus reallocating
1193 lookahead need array.
1194 Note that it does not seem possible to see the initial yychar value during
1195 nondeterministic operation since:
1196 - In order to preserve the initial yychar, only defaulted states may be
1198 - If only defaulted states are entered, there are no conflicts, so
1199 nondeterministic operation does not start. */
1201 %union { char value; }
1207 ]AT_YYERROR_DECLARE[
1209 static void print_lookahead (char const *);
1210 static char merge (union YYSTYPE, union YYSTYPE);
1214 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1221 merge 'c' stack_explosion {
1223 print_lookahead ("start <- merge 'c' stack_explosion");
1227 /* When merging the 2 deferred actions, the lookahead needs are different. */
1229 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1231 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1233 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1235 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1242 print_lookahead ("nonconflict1 <- empty string");
1247 print_lookahead ("nonconflict2 <- empty string");
1251 print_lookahead ("nonconflict2 <- 'a'");
1256 print_lookahead ("conflict <- empty string");
1261 print_lookahead ("defstate_look <- empty string");
1265 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1268 print_lookahead ("defstate_shift <- empty string");
1274 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1275 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1276 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1281 if (yychar != 'd' && yychar != YYEOF)
1283 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1290 if (yychar != 'd' && yychar != YYEOF)
1292 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1299 if (yychar != 'd' && yychar != YYEOF)
1301 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1307 if (yychar != YYEMPTY)
1310 "Found lookahead where shouldn't during stack explosion.\n");
1321 static char const input[] = "abcdddd";
1322 static size_t toknum;
1323 assert (toknum < sizeof input);
1324 yylloc.first_line = yylloc.last_line = 1;
1325 yylloc.first_column = yylloc.last_column = toknum + 1;
1326 yylval.value = input[toknum] + 'A' - 'a';
1327 return input[toknum++];
1331 print_lookahead (char const *reduction)
1333 printf ("%s:\n yychar=", reduction);
1334 if (yychar == YYEMPTY)
1336 else if (yychar == YYEOF)
1340 printf ("'%c', yylval='", yychar);
1341 if (yylval.value > ' ')
1342 printf ("%c", yylval.value);
1343 printf ("', yylloc=(%d,%d),(%d,%d)",
1344 yylloc.first_line, yylloc.first_column,
1345 yylloc.last_line, yylloc.last_column);
1351 merge (union YYSTYPE s1, union YYSTYPE s2)
1353 char dummy = s1.value + s2.value;
1360 yychar = '#'; /* Not a token in the grammar. */
1365 AT_BISON_OPTION_POPDEFS
1367 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1368 [[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1370 AT_COMPILE([glr-regr14])
1372 AT_PARSER_CHECK([[./glr-regr14]], 0,
1373 [conflict <- empty string:
1374 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1375 defstate_look <- empty string:
1376 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1377 nonconflict2 <- empty string:
1378 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1379 defstate_shift <- empty string:
1381 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1383 start <- merge 'c' stack_explosion:
1390 ## ------------------------------------------------- ##
1391 ## Leaked semantic values when reporting ambiguity. ##
1392 ## ------------------------------------------------- ##
1394 AT_SETUP([Leaked semantic values when reporting ambiguity])
1396 AT_BISON_OPTION_PUSHDEFS
1397 AT_DATA_GRAMMAR([glr-regr15.y],
1400 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1403 # include <stdlib.h>
1404 ]AT_YYERROR_DECLARE[
1406 static int parent_rhs_before_value = 0;
1417 /* This stack must be merged into the other stacks *last* (added at the
1418 beginning of the semantic options list) so that yyparse will choose to clean
1419 it up rather than the tree for which some semantic actions have been
1420 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1421 those other trees are not cleaned up. */
1425 parent_rhs_before ambiguity {
1427 parent_rhs_before_value = 0;
1434 parent_rhs_before_value = 1;
1438 ambiguity: ambiguity1 | ambiguity2 ;
1449 int exit_status = yyparse () != 1;
1450 if (parent_rhs_before_value)
1452 fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1458 AT_BISON_OPTION_POPDEFS
1460 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1461 [[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1463 AT_COMPILE([glr-regr15])
1465 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1466 [syntax is ambiguous
1472 ## ------------------------------------------------------------ ##
1473 ## Leaked lookahead after nondeterministic parse syntax error. ##
1474 ## ------------------------------------------------------------ ##
1476 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1478 AT_BISON_OPTION_PUSHDEFS
1479 AT_DATA_GRAMMAR([glr-regr16.y],
1482 %destructor { lookahead_value = 0; } 'b'
1485 # include <stdlib.h>
1486 # include <assert.h>
1487 ]AT_YYERROR_DECLARE[
1489 static int lookahead_value = 0;
1495 start: alt1 'a' | alt2 'a' ;
1502 ]AT_YYLEX_DEFINE(["ab"],
1504 lookahead_value = 1])[
1509 int exit_status = yyparse () != 1;
1510 if (lookahead_value)
1512 fprintf (stderr, "Lookahead destructor not called.\n");
1518 AT_BISON_OPTION_POPDEFS
1520 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1521 [[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1523 AT_COMPILE([glr-regr16])
1525 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1532 ## ------------------------------------------------- ##
1533 ## Uninitialized location when reporting ambiguity. ##
1534 ## ------------------------------------------------- ##
1536 AT_SETUP([Uninitialized location when reporting ambiguity])
1538 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1540 AT_DATA_GRAMMAR([glr-regr17.y],
1547 %union { int dummy; }
1550 ]AT_YYERROR_DECLARE[
1556 /* Tests the case of an empty RHS that has inherited the location of the
1557 previous nonterminal, which is unresolved. That location is reported as the
1558 last position of the ambiguity. */
1559 start: ambig1 empty1 | ambig2 empty2 ;
1561 /* Tests multiple levels of yyresolveLocations recursion. */
1562 ambig1: sub_ambig1 | sub_ambig2 ;
1563 ambig2: sub_ambig1 | sub_ambig2 ;
1565 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1566 has inherited the initial location. The empty RHS's location is reported as
1567 the first position in the ambiguity. */
1568 sub_ambig1: empty1 'a' 'b' ;
1569 sub_ambig2: empty2 'a' 'b' ;
1574 # include <assert.h>
1578 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1580 static char const input[] = "ab";
1581 static size_t toknum;
1582 assert (toknum < sizeof input);
1584 llocp->first_line = llocp->last_line = 2;
1585 llocp->first_column = toknum + 1;
1586 llocp->last_column = llocp->first_column + 1;
1587 return input[toknum++];
1592 AT_BISON_OPTION_POPDEFS
1594 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1595 [[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1597 AT_COMPILE([glr-regr17])
1599 AT_PARSER_CHECK([[./glr-regr17]], 1, [],
1600 [1.1-2.2: syntax is ambiguous
1606 ## ------------------------------------------------------------- ##
1607 ## Missed %merge type warnings when LHS type is declared later. ##
1608 ## ------------------------------------------------------------- ##
1610 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1612 AT_BISON_OPTION_PUSHDEFS
1613 AT_DATA_GRAMMAR([glr-regr18.y],
1618 ]AT_YYERROR_DECLARE[
1630 sym1: sym2 %merge<merge> { $$ = $1; } ;
1631 sym2: sym3 %merge<merge> { $$ = $1; } ;
1632 sym3: %merge<merge> { $$ = 0; } ;
1643 AT_BISON_OPTION_POPDEFS
1645 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1646 [[glr-regr18.y:28.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
1647 glr-regr18.y:27.18-24: previous declaration
1648 glr-regr18.y:29.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
1649 glr-regr18.y:28.18-24: previous declaration
1655 ## ------------------- ##
1656 ## Ambiguity reports. ##
1657 ## ------------------- ##
1659 AT_SETUP([Ambiguity reports])
1661 AT_BISON_OPTION_PUSHDEFS([%debug])
1662 AT_DATA_GRAMMAR([input.y],
1667 ]AT_YYERROR_DECLARE[
1683 ]AT_YYLEX_DEFINE(["abc"])[
1686 AT_BISON_OPTION_POPDEFS
1688 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1689 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1693 AT_PARSER_CHECK([[./input --debug]], 1, [],
1696 Reading a token: Next token is token 'a' ()
1697 Shifting token 'a' ()
1699 Reading a token: Next token is token 'b' ()
1700 Shifting token 'b' ()
1702 Reducing stack 0 by rule 3 (line 27):
1706 Reading a token: Next token is token 'c' ()
1707 Shifting token 'c' ()
1709 Reducing stack 0 by rule 4 (line 28):
1712 Reading a token: Now at end of input.
1713 Stack 0 Entering state 7
1714 Now at end of input.
1715 Splitting off stack 1 from 0.
1716 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1717 Stack 1 Entering state 2
1718 Now at end of input.
1719 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1720 Merging stack 0 into stack 1.
1721 Stack 1 Entering state 2
1722 Now at end of input.
1723 Removing dead stacks.
1724 Rename stack 1 -> 0.
1725 On stack 0, shifting token $end ()
1726 Stack 0 now in state #5
1729 start -> <Rule 1, tokens 1 .. 3>
1736 start -> <Rule 2, tokens 1 .. 3>
1743 Cleanup: popping token $end ()
1744 Cleanup: popping unresolved nterm start ()
1745 Cleanup: popping nterm d ()
1746 Cleanup: popping token 'c' ()
1747 Cleanup: popping nterm b ()
1748 Cleanup: popping token 'a' ()
1754 ## ----------------------------------------------------------------- ##
1757 ## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ##
1758 ## ----------------------------------------------------------------- ##
1760 AT_SETUP([Predicates])
1762 # FIXME: We need genuine test cases with uses of %?.
1764 AT_DATA_GRAMMAR([input.y],
1768 // Exercise "%?{...}" and "%? {...}".
1770 %? {new_syntax} "widget" id new_args { $$ = f($3, $4); }
1771 | %?{!new_syntax} "widget" id old_args { $$ = f($3, $4); }
1779 AT_BISON_CHECK([[input.y]])