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: 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)
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: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
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: warning: 1 shift/reduce conflict [-Wconflicts-sr]
335 glr-regr3.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
337 AT_COMPILE([glr-regr3])
340 [[p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2
342 AT_PARSER_CHECK([[./glr-regr3 input.txt]],
350 ## ------------------------------------------------------------------------- ##
351 ## Duplicate representation of merged trees. See ##
352 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
353 ## ------------------------------------------------------------------------- ##
355 AT_SETUP([Duplicate representation of merged trees])
357 AT_BISON_OPTION_PUSHDEFS
358 AT_DATA_GRAMMAR([glr-regr4.y],
360 %union { char *ptr; }
361 %type <ptr> S A A1 A2 B
368 static char *merge (YYSTYPE, YYSTYPE);
369 static char *make_value (char const *, char const *);
372 static char *ptrs[100];
373 static char **ptrs_next = ptrs;
378 tree: S { printf ("%s\n", $1); } ;
381 A %merge<merge> { $$ = make_value ("S", $1); }
382 | B %merge<merge> { $$ = make_value ("S", $1); }
386 A1 %merge<merge> { $$ = make_value ("A", $1); }
387 | A2 %merge<merge> { $$ = make_value ("A", $1); }
390 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
391 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
392 B: 'a' { $$ = make_value ("B", "'a'"); } ;
396 ]AT_YYLEX_DEFINE(["a"])[
401 int status = yyparse ();
402 while (ptrs_next != ptrs)
408 make_value (char const *parent, char const *child)
410 char const format[] = "%s <- %s";
411 char *value = *ptrs_next++ =
412 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
413 sprintf (value, format, parent, child);
418 merge (YYSTYPE s1, YYSTYPE s2)
420 char const format[] = "merge{ %s and %s }";
421 char *value = *ptrs_next++ =
422 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
423 sprintf (value, format, s1.ptr, s2.ptr);
427 AT_BISON_OPTION_POPDEFS
429 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
430 [[glr-regr4.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
432 AT_COMPILE([glr-regr4])
434 AT_PARSER_CHECK([[./glr-regr4]], 0,
435 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
441 ## -------------------------------------------------------------------------- ##
442 ## User destructor for unresolved GLR semantic value. See ##
443 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
444 ## -------------------------------------------------------------------------- ##
446 AT_SETUP([User destructor for unresolved GLR semantic value])
448 AT_BISON_OPTION_PUSHDEFS
449 AT_DATA_GRAMMAR([glr-regr5.y],
456 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
460 %union { int value; }
464 if ($$ != MAGIC_VALUE)
466 fprintf (stderr, "Bad destructor call.\n");
474 'a' { $$ = MAGIC_VALUE; }
475 | 'a' { $$ = MAGIC_VALUE; }
479 ]AT_YYLEX_DEFINE(["a"])[
484 return yyparse () != 1;
487 AT_BISON_OPTION_POPDEFS
489 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
490 [[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
492 AT_COMPILE([glr-regr5])
494 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
501 ## -------------------------------------------------------------------------- ##
502 ## User destructor after an error during a split parse. See ##
503 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
504 ## -------------------------------------------------------------------------- ##
506 AT_SETUP([User destructor after an error during a split parse])
508 AT_BISON_OPTION_PUSHDEFS
509 AT_DATA_GRAMMAR([glr-regr6.y],
519 %union { int value; }
523 printf ("Destructor called.\n");
532 ]AT_YYLEX_DEFINE(["a"])[
536 return yyparse () != 1;
539 AT_BISON_OPTION_POPDEFS
541 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
542 [[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
544 AT_COMPILE([glr-regr6])
546 AT_PARSER_CHECK([[./glr-regr6]], 0,
555 ## ------------------------------------------------------------------------- ##
556 ## Duplicated user destructor for lookahead. See ##
557 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
558 ## ------------------------------------------------------------------------- ##
560 AT_SETUP([Duplicated user destructor for lookahead])
562 AT_BISON_OPTION_PUSHDEFS
563 AT_DATA_GRAMMAR([glr-regr7.y],
570 #define YYSTACKEXPANDABLE 0
571 typedef struct count_node {
573 struct count_node *prev;
575 static count_node *tail;
579 %union { count_node *node; }
584 fprintf (stderr, "Destructor called on same value twice.\n");
602 yylval.node = (count_node*) malloc (sizeof *yylval.node);
605 fprintf (stderr, "Test inconclusive.\n");
608 yylval.node->count = 0;
609 yylval.node->prev = tail;
618 int status = yyparse ();
621 count_node *prev = tail->prev;
628 AT_BISON_OPTION_POPDEFS
630 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
631 [[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
633 AT_COMPILE([glr-regr7])
635 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
642 ## ------------------------------------------------------------------------- ##
643 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
644 ## report by Claudia Hermann. ##
645 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
646 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
647 ## ------------------------------------------------------------------------- ##
649 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
651 AT_BISON_OPTION_PUSHDEFS
652 AT_DATA_GRAMMAR([glr-regr8.y],
670 PortClause : T_PORT InterfaceDeclaration T_PORT
671 { printf("%d/%d - %d/%d - %d/%d\n",
672 @1.first_column, @1.last_column,
673 @2.first_column, @2.last_column,
674 @3.first_column, @3.last_column); }
677 InterfaceDeclaration : OptConstantWord %dprec 1
678 | OptSignalWord %dprec 2
681 OptConstantWord : /* empty */
685 OptSignalWord : /* empty */
686 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
703 yylloc.first_column = 1;
704 yylloc.last_column = 9;
707 yylloc.first_column = 13;
708 yylloc.last_column = 17;
722 AT_BISON_OPTION_POPDEFS
724 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
725 [[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
727 AT_COMPILE([glr-regr8])
729 AT_PARSER_CHECK([[./glr-regr8]], 0,
738 ## ------------------------------------------------------------------------- ##
739 ## No users destructors if stack 0 deleted. See ##
740 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
741 ## ------------------------------------------------------------------------- ##
743 AT_SETUP([No users destructors if stack 0 deleted])
745 AT_BISON_OPTION_PUSHDEFS
746 AT_DATA_GRAMMAR([glr-regr9.y],
753 # define YYSTACKEXPANDABLE 0
754 static int tokens = 0;
755 static int destructors = 0;
760 %union { int dummy; }
770 ambig0 'a' { destructors += 2; USE ($2); }
771 | ambig1 start { destructors += 1; }
772 | ambig2 start { destructors += 1; }
793 exit_status = yyparse ();
794 if (tokens != destructors)
796 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
802 AT_BISON_OPTION_POPDEFS
804 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
805 [[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
807 AT_COMPILE([glr-regr9])
809 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
816 ## ------------------------------------------------------------------------- ##
817 ## Corrupted semantic options if user action cuts parse. ##
818 ## ------------------------------------------------------------------------- ##
820 AT_SETUP([Corrupted semantic options if user action cuts parse])
822 AT_BISON_OPTION_PUSHDEFS
823 AT_DATA_GRAMMAR([glr-regr10.y],
830 #define GARBAGE_SIZE 50
831 static char garbage[GARBAGE_SIZE];
835 %union { char *ptr; }
841 %dprec 2 { $$ = garbage; YYACCEPT; }
842 | %dprec 1 { $$ = garbage; YYACCEPT; }
853 for (i = 0; i < GARBAGE_SIZE; i+=1)
858 AT_BISON_OPTION_POPDEFS
860 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
861 [[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
863 AT_COMPILE([glr-regr10])
865 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
870 ## ------------------------------------------------------------------------- ##
871 ## Undesirable destructors if user action cuts parse. ##
872 ## ------------------------------------------------------------------------- ##
874 AT_SETUP([Undesirable destructors if user action cuts parse])
876 AT_BISON_OPTION_PUSHDEFS
877 AT_DATA_GRAMMAR([glr-regr11.y],
883 static int destructors = 0;
888 %union { int dummy; }
890 %destructor { destructors += 1; } 'a'
895 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
896 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
902 ]AT_YYLEX_DEFINE(["a"])[
907 int exit_status = yyparse ();
908 if (destructors != 1)
910 fprintf (stderr, "Destructor calls: %d\n", destructors);
916 AT_BISON_OPTION_POPDEFS
918 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
919 [[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
921 AT_COMPILE([glr-regr11])
923 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
928 ## ------------------------------------------------------------------------- ##
929 ## Leaked semantic values if user action cuts parse. ##
930 ## ------------------------------------------------------------------------- ##
932 AT_SETUP([Leaked semantic values if user action cuts parse])
934 AT_BISON_OPTION_PUSHDEFS
935 AT_DATA_GRAMMAR([glr-regr12.y],
938 %union { int dummy; }
939 %token PARENT_RHS_AFTER
940 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
941 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
942 %destructor { merged_value = 0; } merged
943 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
948 static int merge (YYSTYPE, YYSTYPE);
951 static int parent_rhs_before_value = 0;
952 static int merged_value = 0;
953 static int parent_rhs_after_value = 0;
967 parent_rhs_after_value = 0;
972 parent_rhs_before merged PARENT_RHS_AFTER {
974 parent_rhs_before_value = 0;
976 parent_rhs_after_value = 0;
983 parent_rhs_before_value = 1;
992 | cut %merge<merge> {
1003 merge (YYSTYPE s1, YYSTYPE s2)
1006 char dummy = s1.dummy + s2.dummy;
1011 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1012 [if (res == PARENT_RHS_AFTER)
1013 parent_rhs_after_value = 1;])[
1018 int exit_status = yyparse ();
1019 if (parent_rhs_before_value)
1021 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1026 fprintf (stderr, "`merged' destructor not called.\n");
1029 if (parent_rhs_after_value)
1031 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1037 AT_BISON_OPTION_POPDEFS
1039 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1040 [[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1041 glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1043 AT_COMPILE([glr-regr12])
1045 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1050 ## ------------------------------------------------------------------------- ##
1051 ## Incorrect lookahead during deterministic GLR. See ##
1052 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1053 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1054 ## ------------------------------------------------------------------------- ##
1056 AT_SETUP([Incorrect lookahead during deterministic GLR])
1058 AT_BISON_OPTION_PUSHDEFS
1059 AT_DATA_GRAMMAR([glr-regr13.y],
1062 - Defaulted state with initial yychar: yychar == YYEMPTY.
1063 - Nondefaulted state: yychar != YYEMPTY.
1064 - Defaulted state after lookahead: yychar != YYEMPTY.
1065 - Defaulted state after shift: yychar == YYEMPTY.
1066 - User action changing the lookahead. */
1071 ]AT_YYERROR_DECLARE[
1073 static void print_lookahead (char const *);
1077 %union { char value; }
1078 %type <value> 'a' 'b'
1085 defstate_init defstate_shift 'b' change_lookahead 'a' {
1087 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1092 print_lookahead ("defstate_init <- empty string");
1096 nondefstate defstate_look 'a' {
1098 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1103 print_lookahead ("defstate_look <- empty string");
1108 print_lookahead ("nondefstate <- empty string");
1112 print_lookahead ("nondefstate <- 'b'");
1124 ]AT_YYLEX_DEFINE(["ab"],
1125 [yylval.value = res + 'A' - 'a'])[
1128 print_lookahead (char const *reduction)
1130 printf ("%s:\n yychar=", reduction);
1131 if (yychar == YYEMPTY)
1133 else if (yychar == YYEOF)
1137 printf ("'%c', yylval='", yychar);
1138 if (yylval.value > ' ')
1139 printf ("%c", yylval.value);
1140 printf ("', yylloc=(%d,%d),(%d,%d)",
1141 yylloc.first_line, yylloc.first_column,
1142 yylloc.last_line, yylloc.last_column);
1150 yychar = '#'; /* Not a token in the grammar. */
1155 AT_BISON_OPTION_POPDEFS
1157 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1158 AT_COMPILE([glr-regr13])
1160 AT_PARSER_CHECK([[./glr-regr13]], 0,
1161 [defstate_init <- empty string:
1163 nondefstate <- empty string:
1164 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1165 defstate_look <- empty string:
1166 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1167 defstate_shift <- nondefstate defstate_look 'a':
1169 start <- defstate_init defstate_shift 'b':
1176 ## ------------------------------------------------------------------------- ##
1177 ## Incorrect lookahead during nondeterministic GLR. ##
1178 ## ------------------------------------------------------------------------- ##
1180 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1182 AT_BISON_OPTION_PUSHDEFS
1183 AT_DATA_GRAMMAR([glr-regr14.y],
1186 - Conflicting actions (split-off parse, which copies lookahead need,
1187 which is necessarily yytrue) and nonconflicting actions (non-split-off
1188 parse) for nondefaulted state: yychar != YYEMPTY.
1189 - Merged deferred actions (lookahead need and RHS from different stack
1190 than the target state) and nonmerged deferred actions (same stack).
1191 - Defaulted state after lookahead: yychar != YYEMPTY.
1192 - Defaulted state after shift: yychar == YYEMPTY.
1193 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1194 seen the lookahead but current stack has not).
1195 - Exceeding stack capacity (stack explosion), and thus reallocating
1196 lookahead need array.
1197 Note that it does not seem possible to see the initial yychar value during
1198 nondeterministic operation since:
1199 - In order to preserve the initial yychar, only defaulted states may be
1201 - If only defaulted states are entered, there are no conflicts, so
1202 nondeterministic operation does not start. */
1204 %union { char value; }
1210 ]AT_YYERROR_DECLARE[
1212 static void print_lookahead (char const *);
1213 static char merge (union YYSTYPE, union YYSTYPE);
1217 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1224 merge 'c' stack_explosion {
1226 print_lookahead ("start <- merge 'c' stack_explosion");
1230 /* When merging the 2 deferred actions, the lookahead needs are different. */
1232 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1234 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1236 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1238 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1245 print_lookahead ("nonconflict1 <- empty string");
1250 print_lookahead ("nonconflict2 <- empty string");
1254 print_lookahead ("nonconflict2 <- 'a'");
1259 print_lookahead ("conflict <- empty string");
1264 print_lookahead ("defstate_look <- empty string");
1268 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1271 print_lookahead ("defstate_shift <- empty string");
1277 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1278 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1279 | alt3 stack_explosion %merge<merge> { $$ = $2; }
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");
1302 if (yychar != 'd' && yychar != YYEOF)
1304 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1310 if (yychar != YYEMPTY)
1313 "Found lookahead where shouldn't during stack explosion.\n");
1324 static char const input[] = "abcdddd";
1325 static size_t toknum;
1326 assert (toknum < sizeof input);
1327 yylloc.first_line = yylloc.last_line = 1;
1328 yylloc.first_column = yylloc.last_column = toknum + 1;
1329 yylval.value = input[toknum] + 'A' - 'a';
1330 return input[toknum++];
1334 print_lookahead (char const *reduction)
1336 printf ("%s:\n yychar=", reduction);
1337 if (yychar == YYEMPTY)
1339 else if (yychar == YYEOF)
1343 printf ("'%c', yylval='", yychar);
1344 if (yylval.value > ' ')
1345 printf ("%c", yylval.value);
1346 printf ("', yylloc=(%d,%d),(%d,%d)",
1347 yylloc.first_line, yylloc.first_column,
1348 yylloc.last_line, yylloc.last_column);
1354 merge (union YYSTYPE s1, union YYSTYPE s2)
1356 char dummy = s1.value + s2.value;
1363 yychar = '#'; /* Not a token in the grammar. */
1368 AT_BISON_OPTION_POPDEFS
1370 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1371 [[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1373 AT_COMPILE([glr-regr14])
1375 AT_PARSER_CHECK([[./glr-regr14]], 0,
1376 [conflict <- empty string:
1377 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1378 defstate_look <- empty string:
1379 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1380 nonconflict2 <- empty string:
1381 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1382 defstate_shift <- empty string:
1384 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1386 start <- merge 'c' stack_explosion:
1393 ## ------------------------------------------------------------------------- ##
1394 ## Leaked semantic values when reporting ambiguity. ##
1395 ## ------------------------------------------------------------------------- ##
1397 AT_SETUP([Leaked semantic values when reporting ambiguity])
1399 AT_BISON_OPTION_PUSHDEFS
1400 AT_DATA_GRAMMAR([glr-regr15.y],
1403 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1406 # include <stdlib.h>
1407 ]AT_YYERROR_DECLARE[
1409 static int parent_rhs_before_value = 0;
1420 /* This stack must be merged into the other stacks *last* (added at the
1421 beginning of the semantic options list) so that yyparse will choose to clean
1422 it up rather than the tree for which some semantic actions have been
1423 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1424 those other trees are not cleaned up. */
1428 parent_rhs_before ambiguity {
1430 parent_rhs_before_value = 0;
1437 parent_rhs_before_value = 1;
1441 ambiguity: ambiguity1 | ambiguity2 ;
1452 int exit_status = yyparse () != 1;
1453 if (parent_rhs_before_value)
1455 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1461 AT_BISON_OPTION_POPDEFS
1463 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1464 [[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1466 AT_COMPILE([glr-regr15])
1468 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1469 [syntax is ambiguous
1475 ## ------------------------------------------------------------------------- ##
1476 ## Leaked lookahead after nondeterministic parse syntax error. ##
1477 ## ------------------------------------------------------------------------- ##
1479 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1481 AT_BISON_OPTION_PUSHDEFS
1482 AT_DATA_GRAMMAR([glr-regr16.y],
1485 %destructor { lookahead_value = 0; } 'b'
1488 # include <stdlib.h>
1489 # include <assert.h>
1490 ]AT_YYERROR_DECLARE[
1492 static int lookahead_value = 0;
1498 start: alt1 'a' | alt2 'a' ;
1505 ]AT_YYLEX_DEFINE(["ab"],
1507 lookahead_value = 1])[
1512 int exit_status = yyparse () != 1;
1513 if (lookahead_value)
1515 fprintf (stderr, "Lookahead destructor not called.\n");
1521 AT_BISON_OPTION_POPDEFS
1523 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1524 [[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1526 AT_COMPILE([glr-regr16])
1528 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1535 ## ------------------------------------------------------------------------- ##
1536 ## Uninitialized location when reporting ambiguity. ##
1537 ## ------------------------------------------------------------------------- ##
1539 AT_SETUP([Uninitialized location when reporting ambiguity])
1541 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1543 AT_DATA_GRAMMAR([glr-regr17.y],
1550 %union { int dummy; }
1553 ]AT_YYERROR_DECLARE[
1559 /* Tests the case of an empty RHS that has inherited the location of the
1560 previous nonterminal, which is unresolved. That location is reported as the
1561 last position of the ambiguity. */
1562 start: ambig1 empty1 | ambig2 empty2 ;
1564 /* Tests multiple levels of yyresolveLocations recursion. */
1565 ambig1: sub_ambig1 | sub_ambig2 ;
1566 ambig2: sub_ambig1 | sub_ambig2 ;
1568 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1569 has inherited the initial location. The empty RHS's location is reported as
1570 the first position in the ambiguity. */
1571 sub_ambig1: empty1 'a' 'b' ;
1572 sub_ambig2: empty2 'a' 'b' ;
1577 # include <assert.h>
1581 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1583 static char const input[] = "ab";
1584 static size_t toknum;
1585 assert (toknum < sizeof input);
1587 llocp->first_line = llocp->last_line = 2;
1588 llocp->first_column = toknum + 1;
1589 llocp->last_column = llocp->first_column + 1;
1590 return input[toknum++];
1596 return yyparse () != 1;
1599 AT_BISON_OPTION_POPDEFS
1601 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1602 [[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1604 AT_COMPILE([glr-regr17])
1606 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1607 [1.1-2.2: syntax is ambiguous
1613 ## -------------------------------------------------------------##
1614 ## Missed %merge type warnings when LHS type is declared later. ##
1615 ## -------------------------------------------------------------##
1617 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1619 AT_BISON_OPTION_PUSHDEFS
1620 AT_DATA_GRAMMAR([glr-regr18.y],
1625 ]AT_YYERROR_DECLARE[
1637 sym1: sym2 %merge<merge> { $$ = $1; } ;
1638 sym2: sym3 %merge<merge> { $$ = $1; } ;
1639 sym3: %merge<merge> { $$ = 0; } ;
1654 AT_BISON_OPTION_POPDEFS
1656 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1657 [[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
1658 glr-regr18.y:25.18-24: previous declaration
1659 glr-regr18.y:27.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
1660 glr-regr18.y:26.18-24: previous declaration
1666 ## ------------------- ##
1667 ## Ambiguity reports. ##
1668 ## ------------------- ##
1670 AT_SETUP([Ambiguity reports])
1672 AT_BISON_OPTION_PUSHDEFS
1673 AT_DATA_GRAMMAR([input.y],
1678 ]AT_YYERROR_DECLARE[
1693 ]AT_YYLEX_DEFINE(["abc"])[
1699 return !!yyparse ();
1702 AT_BISON_OPTION_POPDEFS
1704 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1705 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1709 AT_PARSER_CHECK([[./input]], 1, [],
1712 Reading a token: Next token is token 'a' ()
1713 Shifting token 'a' ()
1715 Reading a token: Next token is token 'b' ()
1716 Shifting token 'b' ()
1718 Reducing stack 0 by rule 3 (line 25):
1722 Reading a token: Next token is token 'c' ()
1723 Shifting token 'c' ()
1725 Reducing stack 0 by rule 4 (line 26):
1728 Reading a token: Now at end of input.
1729 Stack 0 Entering state 7
1730 Now at end of input.
1731 Splitting off stack 1 from 0.
1732 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1733 Stack 1 Entering state 2
1734 Now at end of input.
1735 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1736 Merging stack 0 into stack 1.
1737 Stack 1 Entering state 2
1738 Now at end of input.
1739 Removing dead stacks.
1740 Rename stack 1 -> 0.
1741 On stack 0, shifting token $end ()
1742 Stack 0 now in state #5
1745 start -> <Rule 1, tokens 1 .. 3>
1752 start -> <Rule 2, tokens 1 .. 3>
1759 Cleanup: popping token $end ()
1760 Cleanup: popping unresolved nterm start ()
1761 Cleanup: popping nterm d ()
1762 Cleanup: popping token 'c' ()
1763 Cleanup: popping nterm b ()
1764 Cleanup: popping token 'a' ()