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: conflicts: 1 shift/reduce
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: conflicts: 2 shift/reduce
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: conflicts: 1 shift/reduce, 1 reduce/reduce
330 AT_COMPILE([glr-regr3])
332 AT_PARSER_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]],
340 ## ------------------------------------------------------------------------- ##
341 ## Duplicate representation of merged trees. See ##
342 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
343 ## ------------------------------------------------------------------------- ##
345 AT_SETUP([Duplicate representation of merged trees])
347 AT_BISON_OPTION_PUSHDEFS
348 AT_DATA_GRAMMAR([glr-regr4.y],
350 %union { char *ptr; }
351 %type <ptr> S A A1 A2 B
358 static char *merge (YYSTYPE, YYSTYPE);
359 static char *make_value (char const *, char const *);
362 static char *ptrs[100];
363 static char **ptrs_next = ptrs;
368 tree: S { printf ("%s\n", $1); } ;
371 A %merge<merge> { $$ = make_value ("S", $1); }
372 | B %merge<merge> { $$ = make_value ("S", $1); }
376 A1 %merge<merge> { $$ = make_value ("A", $1); }
377 | A2 %merge<merge> { $$ = make_value ("A", $1); }
380 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
381 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
382 B: 'a' { $$ = make_value ("B", "'a'"); } ;
386 ]AT_YYLEX_DEFINE(["a"])[
391 int status = yyparse ();
392 while (ptrs_next != ptrs)
398 make_value (char const *parent, char const *child)
400 char const format[] = "%s <- %s";
401 char *value = *ptrs_next++ =
402 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
403 sprintf (value, format, parent, child);
408 merge (YYSTYPE s1, YYSTYPE s2)
410 char const format[] = "merge{ %s and %s }";
411 char *value = *ptrs_next++ =
412 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
413 sprintf (value, format, s1.ptr, s2.ptr);
417 AT_BISON_OPTION_POPDEFS
419 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
420 [glr-regr4.y: conflicts: 1 reduce/reduce
422 AT_COMPILE([glr-regr4])
424 AT_PARSER_CHECK([[./glr-regr4]], 0,
425 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
431 ## -------------------------------------------------------------------------- ##
432 ## User destructor for unresolved GLR semantic value. See ##
433 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
434 ## -------------------------------------------------------------------------- ##
436 AT_SETUP([User destructor for unresolved GLR semantic value])
438 AT_BISON_OPTION_PUSHDEFS
439 AT_DATA_GRAMMAR([glr-regr5.y],
446 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
450 %union { int value; }
454 if ($$ != MAGIC_VALUE)
456 fprintf (stderr, "Bad destructor call.\n");
464 'a' { $$ = MAGIC_VALUE; }
465 | 'a' { $$ = MAGIC_VALUE; }
469 ]AT_YYLEX_DEFINE(["a"])[
474 return yyparse () != 1;
477 AT_BISON_OPTION_POPDEFS
479 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
480 [glr-regr5.y: conflicts: 1 reduce/reduce
482 AT_COMPILE([glr-regr5])
484 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
491 ## -------------------------------------------------------------------------- ##
492 ## User destructor after an error during a split parse. See ##
493 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
494 ## -------------------------------------------------------------------------- ##
496 AT_SETUP([User destructor after an error during a split parse])
498 AT_BISON_OPTION_PUSHDEFS
499 AT_DATA_GRAMMAR([glr-regr6.y],
509 %union { int value; }
513 printf ("Destructor called.\n");
522 ]AT_YYLEX_DEFINE(["a"])[
526 return yyparse () != 1;
529 AT_BISON_OPTION_POPDEFS
531 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
532 [glr-regr6.y: conflicts: 1 reduce/reduce
534 AT_COMPILE([glr-regr6])
536 AT_PARSER_CHECK([[./glr-regr6]], 0,
545 ## ------------------------------------------------------------------------- ##
546 ## Duplicated user destructor for lookahead. See ##
547 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
548 ## ------------------------------------------------------------------------- ##
550 AT_SETUP([Duplicated user destructor for lookahead])
552 AT_BISON_OPTION_PUSHDEFS
553 AT_DATA_GRAMMAR([glr-regr7.y],
560 #define YYSTACKEXPANDABLE 0
561 typedef struct count_node {
563 struct count_node *prev;
565 static count_node *tail;
569 %union { count_node *node; }
574 fprintf (stderr, "Destructor called on same value twice.\n");
592 yylval.node = (count_node*) malloc (sizeof *yylval.node);
595 fprintf (stderr, "Test inconclusive.\n");
598 yylval.node->count = 0;
599 yylval.node->prev = tail;
608 int status = yyparse ();
611 count_node *prev = tail->prev;
618 AT_BISON_OPTION_POPDEFS
620 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
621 [glr-regr7.y: conflicts: 2 reduce/reduce
623 AT_COMPILE([glr-regr7])
625 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
632 ## ------------------------------------------------------------------------- ##
633 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
634 ## report by Claudia Hermann. ##
635 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
636 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
637 ## ------------------------------------------------------------------------- ##
639 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
641 AT_BISON_OPTION_PUSHDEFS
642 AT_DATA_GRAMMAR([glr-regr8.y],
660 PortClause : T_PORT InterfaceDeclaration T_PORT
661 { printf("%d/%d - %d/%d - %d/%d\n",
662 @1.first_column, @1.last_column,
663 @2.first_column, @2.last_column,
664 @3.first_column, @3.last_column); }
667 InterfaceDeclaration : OptConstantWord %dprec 1
668 | OptSignalWord %dprec 2
671 OptConstantWord : /* empty */
675 OptSignalWord : /* empty */
676 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
693 yylloc.first_column = 1;
694 yylloc.last_column = 9;
697 yylloc.first_column = 13;
698 yylloc.last_column = 17;
712 AT_BISON_OPTION_POPDEFS
714 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
715 [glr-regr8.y: conflicts: 1 reduce/reduce
717 AT_COMPILE([glr-regr8])
719 AT_PARSER_CHECK([[./glr-regr8]], 0,
728 ## ------------------------------------------------------------------------- ##
729 ## No users destructors if stack 0 deleted. See ##
730 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
731 ## ------------------------------------------------------------------------- ##
733 AT_SETUP([No users destructors if stack 0 deleted])
735 AT_BISON_OPTION_PUSHDEFS
736 AT_DATA_GRAMMAR([glr-regr9.y],
743 # define YYSTACKEXPANDABLE 0
744 static int tokens = 0;
745 static int destructors = 0;
750 %union { int dummy; }
760 ambig0 'a' { destructors += 2; USE ($2); }
761 | ambig1 start { destructors += 1; }
762 | ambig2 start { destructors += 1; }
783 exit_status = yyparse ();
784 if (tokens != destructors)
786 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
792 AT_BISON_OPTION_POPDEFS
794 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
795 [glr-regr9.y: conflicts: 1 reduce/reduce
797 AT_COMPILE([glr-regr9])
799 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
806 ## ------------------------------------------------------------------------- ##
807 ## Corrupted semantic options if user action cuts parse. ##
808 ## ------------------------------------------------------------------------- ##
810 AT_SETUP([Corrupted semantic options if user action cuts parse])
812 AT_BISON_OPTION_PUSHDEFS
813 AT_DATA_GRAMMAR([glr-regr10.y],
820 #define GARBAGE_SIZE 50
821 static char garbage[GARBAGE_SIZE];
825 %union { char *ptr; }
831 %dprec 2 { $$ = garbage; YYACCEPT; }
832 | %dprec 1 { $$ = garbage; YYACCEPT; }
843 for (i = 0; i < GARBAGE_SIZE; i+=1)
848 AT_BISON_OPTION_POPDEFS
850 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
851 [glr-regr10.y: conflicts: 1 reduce/reduce
853 AT_COMPILE([glr-regr10])
855 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
860 ## ------------------------------------------------------------------------- ##
861 ## Undesirable destructors if user action cuts parse. ##
862 ## ------------------------------------------------------------------------- ##
864 AT_SETUP([Undesirable destructors if user action cuts parse])
866 AT_BISON_OPTION_PUSHDEFS
867 AT_DATA_GRAMMAR([glr-regr11.y],
873 static int destructors = 0;
878 %union { int dummy; }
880 %destructor { destructors += 1; } 'a'
885 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
886 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
892 ]AT_YYLEX_DEFINE(["a"])[
897 int exit_status = yyparse ();
898 if (destructors != 1)
900 fprintf (stderr, "Destructor calls: %d\n", destructors);
906 AT_BISON_OPTION_POPDEFS
908 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
909 [glr-regr11.y: conflicts: 1 reduce/reduce
911 AT_COMPILE([glr-regr11])
913 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
918 ## ------------------------------------------------------------------------- ##
919 ## Leaked semantic values if user action cuts parse. ##
920 ## ------------------------------------------------------------------------- ##
922 AT_SETUP([Leaked semantic values if user action cuts parse])
924 AT_BISON_OPTION_PUSHDEFS
925 AT_DATA_GRAMMAR([glr-regr12.y],
928 %union { int dummy; }
929 %token PARENT_RHS_AFTER
930 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
931 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
932 %destructor { merged_value = 0; } merged
933 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
938 static int merge (YYSTYPE, YYSTYPE);
941 static int parent_rhs_before_value = 0;
942 static int merged_value = 0;
943 static int parent_rhs_after_value = 0;
957 parent_rhs_after_value = 0;
962 parent_rhs_before merged PARENT_RHS_AFTER {
964 parent_rhs_before_value = 0;
966 parent_rhs_after_value = 0;
973 parent_rhs_before_value = 1;
982 | cut %merge<merge> {
993 merge (YYSTYPE s1, YYSTYPE s2)
996 char dummy = s1.dummy + s2.dummy;
1004 static int const input[] = { PARENT_RHS_AFTER, 0 };
1005 static size_t toknum;
1006 assert (toknum < sizeof input / sizeof *input);
1007 if (input[toknum] == PARENT_RHS_AFTER)
1008 parent_rhs_after_value = 1;
1009 return input[toknum++];
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: conflicts: 1 shift/reduce, 1 reduce/reduce
1039 AT_COMPILE([glr-regr12])
1041 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1046 ## ------------------------------------------------------------------------- ##
1047 ## Incorrect lookahead during deterministic GLR. See ##
1048 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1049 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1050 ## ------------------------------------------------------------------------- ##
1052 AT_SETUP([Incorrect lookahead during deterministic GLR])
1054 AT_BISON_OPTION_PUSHDEFS
1055 AT_DATA_GRAMMAR([glr-regr13.y],
1058 - Defaulted state with initial yychar: yychar == YYEMPTY.
1059 - Nondefaulted state: yychar != YYEMPTY.
1060 - Defaulted state after lookahead: yychar != YYEMPTY.
1061 - Defaulted state after shift: yychar == YYEMPTY.
1062 - User action changing the lookahead. */
1067 ]AT_YYERROR_DECLARE[
1069 static void print_lookahead (char const *);
1073 %union { char value; }
1074 %type <value> 'a' 'b'
1081 defstate_init defstate_shift 'b' change_lookahead 'a' {
1083 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1088 print_lookahead ("defstate_init <- empty string");
1092 nondefstate defstate_look 'a' {
1094 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1099 print_lookahead ("defstate_look <- empty string");
1104 print_lookahead ("nondefstate <- empty string");
1108 print_lookahead ("nondefstate <- 'b'");
1123 static char const input[] = "ab";
1124 static size_t toknum;
1125 assert (toknum < sizeof input);
1126 yylloc.first_line = yylloc.last_line = 1;
1127 yylloc.first_column = yylloc.last_column = toknum + 1;
1128 yylval.value = input[toknum] + 'A' - 'a';
1129 return input[toknum++];
1133 print_lookahead (char const *reduction)
1135 printf ("%s:\n yychar=", reduction);
1136 if (yychar == YYEMPTY)
1138 else if (yychar == YYEOF)
1142 printf ("'%c', yylval='", yychar);
1143 if (yylval.value > ' ')
1144 printf ("%c", yylval.value);
1145 printf ("', yylloc=(%d,%d),(%d,%d)",
1146 yylloc.first_line, yylloc.first_column,
1147 yylloc.last_line, yylloc.last_column);
1155 yychar = '#'; /* Not a token in the grammar. */
1160 AT_BISON_OPTION_POPDEFS
1162 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1163 AT_COMPILE([glr-regr13])
1165 AT_PARSER_CHECK([[./glr-regr13]], 0,
1166 [defstate_init <- empty string:
1168 nondefstate <- empty string:
1169 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1170 defstate_look <- empty string:
1171 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1172 defstate_shift <- nondefstate defstate_look 'a':
1174 start <- defstate_init defstate_shift 'b':
1181 ## ------------------------------------------------------------------------- ##
1182 ## Incorrect lookahead during nondeterministic GLR. ##
1183 ## ------------------------------------------------------------------------- ##
1185 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1187 AT_BISON_OPTION_PUSHDEFS
1188 AT_DATA_GRAMMAR([glr-regr14.y],
1191 - Conflicting actions (split-off parse, which copies lookahead need,
1192 which is necessarily yytrue) and nonconflicting actions (non-split-off
1193 parse) for nondefaulted state: yychar != YYEMPTY.
1194 - Merged deferred actions (lookahead need and RHS from different stack
1195 than the target state) and nonmerged deferred actions (same stack).
1196 - Defaulted state after lookahead: yychar != YYEMPTY.
1197 - Defaulted state after shift: yychar == YYEMPTY.
1198 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1199 seen the lookahead but current stack has not).
1200 - Exceeding stack capacity (stack explosion), and thus reallocating
1201 lookahead need array.
1202 Note that it does not seem possible to see the initial yychar value during
1203 nondeterministic operation since:
1204 - In order to preserve the initial yychar, only defaulted states may be
1206 - If only defaulted states are entered, there are no conflicts, so
1207 nondeterministic operation does not start. */
1209 %union { char value; }
1215 ]AT_YYERROR_DECLARE[
1217 static void print_lookahead (char const *);
1218 static char merge (union YYSTYPE, union YYSTYPE);
1222 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1229 merge 'c' stack_explosion {
1231 print_lookahead ("start <- merge 'c' stack_explosion");
1235 /* When merging the 2 deferred actions, the lookahead needs are different. */
1237 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1239 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1241 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1243 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1250 print_lookahead ("nonconflict1 <- empty string");
1255 print_lookahead ("nonconflict2 <- empty string");
1259 print_lookahead ("nonconflict2 <- 'a'");
1264 print_lookahead ("conflict <- empty string");
1269 print_lookahead ("defstate_look <- empty string");
1273 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1276 print_lookahead ("defstate_shift <- empty string");
1282 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1283 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1284 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1289 if (yychar != 'd' && yychar != YYEOF)
1291 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1298 if (yychar != 'd' && yychar != YYEOF)
1300 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1307 if (yychar != 'd' && yychar != YYEOF)
1309 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1315 if (yychar != YYEMPTY)
1318 "Found lookahead where shouldn't during stack explosion.\n");
1329 static char const input[] = "abcdddd";
1330 static size_t toknum;
1331 assert (toknum < sizeof input);
1332 yylloc.first_line = yylloc.last_line = 1;
1333 yylloc.first_column = yylloc.last_column = toknum + 1;
1334 yylval.value = input[toknum] + 'A' - 'a';
1335 return input[toknum++];
1339 print_lookahead (char const *reduction)
1341 printf ("%s:\n yychar=", reduction);
1342 if (yychar == YYEMPTY)
1344 else if (yychar == YYEOF)
1348 printf ("'%c', yylval='", yychar);
1349 if (yylval.value > ' ')
1350 printf ("%c", yylval.value);
1351 printf ("', yylloc=(%d,%d),(%d,%d)",
1352 yylloc.first_line, yylloc.first_column,
1353 yylloc.last_line, yylloc.last_column);
1359 merge (union YYSTYPE s1, union YYSTYPE s2)
1361 char dummy = s1.value + s2.value;
1368 yychar = '#'; /* Not a token in the grammar. */
1373 AT_BISON_OPTION_POPDEFS
1375 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1376 [glr-regr14.y: conflicts: 3 reduce/reduce
1378 AT_COMPILE([glr-regr14])
1380 AT_PARSER_CHECK([[./glr-regr14]], 0,
1381 [conflict <- empty string:
1382 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1383 defstate_look <- empty string:
1384 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1385 nonconflict2 <- empty string:
1386 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1387 defstate_shift <- empty string:
1389 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1391 start <- merge 'c' stack_explosion:
1398 ## ------------------------------------------------------------------------- ##
1399 ## Leaked semantic values when reporting ambiguity. ##
1400 ## ------------------------------------------------------------------------- ##
1402 AT_SETUP([Leaked semantic values when reporting ambiguity])
1404 AT_BISON_OPTION_PUSHDEFS
1405 AT_DATA_GRAMMAR([glr-regr15.y],
1408 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1411 # include <stdlib.h>
1412 ]AT_YYERROR_DECLARE[
1414 static int parent_rhs_before_value = 0;
1425 /* This stack must be merged into the other stacks *last* (added at the
1426 beginning of the semantic options list) so that yyparse will choose to clean
1427 it up rather than the tree for which some semantic actions have been
1428 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1429 those other trees are not cleaned up. */
1433 parent_rhs_before ambiguity {
1435 parent_rhs_before_value = 0;
1442 parent_rhs_before_value = 1;
1446 ambiguity: ambiguity1 | ambiguity2 ;
1457 int exit_status = yyparse () != 1;
1458 if (parent_rhs_before_value)
1460 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1466 AT_BISON_OPTION_POPDEFS
1468 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1469 [glr-regr15.y: conflicts: 2 reduce/reduce
1471 AT_COMPILE([glr-regr15])
1473 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1474 [syntax is ambiguous
1480 ## ------------------------------------------------------------------------- ##
1481 ## Leaked lookahead after nondeterministic parse syntax error. ##
1482 ## ------------------------------------------------------------------------- ##
1484 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1486 AT_BISON_OPTION_PUSHDEFS
1487 AT_DATA_GRAMMAR([glr-regr16.y],
1490 %destructor { lookahead_value = 0; } 'b'
1493 # include <stdlib.h>
1494 # include <assert.h>
1495 ]AT_YYERROR_DECLARE[
1497 static int lookahead_value = 0;
1503 start: alt1 'a' | alt2 'a' ;
1513 static char const input[] = "ab";
1514 static size_t toknum;
1515 assert (toknum < sizeof input);
1516 if (input[toknum] == 'b')
1517 lookahead_value = 1;
1518 return input[toknum++];
1524 int exit_status = yyparse () != 1;
1525 if (lookahead_value)
1527 fprintf (stderr, "Lookahead destructor not called.\n");
1533 AT_BISON_OPTION_POPDEFS
1535 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1536 [glr-regr16.y: conflicts: 1 reduce/reduce
1538 AT_COMPILE([glr-regr16])
1540 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1547 ## ------------------------------------------------------------------------- ##
1548 ## Uninitialized location when reporting ambiguity. ##
1549 ## ------------------------------------------------------------------------- ##
1551 AT_SETUP([Uninitialized location when reporting ambiguity])
1553 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1555 AT_DATA_GRAMMAR([glr-regr17.y],
1562 %union { int dummy; }
1565 ]AT_YYERROR_DECLARE[
1571 @$.first_column = 1;
1578 /* Tests the case of an empty RHS that has inherited the location of the
1579 previous nonterminal, which is unresolved. That location is reported as the
1580 last position of the ambiguity. */
1581 start: ambig1 empty1 | ambig2 empty2 ;
1583 /* Tests multiple levels of yyresolveLocations recursion. */
1584 ambig1: sub_ambig1 | sub_ambig2 ;
1585 ambig2: sub_ambig1 | sub_ambig2 ;
1587 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1588 has inherited the initial location. The empty RHS's location is reported as
1589 the first position in the ambiguity. */
1590 sub_ambig1: empty1 'a' 'b' ;
1591 sub_ambig2: empty2 'a' 'b' ;
1596 # include <assert.h>
1600 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1602 static char const input[] = "ab";
1603 static size_t toknum;
1604 assert (toknum < sizeof input);
1606 llocp->first_line = llocp->last_line = 2;
1607 llocp->first_column = toknum + 1;
1608 llocp->last_column = llocp->first_column + 1;
1609 return input[toknum++];
1615 return yyparse () != 1;
1618 AT_BISON_OPTION_POPDEFS
1620 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1621 [glr-regr17.y: conflicts: 3 reduce/reduce
1623 AT_COMPILE([glr-regr17])
1625 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1626 [1.1-2.2: syntax is ambiguous
1632 ## -------------------------------------------------------------##
1633 ## Missed %merge type warnings when LHS type is declared later. ##
1634 ## -------------------------------------------------------------##
1636 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1638 AT_BISON_OPTION_PUSHDEFS
1639 AT_DATA_GRAMMAR([glr-regr18.y],
1644 ]AT_YYERROR_DECLARE[
1656 sym1: sym2 %merge<merge> { $$ = $1; } ;
1657 sym2: sym3 %merge<merge> { $$ = $1; } ;
1658 sym3: %merge<merge> { $$ = 0; } ;
1673 AT_BISON_OPTION_POPDEFS
1675 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1676 [glr-regr18.y:26.18-24: result type clash on merge function 'merge': <type2> != <type1>
1677 glr-regr18.y:25.18-24: previous declaration
1678 glr-regr18.y:27.13-19: result type clash on merge function 'merge': <type3> != <type2>
1679 glr-regr18.y:26.18-24: previous declaration
1685 ## ------------------- ##
1686 ## Ambiguity reports. ##
1687 ## ------------------- ##
1689 AT_SETUP([Ambiguity reports])
1691 AT_BISON_OPTION_PUSHDEFS
1692 AT_DATA_GRAMMAR([input.y],
1697 ]AT_YYERROR_DECLARE[
1712 ]AT_YYLEX_DEFINE(["abc"])[
1718 return !!yyparse ();
1721 AT_BISON_OPTION_POPDEFS
1723 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1724 [input.y: conflicts: 1 reduce/reduce
1728 AT_PARSER_CHECK([[./input]], 1, [],
1731 Reading a token: Next token is token 'a' ()
1732 Shifting token 'a' ()
1734 Reading a token: Next token is token 'b' ()
1735 Shifting token 'b' ()
1737 Reducing stack 0 by rule 3 (line 25):
1741 Reading a token: Next token is token 'c' ()
1742 Shifting token 'c' ()
1744 Reducing stack 0 by rule 4 (line 26):
1747 Reading a token: Now at end of input.
1748 Stack 0 Entering state 7
1749 Now at end of input.
1750 Splitting off stack 1 from 0.
1751 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1752 Stack 1 Entering state 2
1753 Now at end of input.
1754 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1755 Merging stack 0 into stack 1.
1756 Stack 1 Entering state 2
1757 Now at end of input.
1758 Removing dead stacks.
1759 Rename stack 1 -> 0.
1760 On stack 0, shifting token $end ()
1761 Stack 0 now in state #5
1764 start -> <Rule 1, tokens 1 .. 3>
1771 start -> <Rule 2, tokens 1 .. 3>
1778 Cleanup: popping token $end ()
1779 Cleanup: popping unresolved nterm start ()
1780 Cleanup: popping nterm d ()
1781 Cleanup: popping token 'c' ()
1782 Cleanup: popping nterm b ()
1783 Cleanup: popping token 'a' ()