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)
84 assert (!feof (stdin));
88 else if (ch == 'B' || ch == 'P')
93 AT_BISON_OPTION_POPDEFS
95 AT_BISON_CHECK([[-o glr-regr1.c glr-regr1.y]], 0, [],
96 [[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
98 AT_COMPILE([glr-regr1])
99 AT_PARSER_CHECK([[echo BPBPB | ./glr-regr1]], 0,
113 ## ------------------------------------------------------------ ##
114 ## Improper handling of embedded actions and $-N in GLR parsers ##
115 ## ------------------------------------------------------------ ##
117 AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers])
119 AT_BISON_OPTION_PUSHDEFS
120 AT_DATA_GRAMMAR([glr-regr2a.y],
121 [[/* Regression Test: Improper handling of embedded actions and $-N */
122 /* Reported by S. Eken */
125 #define YYSTYPE char *
142 { printf ("Variable: '%s'\n", $2); }
145 | 's' var_list 't' 'e'
146 { printf ("Varlist: '%s'\n", $2); free ($2); }
147 | 's' var 't' var_printer 'x'
161 char *s = (char *) realloc ($1, strlen ($1) + 1 + strlen ($3) + 1);
170 { printf ("Variable: '%s'\n", $-1); }
181 assert (!feof (stdin));
182 switch (fscanf (input, " %1[a-z,]", buf))
191 if (fscanf (input, "%49s", buf) != 1)
193 assert (strlen (buf) < sizeof buf - 1);
194 s = (char *) malloc (strlen (buf) + 1);
201 main (int argc, char **argv)
204 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
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_PARSER_CHECK([[echo s VARIABLE_1 t v x q | ./glr-regr2a]], 0,
216 [[Variable: 'VARIABLE_1'
218 AT_PARSER_CHECK([[echo s VARIABLE_1 , ANOTHER_VARIABLE_2 t e | ./glr-regr2a]],
220 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
222 AT_PARSER_CHECK([[echo s VARIABLE_3 t v x | ./glr-regr2a]], 0,
223 [[Variable: 'VARIABLE_3'
229 ## ------------------------------------------------------------ ##
230 ## Improper merging of GLR delayed action sets ##
231 ## ------------------------------------------------------------ ##
233 AT_SETUP([Improper merging of GLR delayed action sets])
235 AT_BISON_OPTION_PUSHDEFS
236 AT_DATA_GRAMMAR([glr-regr3.y],
237 [[/* Regression Test: Improper merging of GLR delayed action sets. */
238 /* Reported by M. Rosien */
246 static int MergeRule (int x0, int x1);
250 #define RULE(x) (1 << (x))
257 %token P1 P2 T1 T2 T3 T4 O1 O2
261 S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
264 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
267 NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
268 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
271 NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
272 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
275 NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
276 | NT2 { $$ = RULE(8); } %merge<MergeRule>
277 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
280 NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
283 NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
284 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
290 MergeRule (int x0, int x1)
296 FILE *input = YY_NULL;
298 int P[] = { P1, P2 };
299 int O[] = { O1, O2 };
300 int T[] = { T1, T2, T3, T4 };
305 assert (!feof (stdin));
306 if (fscanf (input, "%2s", inp) == EOF)
310 case 'p': return P[inp[1] - '1'];
311 case 't': return T[inp[1] - '1'];
312 case 'o': return O[inp[1] - '1'];
318 main(int argc, char* argv[])
321 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
325 AT_BISON_OPTION_POPDEFS
327 AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
328 [[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
329 glr-regr3.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
331 AT_COMPILE([glr-regr3])
333 AT_PARSER_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]],
341 ## ------------------------------------------------------------------------- ##
342 ## Duplicate representation of merged trees. See ##
343 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
344 ## ------------------------------------------------------------------------- ##
346 AT_SETUP([Duplicate representation of merged trees])
348 AT_BISON_OPTION_PUSHDEFS
349 AT_DATA_GRAMMAR([glr-regr4.y],
351 %union { char *ptr; }
352 %type <ptr> S A A1 A2 B
359 static char *merge (YYSTYPE, YYSTYPE);
360 static char *make_value (char const *, char const *);
363 static char *ptrs[100];
364 static char **ptrs_next = ptrs;
369 tree: S { printf ("%s\n", $1); } ;
372 A %merge<merge> { $$ = make_value ("S", $1); }
373 | B %merge<merge> { $$ = make_value ("S", $1); }
377 A1 %merge<merge> { $$ = make_value ("A", $1); }
378 | A2 %merge<merge> { $$ = make_value ("A", $1); }
381 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
382 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
383 B: 'a' { $$ = make_value ("B", "'a'"); } ;
387 ]AT_YYLEX_DEFINE(["a"])[
392 int status = yyparse ();
393 while (ptrs_next != ptrs)
399 make_value (char const *parent, char const *child)
401 char const format[] = "%s <- %s";
402 char *value = *ptrs_next++ =
403 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
404 sprintf (value, format, parent, child);
409 merge (YYSTYPE s1, YYSTYPE s2)
411 char const format[] = "merge{ %s and %s }";
412 char *value = *ptrs_next++ =
413 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
414 sprintf (value, format, s1.ptr, s2.ptr);
418 AT_BISON_OPTION_POPDEFS
420 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
421 [[glr-regr4.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
423 AT_COMPILE([glr-regr4])
425 AT_PARSER_CHECK([[./glr-regr4]], 0,
426 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
432 ## -------------------------------------------------------------------------- ##
433 ## User destructor for unresolved GLR semantic value. See ##
434 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
435 ## -------------------------------------------------------------------------- ##
437 AT_SETUP([User destructor for unresolved GLR semantic value])
439 AT_BISON_OPTION_PUSHDEFS
440 AT_DATA_GRAMMAR([glr-regr5.y],
447 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
451 %union { int value; }
455 if ($$ != MAGIC_VALUE)
457 fprintf (stderr, "Bad destructor call.\n");
465 'a' { $$ = MAGIC_VALUE; }
466 | 'a' { $$ = MAGIC_VALUE; }
470 ]AT_YYLEX_DEFINE(["a"])[
475 return yyparse () != 1;
478 AT_BISON_OPTION_POPDEFS
480 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
481 [[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
483 AT_COMPILE([glr-regr5])
485 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
492 ## -------------------------------------------------------------------------- ##
493 ## User destructor after an error during a split parse. See ##
494 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
495 ## -------------------------------------------------------------------------- ##
497 AT_SETUP([User destructor after an error during a split parse])
499 AT_BISON_OPTION_PUSHDEFS
500 AT_DATA_GRAMMAR([glr-regr6.y],
510 %union { int value; }
514 printf ("Destructor called.\n");
523 ]AT_YYLEX_DEFINE(["a"])[
527 return yyparse () != 1;
530 AT_BISON_OPTION_POPDEFS
532 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
533 [[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
535 AT_COMPILE([glr-regr6])
537 AT_PARSER_CHECK([[./glr-regr6]], 0,
546 ## ------------------------------------------------------------------------- ##
547 ## Duplicated user destructor for lookahead. See ##
548 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
549 ## ------------------------------------------------------------------------- ##
551 AT_SETUP([Duplicated user destructor for lookahead])
553 AT_BISON_OPTION_PUSHDEFS
554 AT_DATA_GRAMMAR([glr-regr7.y],
561 #define YYSTACKEXPANDABLE 0
562 typedef struct count_node {
564 struct count_node *prev;
566 static count_node *tail;
570 %union { count_node *node; }
575 fprintf (stderr, "Destructor called on same value twice.\n");
593 yylval.node = (count_node*) malloc (sizeof *yylval.node);
596 fprintf (stderr, "Test inconclusive.\n");
599 yylval.node->count = 0;
600 yylval.node->prev = tail;
609 int status = yyparse ();
612 count_node *prev = tail->prev;
619 AT_BISON_OPTION_POPDEFS
621 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
622 [[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
624 AT_COMPILE([glr-regr7])
626 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
633 ## ------------------------------------------------------------------------- ##
634 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
635 ## report by Claudia Hermann. ##
636 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
637 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
638 ## ------------------------------------------------------------------------- ##
640 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
642 AT_BISON_OPTION_PUSHDEFS
643 AT_DATA_GRAMMAR([glr-regr8.y],
661 PortClause : T_PORT InterfaceDeclaration T_PORT
662 { printf("%d/%d - %d/%d - %d/%d\n",
663 @1.first_column, @1.last_column,
664 @2.first_column, @2.last_column,
665 @3.first_column, @3.last_column); }
668 InterfaceDeclaration : OptConstantWord %dprec 1
669 | OptSignalWord %dprec 2
672 OptConstantWord : /* empty */
676 OptSignalWord : /* empty */
677 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
694 yylloc.first_column = 1;
695 yylloc.last_column = 9;
698 yylloc.first_column = 13;
699 yylloc.last_column = 17;
713 AT_BISON_OPTION_POPDEFS
715 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
716 [[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
718 AT_COMPILE([glr-regr8])
720 AT_PARSER_CHECK([[./glr-regr8]], 0,
729 ## ------------------------------------------------------------------------- ##
730 ## No users destructors if stack 0 deleted. See ##
731 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
732 ## ------------------------------------------------------------------------- ##
734 AT_SETUP([No users destructors if stack 0 deleted])
736 AT_BISON_OPTION_PUSHDEFS
737 AT_DATA_GRAMMAR([glr-regr9.y],
744 # define YYSTACKEXPANDABLE 0
745 static int tokens = 0;
746 static int destructors = 0;
751 %union { int dummy; }
761 ambig0 'a' { destructors += 2; USE ($2); }
762 | ambig1 start { destructors += 1; }
763 | ambig2 start { destructors += 1; }
784 exit_status = yyparse ();
785 if (tokens != destructors)
787 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
793 AT_BISON_OPTION_POPDEFS
795 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
796 [[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
798 AT_COMPILE([glr-regr9])
800 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
807 ## ------------------------------------------------------------------------- ##
808 ## Corrupted semantic options if user action cuts parse. ##
809 ## ------------------------------------------------------------------------- ##
811 AT_SETUP([Corrupted semantic options if user action cuts parse])
813 AT_BISON_OPTION_PUSHDEFS
814 AT_DATA_GRAMMAR([glr-regr10.y],
821 #define GARBAGE_SIZE 50
822 static char garbage[GARBAGE_SIZE];
826 %union { char *ptr; }
832 %dprec 2 { $$ = garbage; YYACCEPT; }
833 | %dprec 1 { $$ = garbage; YYACCEPT; }
844 for (i = 0; i < GARBAGE_SIZE; i+=1)
849 AT_BISON_OPTION_POPDEFS
851 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
852 [[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
854 AT_COMPILE([glr-regr10])
856 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
861 ## ------------------------------------------------------------------------- ##
862 ## Undesirable destructors if user action cuts parse. ##
863 ## ------------------------------------------------------------------------- ##
865 AT_SETUP([Undesirable destructors if user action cuts parse])
867 AT_BISON_OPTION_PUSHDEFS
868 AT_DATA_GRAMMAR([glr-regr11.y],
874 static int destructors = 0;
879 %union { int dummy; }
881 %destructor { destructors += 1; } 'a'
886 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
887 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
893 ]AT_YYLEX_DEFINE(["a"])[
898 int exit_status = yyparse ();
899 if (destructors != 1)
901 fprintf (stderr, "Destructor calls: %d\n", destructors);
907 AT_BISON_OPTION_POPDEFS
909 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
910 [[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
912 AT_COMPILE([glr-regr11])
914 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
919 ## ------------------------------------------------------------------------- ##
920 ## Leaked semantic values if user action cuts parse. ##
921 ## ------------------------------------------------------------------------- ##
923 AT_SETUP([Leaked semantic values if user action cuts parse])
925 AT_BISON_OPTION_PUSHDEFS
926 AT_DATA_GRAMMAR([glr-regr12.y],
929 %union { int dummy; }
930 %token PARENT_RHS_AFTER
931 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
932 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
933 %destructor { merged_value = 0; } merged
934 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
939 static int merge (YYSTYPE, YYSTYPE);
942 static int parent_rhs_before_value = 0;
943 static int merged_value = 0;
944 static int parent_rhs_after_value = 0;
958 parent_rhs_after_value = 0;
963 parent_rhs_before merged PARENT_RHS_AFTER {
965 parent_rhs_before_value = 0;
967 parent_rhs_after_value = 0;
974 parent_rhs_before_value = 1;
983 | cut %merge<merge> {
994 merge (YYSTYPE s1, YYSTYPE s2)
997 char dummy = s1.dummy + s2.dummy;
1002 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1003 [if (res == PARENT_RHS_AFTER)
1004 parent_rhs_after_value = 1;])[
1009 int exit_status = yyparse ();
1010 if (parent_rhs_before_value)
1012 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1017 fprintf (stderr, "`merged' destructor not called.\n");
1020 if (parent_rhs_after_value)
1022 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1028 AT_BISON_OPTION_POPDEFS
1030 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1031 [[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1032 glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1034 AT_COMPILE([glr-regr12])
1036 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1041 ## ------------------------------------------------------------------------- ##
1042 ## Incorrect lookahead during deterministic GLR. See ##
1043 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1044 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1045 ## ------------------------------------------------------------------------- ##
1047 AT_SETUP([Incorrect lookahead during deterministic GLR])
1049 AT_BISON_OPTION_PUSHDEFS
1050 AT_DATA_GRAMMAR([glr-regr13.y],
1053 - Defaulted state with initial yychar: yychar == YYEMPTY.
1054 - Nondefaulted state: yychar != YYEMPTY.
1055 - Defaulted state after lookahead: yychar != YYEMPTY.
1056 - Defaulted state after shift: yychar == YYEMPTY.
1057 - User action changing the lookahead. */
1062 ]AT_YYERROR_DECLARE[
1064 static void print_lookahead (char const *);
1068 %union { char value; }
1069 %type <value> 'a' 'b'
1076 defstate_init defstate_shift 'b' change_lookahead 'a' {
1078 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1083 print_lookahead ("defstate_init <- empty string");
1087 nondefstate defstate_look 'a' {
1089 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1094 print_lookahead ("defstate_look <- empty string");
1099 print_lookahead ("nondefstate <- empty string");
1103 print_lookahead ("nondefstate <- 'b'");
1115 ]AT_YYLEX_DEFINE(["ab"],
1116 [yylval.value = res + 'A' - 'a'])[
1119 print_lookahead (char const *reduction)
1121 printf ("%s:\n yychar=", reduction);
1122 if (yychar == YYEMPTY)
1124 else if (yychar == YYEOF)
1128 printf ("'%c', yylval='", yychar);
1129 if (yylval.value > ' ')
1130 printf ("%c", yylval.value);
1131 printf ("', yylloc=(%d,%d),(%d,%d)",
1132 yylloc.first_line, yylloc.first_column,
1133 yylloc.last_line, yylloc.last_column);
1141 yychar = '#'; /* Not a token in the grammar. */
1146 AT_BISON_OPTION_POPDEFS
1148 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1149 AT_COMPILE([glr-regr13])
1151 AT_PARSER_CHECK([[./glr-regr13]], 0,
1152 [defstate_init <- empty string:
1154 nondefstate <- empty string:
1155 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1156 defstate_look <- empty string:
1157 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1158 defstate_shift <- nondefstate defstate_look 'a':
1160 start <- defstate_init defstate_shift 'b':
1167 ## ------------------------------------------------------------------------- ##
1168 ## Incorrect lookahead during nondeterministic GLR. ##
1169 ## ------------------------------------------------------------------------- ##
1171 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1173 AT_BISON_OPTION_PUSHDEFS
1174 AT_DATA_GRAMMAR([glr-regr14.y],
1177 - Conflicting actions (split-off parse, which copies lookahead need,
1178 which is necessarily yytrue) and nonconflicting actions (non-split-off
1179 parse) for nondefaulted state: yychar != YYEMPTY.
1180 - Merged deferred actions (lookahead need and RHS from different stack
1181 than the target state) and nonmerged deferred actions (same stack).
1182 - Defaulted state after lookahead: yychar != YYEMPTY.
1183 - Defaulted state after shift: yychar == YYEMPTY.
1184 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1185 seen the lookahead but current stack has not).
1186 - Exceeding stack capacity (stack explosion), and thus reallocating
1187 lookahead need array.
1188 Note that it does not seem possible to see the initial yychar value during
1189 nondeterministic operation since:
1190 - In order to preserve the initial yychar, only defaulted states may be
1192 - If only defaulted states are entered, there are no conflicts, so
1193 nondeterministic operation does not start. */
1195 %union { char value; }
1201 ]AT_YYERROR_DECLARE[
1203 static void print_lookahead (char const *);
1204 static char merge (union YYSTYPE, union YYSTYPE);
1208 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1215 merge 'c' stack_explosion {
1217 print_lookahead ("start <- merge 'c' stack_explosion");
1221 /* When merging the 2 deferred actions, the lookahead needs are different. */
1223 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1225 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1227 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1229 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1236 print_lookahead ("nonconflict1 <- empty string");
1241 print_lookahead ("nonconflict2 <- empty string");
1245 print_lookahead ("nonconflict2 <- 'a'");
1250 print_lookahead ("conflict <- empty string");
1255 print_lookahead ("defstate_look <- empty string");
1259 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1262 print_lookahead ("defstate_shift <- empty string");
1268 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1269 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1270 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1275 if (yychar != 'd' && yychar != YYEOF)
1277 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1284 if (yychar != 'd' && yychar != YYEOF)
1286 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1293 if (yychar != 'd' && yychar != YYEOF)
1295 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1301 if (yychar != YYEMPTY)
1304 "Found lookahead where shouldn't during stack explosion.\n");
1315 static char const input[] = "abcdddd";
1316 static size_t toknum;
1317 assert (toknum < sizeof input);
1318 yylloc.first_line = yylloc.last_line = 1;
1319 yylloc.first_column = yylloc.last_column = toknum + 1;
1320 yylval.value = input[toknum] + 'A' - 'a';
1321 return input[toknum++];
1325 print_lookahead (char const *reduction)
1327 printf ("%s:\n yychar=", reduction);
1328 if (yychar == YYEMPTY)
1330 else if (yychar == YYEOF)
1334 printf ("'%c', yylval='", yychar);
1335 if (yylval.value > ' ')
1336 printf ("%c", yylval.value);
1337 printf ("', yylloc=(%d,%d),(%d,%d)",
1338 yylloc.first_line, yylloc.first_column,
1339 yylloc.last_line, yylloc.last_column);
1345 merge (union YYSTYPE s1, union YYSTYPE s2)
1347 char dummy = s1.value + s2.value;
1354 yychar = '#'; /* Not a token in the grammar. */
1359 AT_BISON_OPTION_POPDEFS
1361 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1362 [[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1364 AT_COMPILE([glr-regr14])
1366 AT_PARSER_CHECK([[./glr-regr14]], 0,
1367 [conflict <- empty string:
1368 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1369 defstate_look <- empty string:
1370 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1371 nonconflict2 <- empty string:
1372 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1373 defstate_shift <- empty string:
1375 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1377 start <- merge 'c' stack_explosion:
1384 ## ------------------------------------------------------------------------- ##
1385 ## Leaked semantic values when reporting ambiguity. ##
1386 ## ------------------------------------------------------------------------- ##
1388 AT_SETUP([Leaked semantic values when reporting ambiguity])
1390 AT_BISON_OPTION_PUSHDEFS
1391 AT_DATA_GRAMMAR([glr-regr15.y],
1394 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1397 # include <stdlib.h>
1398 ]AT_YYERROR_DECLARE[
1400 static int parent_rhs_before_value = 0;
1411 /* This stack must be merged into the other stacks *last* (added at the
1412 beginning of the semantic options list) so that yyparse will choose to clean
1413 it up rather than the tree for which some semantic actions have been
1414 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1415 those other trees are not cleaned up. */
1419 parent_rhs_before ambiguity {
1421 parent_rhs_before_value = 0;
1428 parent_rhs_before_value = 1;
1432 ambiguity: ambiguity1 | ambiguity2 ;
1443 int exit_status = yyparse () != 1;
1444 if (parent_rhs_before_value)
1446 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1452 AT_BISON_OPTION_POPDEFS
1454 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1455 [[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1457 AT_COMPILE([glr-regr15])
1459 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1460 [syntax is ambiguous
1466 ## ------------------------------------------------------------------------- ##
1467 ## Leaked lookahead after nondeterministic parse syntax error. ##
1468 ## ------------------------------------------------------------------------- ##
1470 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1472 AT_BISON_OPTION_PUSHDEFS
1473 AT_DATA_GRAMMAR([glr-regr16.y],
1476 %destructor { lookahead_value = 0; } 'b'
1479 # include <stdlib.h>
1480 # include <assert.h>
1481 ]AT_YYERROR_DECLARE[
1483 static int lookahead_value = 0;
1489 start: alt1 'a' | alt2 'a' ;
1496 ]AT_YYLEX_DEFINE(["ab"],
1498 lookahead_value = 1])[
1503 int exit_status = yyparse () != 1;
1504 if (lookahead_value)
1506 fprintf (stderr, "Lookahead destructor not called.\n");
1512 AT_BISON_OPTION_POPDEFS
1514 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1515 [[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1517 AT_COMPILE([glr-regr16])
1519 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1526 ## ------------------------------------------------------------------------- ##
1527 ## Uninitialized location when reporting ambiguity. ##
1528 ## ------------------------------------------------------------------------- ##
1530 AT_SETUP([Uninitialized location when reporting ambiguity])
1532 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1534 AT_DATA_GRAMMAR([glr-regr17.y],
1541 %union { int dummy; }
1544 ]AT_YYERROR_DECLARE[
1550 /* Tests the case of an empty RHS that has inherited the location of the
1551 previous nonterminal, which is unresolved. That location is reported as the
1552 last position of the ambiguity. */
1553 start: ambig1 empty1 | ambig2 empty2 ;
1555 /* Tests multiple levels of yyresolveLocations recursion. */
1556 ambig1: sub_ambig1 | sub_ambig2 ;
1557 ambig2: sub_ambig1 | sub_ambig2 ;
1559 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1560 has inherited the initial location. The empty RHS's location is reported as
1561 the first position in the ambiguity. */
1562 sub_ambig1: empty1 'a' 'b' ;
1563 sub_ambig2: empty2 'a' 'b' ;
1568 # include <assert.h>
1572 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1574 static char const input[] = "ab";
1575 static size_t toknum;
1576 assert (toknum < sizeof input);
1578 llocp->first_line = llocp->last_line = 2;
1579 llocp->first_column = toknum + 1;
1580 llocp->last_column = llocp->first_column + 1;
1581 return input[toknum++];
1587 return yyparse () != 1;
1590 AT_BISON_OPTION_POPDEFS
1592 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1593 [[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1595 AT_COMPILE([glr-regr17])
1597 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1598 [1.1-2.2: syntax is ambiguous
1604 ## -------------------------------------------------------------##
1605 ## Missed %merge type warnings when LHS type is declared later. ##
1606 ## -------------------------------------------------------------##
1608 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1610 AT_BISON_OPTION_PUSHDEFS
1611 AT_DATA_GRAMMAR([glr-regr18.y],
1616 ]AT_YYERROR_DECLARE[
1628 sym1: sym2 %merge<merge> { $$ = $1; } ;
1629 sym2: sym3 %merge<merge> { $$ = $1; } ;
1630 sym3: %merge<merge> { $$ = 0; } ;
1645 AT_BISON_OPTION_POPDEFS
1647 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1648 [[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
1649 glr-regr18.y:25.18-24: previous declaration
1650 glr-regr18.y:27.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
1651 glr-regr18.y:26.18-24: previous declaration
1657 ## ------------------- ##
1658 ## Ambiguity reports. ##
1659 ## ------------------- ##
1661 AT_SETUP([Ambiguity reports])
1663 AT_BISON_OPTION_PUSHDEFS
1664 AT_DATA_GRAMMAR([input.y],
1669 ]AT_YYERROR_DECLARE[
1684 ]AT_YYLEX_DEFINE(["abc"])[
1690 return !!yyparse ();
1693 AT_BISON_OPTION_POPDEFS
1695 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1696 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1700 AT_PARSER_CHECK([[./input]], 1, [],
1703 Reading a token: Next token is token 'a' ()
1704 Shifting token 'a' ()
1706 Reading a token: Next token is token 'b' ()
1707 Shifting token 'b' ()
1709 Reducing stack 0 by rule 3 (line 25):
1713 Reading a token: Next token is token 'c' ()
1714 Shifting token 'c' ()
1716 Reducing stack 0 by rule 4 (line 26):
1719 Reading a token: Now at end of input.
1720 Stack 0 Entering state 7
1721 Now at end of input.
1722 Splitting off stack 1 from 0.
1723 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1724 Stack 1 Entering state 2
1725 Now at end of input.
1726 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1727 Merging stack 0 into stack 1.
1728 Stack 1 Entering state 2
1729 Now at end of input.
1730 Removing dead stacks.
1731 Rename stack 1 -> 0.
1732 On stack 0, shifting token $end ()
1733 Stack 0 now in state #5
1736 start -> <Rule 1, tokens 1 .. 3>
1743 start -> <Rule 2, tokens 1 .. 3>
1750 Cleanup: popping token $end ()
1751 Cleanup: popping unresolved nterm start ()
1752 Cleanup: popping nterm d ()
1753 Cleanup: popping token 'c' ()
1754 Cleanup: popping nterm b ()
1755 Cleanup: popping token 'a' ()