1 # Checking GLR Parsing: Regression Tests -*- Autotest -*-
3 # Copyright (C) 2002-2003, 2005-2007, 2009-2012 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 = NULL;
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: conflicts: 1 shift/reduce
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)
199 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
203 AT_BISON_OPTION_POPDEFS
205 AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [],
206 [glr-regr2a.y: conflicts: 2 shift/reduce
208 AT_COMPILE([glr-regr2a])
210 AT_DATA([input1.txt],
211 [[s VARIABLE_1 t v x q
213 AT_PARSER_CHECK([[./glr-regr2a input1.txt]], 0,
214 [[Variable: 'VARIABLE_1'
217 AT_DATA([input2.txt],
218 [[s VARIABLE_1 , ANOTHER_VARIABLE_2 t e
220 AT_PARSER_CHECK([[./glr-regr2a input2.txt]],
222 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
225 AT_DATA([input3.txt],
228 AT_PARSER_CHECK([[./glr-regr2a input3.txt]], 0,
229 [[Variable: 'VARIABLE_3'
235 ## ------------------------------------------------------------ ##
236 ## Improper merging of GLR delayed action sets ##
237 ## ------------------------------------------------------------ ##
239 AT_SETUP([Improper merging of GLR delayed action sets])
241 AT_BISON_OPTION_PUSHDEFS
242 AT_DATA_GRAMMAR([glr-regr3.y],
243 [[/* Regression Test: Improper merging of GLR delayed action sets. */
244 /* Reported by M. Rosien */
252 static int MergeRule (int x0, int x1);
256 #define RULE(x) (1 << (x))
263 %token P1 P2 T1 T2 T3 T4 O1 O2
267 S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
270 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
273 NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
274 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
277 NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
278 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
281 NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
282 | NT2 { $$ = RULE(8); } %merge<MergeRule>
283 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
286 NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
289 NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
290 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
296 MergeRule (int x0, int x1)
302 FILE *input = YY_NULL;
304 int P[] = { P1, P2 };
305 int O[] = { O1, O2 };
306 int T[] = { T1, T2, T3, T4 };
311 assert (!feof (stdin));
312 if (fscanf (input, "%2s", inp) == EOF)
316 case 'p': return P[inp[1] - '1'];
317 case 't': return T[inp[1] - '1'];
318 case 'o': return O[inp[1] - '1'];
324 main(int argc, char* argv[])
327 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
331 AT_BISON_OPTION_POPDEFS
333 AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
334 [glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce
336 AT_COMPILE([glr-regr3])
339 [[p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2
341 AT_PARSER_CHECK([[./glr-regr3 input.txt]],
349 ## ------------------------------------------------------------------------- ##
350 ## Duplicate representation of merged trees. See ##
351 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
352 ## ------------------------------------------------------------------------- ##
354 AT_SETUP([Duplicate representation of merged trees])
356 AT_BISON_OPTION_PUSHDEFS
357 AT_DATA_GRAMMAR([glr-regr4.y],
359 %union { char *ptr; }
360 %type <ptr> S A A1 A2 B
367 static char *merge (YYSTYPE, YYSTYPE);
368 static char *make_value (char const *, char const *);
371 static char *ptrs[100];
372 static char **ptrs_next = ptrs;
377 tree: S { printf ("%s\n", $1); } ;
380 A %merge<merge> { $$ = make_value ("S", $1); }
381 | B %merge<merge> { $$ = make_value ("S", $1); }
385 A1 %merge<merge> { $$ = make_value ("A", $1); }
386 | A2 %merge<merge> { $$ = make_value ("A", $1); }
389 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
390 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
391 B: 'a' { $$ = make_value ("B", "'a'"); } ;
395 ]AT_YYLEX_DEFINE(["a"])[
400 int status = yyparse ();
401 while (ptrs_next != ptrs)
407 make_value (char const *parent, char const *child)
409 char const format[] = "%s <- %s";
410 char *value = *ptrs_next++ =
411 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
412 sprintf (value, format, parent, child);
417 merge (YYSTYPE s1, YYSTYPE s2)
419 char const format[] = "merge{ %s and %s }";
420 char *value = *ptrs_next++ =
421 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
422 sprintf (value, format, s1.ptr, s2.ptr);
426 AT_BISON_OPTION_POPDEFS
428 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
429 [glr-regr4.y: conflicts: 1 reduce/reduce
431 AT_COMPILE([glr-regr4])
433 AT_PARSER_CHECK([[./glr-regr4]], 0,
434 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
440 ## -------------------------------------------------------------------------- ##
441 ## User destructor for unresolved GLR semantic value. See ##
442 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
443 ## -------------------------------------------------------------------------- ##
445 AT_SETUP([User destructor for unresolved GLR semantic value])
447 AT_BISON_OPTION_PUSHDEFS
448 AT_DATA_GRAMMAR([glr-regr5.y],
455 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
459 %union { int value; }
463 if ($$ != MAGIC_VALUE)
465 fprintf (stderr, "Bad destructor call.\n");
473 'a' { $$ = MAGIC_VALUE; }
474 | 'a' { $$ = MAGIC_VALUE; }
478 ]AT_YYLEX_DEFINE(["a"])[
483 return yyparse () != 1;
486 AT_BISON_OPTION_POPDEFS
488 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
489 [glr-regr5.y: conflicts: 1 reduce/reduce
491 AT_COMPILE([glr-regr5])
493 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
500 ## -------------------------------------------------------------------------- ##
501 ## User destructor after an error during a split parse. See ##
502 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
503 ## -------------------------------------------------------------------------- ##
505 AT_SETUP([User destructor after an error during a split parse])
507 AT_BISON_OPTION_PUSHDEFS
508 AT_DATA_GRAMMAR([glr-regr6.y],
518 %union { int value; }
522 printf ("Destructor called.\n");
531 ]AT_YYLEX_DEFINE(["a"])[
535 return yyparse () != 1;
538 AT_BISON_OPTION_POPDEFS
540 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
541 [glr-regr6.y: conflicts: 1 reduce/reduce
543 AT_COMPILE([glr-regr6])
545 AT_PARSER_CHECK([[./glr-regr6]], 0,
554 ## ------------------------------------------------------------------------- ##
555 ## Duplicated user destructor for lookahead. See ##
556 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
557 ## ------------------------------------------------------------------------- ##
559 AT_SETUP([Duplicated user destructor for lookahead])
561 AT_BISON_OPTION_PUSHDEFS
562 AT_DATA_GRAMMAR([glr-regr7.y],
569 #define YYSTACKEXPANDABLE 0
570 typedef struct count_node {
572 struct count_node *prev;
574 static count_node *tail;
578 %union { count_node *node; }
583 fprintf (stderr, "Destructor called on same value twice.\n");
601 yylval.node = (count_node*) malloc (sizeof *yylval.node);
604 fprintf (stderr, "Test inconclusive.\n");
607 yylval.node->count = 0;
608 yylval.node->prev = tail;
617 int status = yyparse ();
620 count_node *prev = tail->prev;
627 AT_BISON_OPTION_POPDEFS
629 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
630 [glr-regr7.y: conflicts: 2 reduce/reduce
632 AT_COMPILE([glr-regr7])
634 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
641 ## ------------------------------------------------------------------------- ##
642 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
643 ## report by Claudia Hermann. ##
644 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
645 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
646 ## ------------------------------------------------------------------------- ##
648 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
650 AT_BISON_OPTION_PUSHDEFS
651 AT_DATA_GRAMMAR([glr-regr8.y],
669 PortClause : T_PORT InterfaceDeclaration T_PORT
670 { printf("%d/%d - %d/%d - %d/%d\n",
671 @1.first_column, @1.last_column,
672 @2.first_column, @2.last_column,
673 @3.first_column, @3.last_column); }
676 InterfaceDeclaration : OptConstantWord %dprec 1
677 | OptSignalWord %dprec 2
680 OptConstantWord : /* empty */
684 OptSignalWord : /* empty */
685 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
702 yylloc.first_column = 1;
703 yylloc.last_column = 9;
706 yylloc.first_column = 13;
707 yylloc.last_column = 17;
721 AT_BISON_OPTION_POPDEFS
723 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
724 [glr-regr8.y: conflicts: 1 reduce/reduce
726 AT_COMPILE([glr-regr8])
728 AT_PARSER_CHECK([[./glr-regr8]], 0,
737 ## ------------------------------------------------------------------------- ##
738 ## No users destructors if stack 0 deleted. See ##
739 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
740 ## ------------------------------------------------------------------------- ##
742 AT_SETUP([No users destructors if stack 0 deleted])
744 AT_BISON_OPTION_PUSHDEFS
745 AT_DATA_GRAMMAR([glr-regr9.y],
752 # define YYSTACKEXPANDABLE 0
753 static int tokens = 0;
754 static int destructors = 0;
759 %union { int dummy; }
769 ambig0 'a' { destructors += 2; USE ($2); }
770 | ambig1 start { destructors += 1; }
771 | ambig2 start { destructors += 1; }
792 exit_status = yyparse ();
793 if (tokens != destructors)
795 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
801 AT_BISON_OPTION_POPDEFS
803 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
804 [glr-regr9.y: conflicts: 1 reduce/reduce
806 AT_COMPILE([glr-regr9])
808 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
815 ## ------------------------------------------------------------------------- ##
816 ## Corrupted semantic options if user action cuts parse. ##
817 ## ------------------------------------------------------------------------- ##
819 AT_SETUP([Corrupted semantic options if user action cuts parse])
821 AT_BISON_OPTION_PUSHDEFS
822 AT_DATA_GRAMMAR([glr-regr10.y],
829 #define GARBAGE_SIZE 50
830 static char garbage[GARBAGE_SIZE];
834 %union { char *ptr; }
840 %dprec 2 { $$ = garbage; YYACCEPT; }
841 | %dprec 1 { $$ = garbage; YYACCEPT; }
852 for (i = 0; i < GARBAGE_SIZE; i+=1)
857 AT_BISON_OPTION_POPDEFS
859 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
860 [glr-regr10.y: conflicts: 1 reduce/reduce
862 AT_COMPILE([glr-regr10])
864 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
869 ## ------------------------------------------------------------------------- ##
870 ## Undesirable destructors if user action cuts parse. ##
871 ## ------------------------------------------------------------------------- ##
873 AT_SETUP([Undesirable destructors if user action cuts parse])
875 AT_BISON_OPTION_PUSHDEFS
876 AT_DATA_GRAMMAR([glr-regr11.y],
882 static int destructors = 0;
887 %union { int dummy; }
889 %destructor { destructors += 1; } 'a'
894 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
895 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
901 ]AT_YYLEX_DEFINE(["a"])[
906 int exit_status = yyparse ();
907 if (destructors != 1)
909 fprintf (stderr, "Destructor calls: %d\n", destructors);
915 AT_BISON_OPTION_POPDEFS
917 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
918 [glr-regr11.y: conflicts: 1 reduce/reduce
920 AT_COMPILE([glr-regr11])
922 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
927 ## ------------------------------------------------------------------------- ##
928 ## Leaked semantic values if user action cuts parse. ##
929 ## ------------------------------------------------------------------------- ##
931 AT_SETUP([Leaked semantic values if user action cuts parse])
933 AT_BISON_OPTION_PUSHDEFS
934 AT_DATA_GRAMMAR([glr-regr12.y],
937 %union { int dummy; }
938 %token PARENT_RHS_AFTER
939 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
940 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
941 %destructor { merged_value = 0; } merged
942 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
947 static int merge (YYSTYPE, YYSTYPE);
950 static int parent_rhs_before_value = 0;
951 static int merged_value = 0;
952 static int parent_rhs_after_value = 0;
966 parent_rhs_after_value = 0;
971 parent_rhs_before merged PARENT_RHS_AFTER {
973 parent_rhs_before_value = 0;
975 parent_rhs_after_value = 0;
982 parent_rhs_before_value = 1;
991 | cut %merge<merge> {
1002 merge (YYSTYPE s1, YYSTYPE s2)
1005 char dummy = s1.dummy + s2.dummy;
1010 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1011 [if (res == PARENT_RHS_AFTER)
1012 parent_rhs_after_value = 1;])[
1017 int exit_status = yyparse ();
1018 if (parent_rhs_before_value)
1020 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1025 fprintf (stderr, "`merged' destructor not called.\n");
1028 if (parent_rhs_after_value)
1030 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1036 AT_BISON_OPTION_POPDEFS
1038 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1039 [glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
1041 AT_COMPILE([glr-regr12])
1043 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1048 ## ------------------------------------------------------------------------- ##
1049 ## Incorrect lookahead during deterministic GLR. See ##
1050 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1051 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1052 ## ------------------------------------------------------------------------- ##
1054 AT_SETUP([Incorrect lookahead during deterministic GLR])
1056 AT_BISON_OPTION_PUSHDEFS
1057 AT_DATA_GRAMMAR([glr-regr13.y],
1060 - Defaulted state with initial yychar: yychar == YYEMPTY.
1061 - Nondefaulted state: yychar != YYEMPTY.
1062 - Defaulted state after lookahead: yychar != YYEMPTY.
1063 - Defaulted state after shift: yychar == YYEMPTY.
1064 - User action changing the lookahead. */
1069 ]AT_YYERROR_DECLARE[
1071 static void print_lookahead (char const *);
1075 %union { char value; }
1076 %type <value> 'a' 'b'
1083 defstate_init defstate_shift 'b' change_lookahead 'a' {
1085 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1090 print_lookahead ("defstate_init <- empty string");
1094 nondefstate defstate_look 'a' {
1096 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1101 print_lookahead ("defstate_look <- empty string");
1106 print_lookahead ("nondefstate <- empty string");
1110 print_lookahead ("nondefstate <- 'b'");
1122 ]AT_YYLEX_DEFINE(["ab"],
1123 [yylval.value = res + 'A' - 'a'])[
1126 print_lookahead (char const *reduction)
1128 printf ("%s:\n yychar=", reduction);
1129 if (yychar == YYEMPTY)
1131 else if (yychar == YYEOF)
1135 printf ("'%c', yylval='", yychar);
1136 if (yylval.value > ' ')
1137 printf ("%c", yylval.value);
1138 printf ("', yylloc=(%d,%d),(%d,%d)",
1139 yylloc.first_line, yylloc.first_column,
1140 yylloc.last_line, yylloc.last_column);
1148 yychar = '#'; /* Not a token in the grammar. */
1153 AT_BISON_OPTION_POPDEFS
1155 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1156 AT_COMPILE([glr-regr13])
1158 AT_PARSER_CHECK([[./glr-regr13]], 0,
1159 [defstate_init <- empty string:
1161 nondefstate <- empty string:
1162 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1163 defstate_look <- empty string:
1164 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1165 defstate_shift <- nondefstate defstate_look 'a':
1167 start <- defstate_init defstate_shift 'b':
1174 ## ------------------------------------------------------------------------- ##
1175 ## Incorrect lookahead during nondeterministic GLR. ##
1176 ## ------------------------------------------------------------------------- ##
1178 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1180 AT_BISON_OPTION_PUSHDEFS
1181 AT_DATA_GRAMMAR([glr-regr14.y],
1184 - Conflicting actions (split-off parse, which copies lookahead need,
1185 which is necessarily yytrue) and nonconflicting actions (non-split-off
1186 parse) for nondefaulted state: yychar != YYEMPTY.
1187 - Merged deferred actions (lookahead need and RHS from different stack
1188 than the target state) and nonmerged deferred actions (same stack).
1189 - Defaulted state after lookahead: yychar != YYEMPTY.
1190 - Defaulted state after shift: yychar == YYEMPTY.
1191 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1192 seen the lookahead but current stack has not).
1193 - Exceeding stack capacity (stack explosion), and thus reallocating
1194 lookahead need array.
1195 Note that it does not seem possible to see the initial yychar value during
1196 nondeterministic operation since:
1197 - In order to preserve the initial yychar, only defaulted states may be
1199 - If only defaulted states are entered, there are no conflicts, so
1200 nondeterministic operation does not start. */
1202 %union { char value; }
1208 ]AT_YYERROR_DECLARE[
1210 static void print_lookahead (char const *);
1211 static char merge (union YYSTYPE, union YYSTYPE);
1215 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1222 merge 'c' stack_explosion {
1224 print_lookahead ("start <- merge 'c' stack_explosion");
1228 /* When merging the 2 deferred actions, the lookahead needs are different. */
1230 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1232 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1234 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1236 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1243 print_lookahead ("nonconflict1 <- empty string");
1248 print_lookahead ("nonconflict2 <- empty string");
1252 print_lookahead ("nonconflict2 <- 'a'");
1257 print_lookahead ("conflict <- empty string");
1262 print_lookahead ("defstate_look <- empty string");
1266 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1269 print_lookahead ("defstate_shift <- empty string");
1275 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1276 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1277 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1282 if (yychar != 'd' && yychar != YYEOF)
1284 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1291 if (yychar != 'd' && yychar != YYEOF)
1293 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1300 if (yychar != 'd' && yychar != YYEOF)
1302 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1308 if (yychar != YYEMPTY)
1311 "Found lookahead where shouldn't during stack explosion.\n");
1322 static char const input[] = "abcdddd";
1323 static size_t toknum;
1324 assert (toknum < sizeof input);
1325 yylloc.first_line = yylloc.last_line = 1;
1326 yylloc.first_column = yylloc.last_column = toknum + 1;
1327 yylval.value = input[toknum] + 'A' - 'a';
1328 return input[toknum++];
1332 print_lookahead (char const *reduction)
1334 printf ("%s:\n yychar=", reduction);
1335 if (yychar == YYEMPTY)
1337 else if (yychar == YYEOF)
1341 printf ("'%c', yylval='", yychar);
1342 if (yylval.value > ' ')
1343 printf ("%c", yylval.value);
1344 printf ("', yylloc=(%d,%d),(%d,%d)",
1345 yylloc.first_line, yylloc.first_column,
1346 yylloc.last_line, yylloc.last_column);
1352 merge (union YYSTYPE s1, union YYSTYPE s2)
1354 char dummy = s1.value + s2.value;
1361 yychar = '#'; /* Not a token in the grammar. */
1366 AT_BISON_OPTION_POPDEFS
1368 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1369 [glr-regr14.y: conflicts: 3 reduce/reduce
1371 AT_COMPILE([glr-regr14])
1373 AT_PARSER_CHECK([[./glr-regr14]], 0,
1374 [conflict <- empty string:
1375 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1376 defstate_look <- empty string:
1377 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1378 nonconflict2 <- empty string:
1379 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1380 defstate_shift <- empty string:
1382 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1384 start <- merge 'c' stack_explosion:
1391 ## ------------------------------------------------------------------------- ##
1392 ## Leaked semantic values when reporting ambiguity. ##
1393 ## ------------------------------------------------------------------------- ##
1395 AT_SETUP([Leaked semantic values when reporting ambiguity])
1397 AT_BISON_OPTION_PUSHDEFS
1398 AT_DATA_GRAMMAR([glr-regr15.y],
1401 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1404 # include <stdlib.h>
1405 ]AT_YYERROR_DECLARE[
1407 static int parent_rhs_before_value = 0;
1418 /* This stack must be merged into the other stacks *last* (added at the
1419 beginning of the semantic options list) so that yyparse will choose to clean
1420 it up rather than the tree for which some semantic actions have been
1421 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1422 those other trees are not cleaned up. */
1426 parent_rhs_before ambiguity {
1428 parent_rhs_before_value = 0;
1435 parent_rhs_before_value = 1;
1439 ambiguity: ambiguity1 | ambiguity2 ;
1450 int exit_status = yyparse () != 1;
1451 if (parent_rhs_before_value)
1453 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1459 AT_BISON_OPTION_POPDEFS
1461 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1462 [glr-regr15.y: conflicts: 2 reduce/reduce
1464 AT_COMPILE([glr-regr15])
1466 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1467 [syntax is ambiguous
1473 ## ------------------------------------------------------------------------- ##
1474 ## Leaked lookahead after nondeterministic parse syntax error. ##
1475 ## ------------------------------------------------------------------------- ##
1477 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1479 AT_BISON_OPTION_PUSHDEFS
1480 AT_DATA_GRAMMAR([glr-regr16.y],
1483 %destructor { lookahead_value = 0; } 'b'
1486 # include <stdlib.h>
1487 # include <assert.h>
1488 ]AT_YYERROR_DECLARE[
1490 static int lookahead_value = 0;
1496 start: alt1 'a' | alt2 'a' ;
1503 ]AT_YYLEX_DEFINE(["ab"],
1505 lookahead_value = 1])[
1510 int exit_status = yyparse () != 1;
1511 if (lookahead_value)
1513 fprintf (stderr, "Lookahead destructor not called.\n");
1519 AT_BISON_OPTION_POPDEFS
1521 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1522 [glr-regr16.y: conflicts: 1 reduce/reduce
1524 AT_COMPILE([glr-regr16])
1526 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1533 ## ------------------------------------------------------------------------- ##
1534 ## Uninitialized location when reporting ambiguity. ##
1535 ## ------------------------------------------------------------------------- ##
1537 AT_SETUP([Uninitialized location when reporting ambiguity])
1539 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1541 AT_DATA_GRAMMAR([glr-regr17.y],
1548 %union { int dummy; }
1551 ]AT_YYERROR_DECLARE[
1557 /* Tests the case of an empty RHS that has inherited the location of the
1558 previous nonterminal, which is unresolved. That location is reported as the
1559 last position of the ambiguity. */
1560 start: ambig1 empty1 | ambig2 empty2 ;
1562 /* Tests multiple levels of yyresolveLocations recursion. */
1563 ambig1: sub_ambig1 | sub_ambig2 ;
1564 ambig2: sub_ambig1 | sub_ambig2 ;
1566 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1567 has inherited the initial location. The empty RHS's location is reported as
1568 the first position in the ambiguity. */
1569 sub_ambig1: empty1 'a' 'b' ;
1570 sub_ambig2: empty2 'a' 'b' ;
1575 # include <assert.h>
1579 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1581 static char const input[] = "ab";
1582 static size_t toknum;
1583 assert (toknum < sizeof input);
1585 llocp->first_line = llocp->last_line = 2;
1586 llocp->first_column = toknum + 1;
1587 llocp->last_column = llocp->first_column + 1;
1588 return input[toknum++];
1594 return yyparse () != 1;
1597 AT_BISON_OPTION_POPDEFS
1599 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1600 [glr-regr17.y: conflicts: 3 reduce/reduce
1602 AT_COMPILE([glr-regr17])
1604 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1605 [1.1-2.2: syntax is ambiguous
1611 ## -------------------------------------------------------------##
1612 ## Missed %merge type warnings when LHS type is declared later. ##
1613 ## -------------------------------------------------------------##
1615 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1617 AT_BISON_OPTION_PUSHDEFS
1618 AT_DATA_GRAMMAR([glr-regr18.y],
1623 ]AT_YYERROR_DECLARE[
1635 sym1: sym2 %merge<merge> { $$ = $1; } ;
1636 sym2: sym3 %merge<merge> { $$ = $1; } ;
1637 sym3: %merge<merge> { $$ = 0; } ;
1652 AT_BISON_OPTION_POPDEFS
1654 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1655 [glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
1656 glr-regr18.y:25.18-24: previous declaration
1657 glr-regr18.y:27.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
1658 glr-regr18.y:26.18-24: previous declaration
1664 ## ------------------- ##
1665 ## Ambiguity reports. ##
1666 ## ------------------- ##
1668 AT_SETUP([Ambiguity reports])
1670 AT_BISON_OPTION_PUSHDEFS
1671 AT_DATA_GRAMMAR([input.y],
1676 ]AT_YYERROR_DECLARE[
1691 ]AT_YYLEX_DEFINE(["abc"])[
1697 return !!yyparse ();
1700 AT_BISON_OPTION_POPDEFS
1702 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1703 [input.y: conflicts: 1 reduce/reduce
1707 AT_PARSER_CHECK([[./input]], 1, [],
1710 Reading a token: Next token is token 'a' ()
1711 Shifting token 'a' ()
1713 Reading a token: Next token is token 'b' ()
1714 Shifting token 'b' ()
1716 Reducing stack 0 by rule 3 (line 25):
1720 Reading a token: Next token is token 'c' ()
1721 Shifting token 'c' ()
1723 Reducing stack 0 by rule 4 (line 26):
1726 Reading a token: Now at end of input.
1727 Stack 0 Entering state 7
1728 Now at end of input.
1729 Splitting off stack 1 from 0.
1730 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1731 Stack 1 Entering state 2
1732 Now at end of input.
1733 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1734 Merging stack 0 into stack 1.
1735 Stack 1 Entering state 2
1736 Now at end of input.
1737 Removing dead stacks.
1738 Rename stack 1 -> 0.
1739 On stack 0, shifting token $end ()
1740 Stack 0 now in state #5
1743 start -> <Rule 1, tokens 1 .. 3>
1750 start -> <Rule 2, tokens 1 .. 3>
1757 Cleanup: popping token $end ()
1758 Cleanup: popping unresolved nterm start ()
1759 Cleanup: popping nterm d ()
1760 Cleanup: popping token 'c' ()
1761 Cleanup: popping nterm b ()
1762 Cleanup: popping token 'a' ()