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")))
201 int res = yyparse ();
202 if (argc == 2 && fclose (input))
207 AT_BISON_OPTION_POPDEFS
209 AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [],
210 [[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
212 AT_COMPILE([glr-regr2a])
214 AT_DATA([input1.txt],
215 [[s VARIABLE_1 t v x q
217 AT_PARSER_CHECK([[./glr-regr2a input1.txt]], 0,
218 [[Variable: 'VARIABLE_1'
221 AT_DATA([input2.txt],
222 [[s VARIABLE_1 , ANOTHER_VARIABLE_2 t e
224 AT_PARSER_CHECK([[./glr-regr2a input2.txt]],
226 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
229 AT_DATA([input3.txt],
232 AT_PARSER_CHECK([[./glr-regr2a input3.txt]], 0,
233 [[Variable: 'VARIABLE_3'
239 ## ------------------------------------------------------------ ##
240 ## Improper merging of GLR delayed action sets ##
241 ## ------------------------------------------------------------ ##
243 AT_SETUP([Improper merging of GLR delayed action sets])
245 AT_BISON_OPTION_PUSHDEFS
246 AT_DATA_GRAMMAR([glr-regr3.y],
247 [[/* Regression Test: Improper merging of GLR delayed action sets. */
248 /* Reported by M. Rosien */
256 static int MergeRule (int x0, int x1);
260 #define RULE(x) (1 << (x))
267 %token P1 P2 T1 T2 T3 T4 O1 O2
271 S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
274 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
277 NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
278 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
281 NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
282 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
285 NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
286 | NT2 { $$ = RULE(8); } %merge<MergeRule>
287 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
290 NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
293 NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
294 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
300 MergeRule (int x0, int x1)
306 FILE *input = YY_NULL;
308 int P[] = { P1, P2 };
309 int O[] = { O1, O2 };
310 int T[] = { T1, T2, T3, T4 };
315 assert (!feof (stdin));
316 if (fscanf (input, "%2s", inp) == EOF)
320 case 'p': return P[inp[1] - '1'];
321 case 't': return T[inp[1] - '1'];
322 case 'o': return O[inp[1] - '1'];
328 main(int argc, char* argv[])
331 if (argc == 2 && !(input = fopen (argv[1], "r")))
333 int res = yyparse ();
334 if (argc == 2 && fclose (input))
339 AT_BISON_OPTION_POPDEFS
341 AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
342 [[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
343 glr-regr3.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
345 AT_COMPILE([glr-regr3])
348 [[p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2
350 AT_PARSER_CHECK([[./glr-regr3 input.txt]],
358 ## ------------------------------------------------------------------------- ##
359 ## Duplicate representation of merged trees. See ##
360 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
361 ## ------------------------------------------------------------------------- ##
363 AT_SETUP([Duplicate representation of merged trees])
365 AT_BISON_OPTION_PUSHDEFS
366 AT_DATA_GRAMMAR([glr-regr4.y],
368 %union { char *ptr; }
369 %type <ptr> S A A1 A2 B
376 static char *merge (YYSTYPE, YYSTYPE);
377 static char *make_value (char const *, char const *);
380 static char *ptrs[100];
381 static char **ptrs_next = ptrs;
386 tree: S { printf ("%s\n", $1); } ;
389 A %merge<merge> { $$ = make_value ("S", $1); }
390 | B %merge<merge> { $$ = make_value ("S", $1); }
394 A1 %merge<merge> { $$ = make_value ("A", $1); }
395 | A2 %merge<merge> { $$ = make_value ("A", $1); }
398 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
399 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
400 B: 'a' { $$ = make_value ("B", "'a'"); } ;
404 ]AT_YYLEX_DEFINE(["a"])[
409 int status = yyparse ();
410 while (ptrs_next != ptrs)
416 make_value (char const *parent, char const *child)
418 char const format[] = "%s <- %s";
419 char *value = *ptrs_next++ =
420 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
421 sprintf (value, format, parent, child);
426 merge (YYSTYPE s1, YYSTYPE s2)
428 char const format[] = "merge{ %s and %s }";
429 char *value = *ptrs_next++ =
430 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
431 sprintf (value, format, s1.ptr, s2.ptr);
435 AT_BISON_OPTION_POPDEFS
437 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
438 [[glr-regr4.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
440 AT_COMPILE([glr-regr4])
442 AT_PARSER_CHECK([[./glr-regr4]], 0,
443 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
449 ## -------------------------------------------------------------------------- ##
450 ## User destructor for unresolved GLR semantic value. See ##
451 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
452 ## -------------------------------------------------------------------------- ##
454 AT_SETUP([User destructor for unresolved GLR semantic value])
456 AT_BISON_OPTION_PUSHDEFS
457 AT_DATA_GRAMMAR([glr-regr5.y],
464 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
468 %union { int value; }
472 if ($$ != MAGIC_VALUE)
474 fprintf (stderr, "Bad destructor call.\n");
482 'a' { $$ = MAGIC_VALUE; }
483 | 'a' { $$ = MAGIC_VALUE; }
487 ]AT_YYLEX_DEFINE(["a"])[
492 return yyparse () != 1;
495 AT_BISON_OPTION_POPDEFS
497 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
498 [[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
500 AT_COMPILE([glr-regr5])
502 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
509 ## -------------------------------------------------------------------------- ##
510 ## User destructor after an error during a split parse. See ##
511 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
512 ## -------------------------------------------------------------------------- ##
514 AT_SETUP([User destructor after an error during a split parse])
516 AT_BISON_OPTION_PUSHDEFS
517 AT_DATA_GRAMMAR([glr-regr6.y],
527 %union { int value; }
531 printf ("Destructor called.\n");
540 ]AT_YYLEX_DEFINE(["a"])[
544 return yyparse () != 1;
547 AT_BISON_OPTION_POPDEFS
549 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
550 [[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
552 AT_COMPILE([glr-regr6])
554 AT_PARSER_CHECK([[./glr-regr6]], 0,
563 ## ------------------------------------------------------------------------- ##
564 ## Duplicated user destructor for lookahead. See ##
565 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
566 ## ------------------------------------------------------------------------- ##
568 AT_SETUP([Duplicated user destructor for lookahead])
570 AT_BISON_OPTION_PUSHDEFS
571 AT_DATA_GRAMMAR([glr-regr7.y],
578 #define YYSTACKEXPANDABLE 0
579 typedef struct count_node {
581 struct count_node *prev;
583 static count_node *tail;
587 %union { count_node *node; }
592 fprintf (stderr, "Destructor called on same value twice.\n");
610 yylval.node = (count_node*) malloc (sizeof *yylval.node);
613 fprintf (stderr, "Test inconclusive.\n");
616 yylval.node->count = 0;
617 yylval.node->prev = tail;
626 int status = yyparse ();
629 count_node *prev = tail->prev;
636 AT_BISON_OPTION_POPDEFS
638 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
639 [[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
641 AT_COMPILE([glr-regr7])
643 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
650 ## ------------------------------------------------------------------------- ##
651 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
652 ## report by Claudia Hermann. ##
653 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
654 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
655 ## ------------------------------------------------------------------------- ##
657 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
659 AT_BISON_OPTION_PUSHDEFS
660 AT_DATA_GRAMMAR([glr-regr8.y],
678 PortClause : T_PORT InterfaceDeclaration T_PORT
679 { printf("%d/%d - %d/%d - %d/%d\n",
680 @1.first_column, @1.last_column,
681 @2.first_column, @2.last_column,
682 @3.first_column, @3.last_column); }
685 InterfaceDeclaration : OptConstantWord %dprec 1
686 | OptSignalWord %dprec 2
689 OptConstantWord : /* empty */
693 OptSignalWord : /* empty */
694 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
711 yylloc.first_column = 1;
712 yylloc.last_column = 9;
715 yylloc.first_column = 13;
716 yylloc.last_column = 17;
730 AT_BISON_OPTION_POPDEFS
732 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
733 [[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
735 AT_COMPILE([glr-regr8])
737 AT_PARSER_CHECK([[./glr-regr8]], 0,
746 ## ------------------------------------------------------------------------- ##
747 ## No users destructors if stack 0 deleted. See ##
748 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
749 ## ------------------------------------------------------------------------- ##
751 AT_SETUP([No users destructors if stack 0 deleted])
753 AT_BISON_OPTION_PUSHDEFS
754 AT_DATA_GRAMMAR([glr-regr9.y],
761 # define YYSTACKEXPANDABLE 0
762 static int tokens = 0;
763 static int destructors = 0;
768 %union { int dummy; }
778 ambig0 'a' { destructors += 2; USE ($2); }
779 | ambig1 start { destructors += 1; }
780 | ambig2 start { destructors += 1; }
801 exit_status = yyparse ();
802 if (tokens != destructors)
804 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
810 AT_BISON_OPTION_POPDEFS
812 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
813 [[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
815 AT_COMPILE([glr-regr9])
817 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
824 ## ------------------------------------------------------------------------- ##
825 ## Corrupted semantic options if user action cuts parse. ##
826 ## ------------------------------------------------------------------------- ##
828 AT_SETUP([Corrupted semantic options if user action cuts parse])
830 AT_BISON_OPTION_PUSHDEFS
831 AT_DATA_GRAMMAR([glr-regr10.y],
838 #define GARBAGE_SIZE 50
839 static char garbage[GARBAGE_SIZE];
843 %union { char *ptr; }
849 %dprec 2 { $$ = garbage; YYACCEPT; }
850 | %dprec 1 { $$ = garbage; YYACCEPT; }
861 for (i = 0; i < GARBAGE_SIZE; i+=1)
866 AT_BISON_OPTION_POPDEFS
868 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
869 [[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
871 AT_COMPILE([glr-regr10])
873 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
878 ## ------------------------------------------------------------------------- ##
879 ## Undesirable destructors if user action cuts parse. ##
880 ## ------------------------------------------------------------------------- ##
882 AT_SETUP([Undesirable destructors if user action cuts parse])
884 AT_BISON_OPTION_PUSHDEFS
885 AT_DATA_GRAMMAR([glr-regr11.y],
891 static int destructors = 0;
896 %union { int dummy; }
898 %destructor { destructors += 1; } 'a'
903 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
904 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
910 ]AT_YYLEX_DEFINE(["a"])[
915 int exit_status = yyparse ();
916 if (destructors != 1)
918 fprintf (stderr, "Destructor calls: %d\n", destructors);
924 AT_BISON_OPTION_POPDEFS
926 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
927 [[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
929 AT_COMPILE([glr-regr11])
931 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
936 ## ------------------------------------------------------------------------- ##
937 ## Leaked semantic values if user action cuts parse. ##
938 ## ------------------------------------------------------------------------- ##
940 AT_SETUP([Leaked semantic values if user action cuts parse])
942 AT_BISON_OPTION_PUSHDEFS
943 AT_DATA_GRAMMAR([glr-regr12.y],
946 %union { int dummy; }
947 %token PARENT_RHS_AFTER
948 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
949 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
950 %destructor { merged_value = 0; } merged
951 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
956 static int merge (YYSTYPE, YYSTYPE);
959 static int parent_rhs_before_value = 0;
960 static int merged_value = 0;
961 static int parent_rhs_after_value = 0;
975 parent_rhs_after_value = 0;
980 parent_rhs_before merged PARENT_RHS_AFTER {
982 parent_rhs_before_value = 0;
984 parent_rhs_after_value = 0;
991 parent_rhs_before_value = 1;
1000 | cut %merge<merge> {
1006 cut: { YYACCEPT; } ;
1011 merge (YYSTYPE s1, YYSTYPE s2)
1014 char dummy = s1.dummy + s2.dummy;
1019 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1020 [if (res == PARENT_RHS_AFTER)
1021 parent_rhs_after_value = 1;])[
1026 int exit_status = yyparse ();
1027 if (parent_rhs_before_value)
1029 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1034 fprintf (stderr, "`merged' destructor not called.\n");
1037 if (parent_rhs_after_value)
1039 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1045 AT_BISON_OPTION_POPDEFS
1047 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1048 [[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1049 glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1051 AT_COMPILE([glr-regr12])
1053 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1058 ## ------------------------------------------------------------------------- ##
1059 ## Incorrect lookahead during deterministic GLR. See ##
1060 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1061 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1062 ## ------------------------------------------------------------------------- ##
1064 AT_SETUP([Incorrect lookahead during deterministic GLR])
1066 AT_BISON_OPTION_PUSHDEFS
1067 AT_DATA_GRAMMAR([glr-regr13.y],
1070 - Defaulted state with initial yychar: yychar == YYEMPTY.
1071 - Nondefaulted state: yychar != YYEMPTY.
1072 - Defaulted state after lookahead: yychar != YYEMPTY.
1073 - Defaulted state after shift: yychar == YYEMPTY.
1074 - User action changing the lookahead. */
1079 ]AT_YYERROR_DECLARE[
1081 static void print_lookahead (char const *);
1085 %union { char value; }
1086 %type <value> 'a' 'b'
1093 defstate_init defstate_shift 'b' change_lookahead 'a' {
1095 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1100 print_lookahead ("defstate_init <- empty string");
1104 nondefstate defstate_look 'a' {
1106 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1111 print_lookahead ("defstate_look <- empty string");
1116 print_lookahead ("nondefstate <- empty string");
1120 print_lookahead ("nondefstate <- 'b'");
1132 ]AT_YYLEX_DEFINE(["ab"],
1133 [yylval.value = res + 'A' - 'a'])[
1136 print_lookahead (char const *reduction)
1138 printf ("%s:\n yychar=", reduction);
1139 if (yychar == YYEMPTY)
1141 else if (yychar == YYEOF)
1145 printf ("'%c', yylval='", yychar);
1146 if (yylval.value > ' ')
1147 printf ("%c", yylval.value);
1148 printf ("', yylloc=(%d,%d),(%d,%d)",
1149 yylloc.first_line, yylloc.first_column,
1150 yylloc.last_line, yylloc.last_column);
1158 yychar = '#'; /* Not a token in the grammar. */
1163 AT_BISON_OPTION_POPDEFS
1165 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1166 AT_COMPILE([glr-regr13])
1168 AT_PARSER_CHECK([[./glr-regr13]], 0,
1169 [defstate_init <- empty string:
1171 nondefstate <- empty string:
1172 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1173 defstate_look <- empty string:
1174 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1175 defstate_shift <- nondefstate defstate_look 'a':
1177 start <- defstate_init defstate_shift 'b':
1184 ## ------------------------------------------------------------------------- ##
1185 ## Incorrect lookahead during nondeterministic GLR. ##
1186 ## ------------------------------------------------------------------------- ##
1188 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1190 AT_BISON_OPTION_PUSHDEFS
1191 AT_DATA_GRAMMAR([glr-regr14.y],
1194 - Conflicting actions (split-off parse, which copies lookahead need,
1195 which is necessarily yytrue) and nonconflicting actions (non-split-off
1196 parse) for nondefaulted state: yychar != YYEMPTY.
1197 - Merged deferred actions (lookahead need and RHS from different stack
1198 than the target state) and nonmerged deferred actions (same stack).
1199 - Defaulted state after lookahead: yychar != YYEMPTY.
1200 - Defaulted state after shift: yychar == YYEMPTY.
1201 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1202 seen the lookahead but current stack has not).
1203 - Exceeding stack capacity (stack explosion), and thus reallocating
1204 lookahead need array.
1205 Note that it does not seem possible to see the initial yychar value during
1206 nondeterministic operation since:
1207 - In order to preserve the initial yychar, only defaulted states may be
1209 - If only defaulted states are entered, there are no conflicts, so
1210 nondeterministic operation does not start. */
1212 %union { char value; }
1218 ]AT_YYERROR_DECLARE[
1220 static void print_lookahead (char const *);
1221 static char merge (union YYSTYPE, union YYSTYPE);
1225 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1232 merge 'c' stack_explosion {
1234 print_lookahead ("start <- merge 'c' stack_explosion");
1238 /* When merging the 2 deferred actions, the lookahead needs are different. */
1240 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1242 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1244 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1246 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1253 print_lookahead ("nonconflict1 <- empty string");
1258 print_lookahead ("nonconflict2 <- empty string");
1262 print_lookahead ("nonconflict2 <- 'a'");
1267 print_lookahead ("conflict <- empty string");
1272 print_lookahead ("defstate_look <- empty string");
1276 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1279 print_lookahead ("defstate_shift <- empty string");
1285 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1286 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1287 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1292 if (yychar != 'd' && yychar != YYEOF)
1294 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1301 if (yychar != 'd' && yychar != YYEOF)
1303 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1310 if (yychar != 'd' && yychar != YYEOF)
1312 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1318 if (yychar != YYEMPTY)
1321 "Found lookahead where shouldn't during stack explosion.\n");
1332 static char const input[] = "abcdddd";
1333 static size_t toknum;
1334 assert (toknum < sizeof input);
1335 yylloc.first_line = yylloc.last_line = 1;
1336 yylloc.first_column = yylloc.last_column = toknum + 1;
1337 yylval.value = input[toknum] + 'A' - 'a';
1338 return input[toknum++];
1342 print_lookahead (char const *reduction)
1344 printf ("%s:\n yychar=", reduction);
1345 if (yychar == YYEMPTY)
1347 else if (yychar == YYEOF)
1351 printf ("'%c', yylval='", yychar);
1352 if (yylval.value > ' ')
1353 printf ("%c", yylval.value);
1354 printf ("', yylloc=(%d,%d),(%d,%d)",
1355 yylloc.first_line, yylloc.first_column,
1356 yylloc.last_line, yylloc.last_column);
1362 merge (union YYSTYPE s1, union YYSTYPE s2)
1364 char dummy = s1.value + s2.value;
1371 yychar = '#'; /* Not a token in the grammar. */
1376 AT_BISON_OPTION_POPDEFS
1378 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1379 [[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1381 AT_COMPILE([glr-regr14])
1383 AT_PARSER_CHECK([[./glr-regr14]], 0,
1384 [conflict <- empty string:
1385 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1386 defstate_look <- empty string:
1387 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1388 nonconflict2 <- empty string:
1389 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1390 defstate_shift <- empty string:
1392 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1394 start <- merge 'c' stack_explosion:
1401 ## ------------------------------------------------------------------------- ##
1402 ## Leaked semantic values when reporting ambiguity. ##
1403 ## ------------------------------------------------------------------------- ##
1405 AT_SETUP([Leaked semantic values when reporting ambiguity])
1407 AT_BISON_OPTION_PUSHDEFS
1408 AT_DATA_GRAMMAR([glr-regr15.y],
1411 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1414 # include <stdlib.h>
1415 ]AT_YYERROR_DECLARE[
1417 static int parent_rhs_before_value = 0;
1428 /* This stack must be merged into the other stacks *last* (added at the
1429 beginning of the semantic options list) so that yyparse will choose to clean
1430 it up rather than the tree for which some semantic actions have been
1431 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1432 those other trees are not cleaned up. */
1436 parent_rhs_before ambiguity {
1438 parent_rhs_before_value = 0;
1445 parent_rhs_before_value = 1;
1449 ambiguity: ambiguity1 | ambiguity2 ;
1460 int exit_status = yyparse () != 1;
1461 if (parent_rhs_before_value)
1463 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1469 AT_BISON_OPTION_POPDEFS
1471 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1472 [[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1474 AT_COMPILE([glr-regr15])
1476 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1477 [syntax is ambiguous
1483 ## ------------------------------------------------------------------------- ##
1484 ## Leaked lookahead after nondeterministic parse syntax error. ##
1485 ## ------------------------------------------------------------------------- ##
1487 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1489 AT_BISON_OPTION_PUSHDEFS
1490 AT_DATA_GRAMMAR([glr-regr16.y],
1493 %destructor { lookahead_value = 0; } 'b'
1496 # include <stdlib.h>
1497 # include <assert.h>
1498 ]AT_YYERROR_DECLARE[
1500 static int lookahead_value = 0;
1506 start: alt1 'a' | alt2 'a' ;
1513 ]AT_YYLEX_DEFINE(["ab"],
1515 lookahead_value = 1])[
1520 int exit_status = yyparse () != 1;
1521 if (lookahead_value)
1523 fprintf (stderr, "Lookahead destructor not called.\n");
1529 AT_BISON_OPTION_POPDEFS
1531 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1532 [[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1534 AT_COMPILE([glr-regr16])
1536 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1543 ## ------------------------------------------------------------------------- ##
1544 ## Uninitialized location when reporting ambiguity. ##
1545 ## ------------------------------------------------------------------------- ##
1547 AT_SETUP([Uninitialized location when reporting ambiguity])
1549 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1551 AT_DATA_GRAMMAR([glr-regr17.y],
1558 %union { int dummy; }
1561 ]AT_YYERROR_DECLARE[
1567 /* Tests the case of an empty RHS that has inherited the location of the
1568 previous nonterminal, which is unresolved. That location is reported as the
1569 last position of the ambiguity. */
1570 start: ambig1 empty1 | ambig2 empty2 ;
1572 /* Tests multiple levels of yyresolveLocations recursion. */
1573 ambig1: sub_ambig1 | sub_ambig2 ;
1574 ambig2: sub_ambig1 | sub_ambig2 ;
1576 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1577 has inherited the initial location. The empty RHS's location is reported as
1578 the first position in the ambiguity. */
1579 sub_ambig1: empty1 'a' 'b' ;
1580 sub_ambig2: empty2 'a' 'b' ;
1585 # include <assert.h>
1589 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1591 static char const input[] = "ab";
1592 static size_t toknum;
1593 assert (toknum < sizeof input);
1595 llocp->first_line = llocp->last_line = 2;
1596 llocp->first_column = toknum + 1;
1597 llocp->last_column = llocp->first_column + 1;
1598 return input[toknum++];
1604 return yyparse () != 1;
1607 AT_BISON_OPTION_POPDEFS
1609 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1610 [[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1612 AT_COMPILE([glr-regr17])
1614 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1615 [1.1-2.2: syntax is ambiguous
1621 ## -------------------------------------------------------------##
1622 ## Missed %merge type warnings when LHS type is declared later. ##
1623 ## -------------------------------------------------------------##
1625 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1627 AT_BISON_OPTION_PUSHDEFS
1628 AT_DATA_GRAMMAR([glr-regr18.y],
1633 ]AT_YYERROR_DECLARE[
1645 sym1: sym2 %merge<merge> { $$ = $1; } ;
1646 sym2: sym3 %merge<merge> { $$ = $1; } ;
1647 sym3: %merge<merge> { $$ = 0; } ;
1662 AT_BISON_OPTION_POPDEFS
1664 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1665 [[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
1666 glr-regr18.y:25.18-24: previous declaration
1667 glr-regr18.y:27.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
1668 glr-regr18.y:26.18-24: previous declaration
1674 ## ------------------- ##
1675 ## Ambiguity reports. ##
1676 ## ------------------- ##
1678 AT_SETUP([Ambiguity reports])
1680 AT_BISON_OPTION_PUSHDEFS
1681 AT_DATA_GRAMMAR([input.y],
1686 ]AT_YYERROR_DECLARE[
1701 ]AT_YYLEX_DEFINE(["abc"])[
1707 return !!yyparse ();
1710 AT_BISON_OPTION_POPDEFS
1712 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1713 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1717 AT_PARSER_CHECK([[./input]], 1, [],
1720 Reading a token: Next token is token 'a' ()
1721 Shifting token 'a' ()
1723 Reading a token: Next token is token 'b' ()
1724 Shifting token 'b' ()
1726 Reducing stack 0 by rule 3 (line 25):
1730 Reading a token: Next token is token 'c' ()
1731 Shifting token 'c' ()
1733 Reducing stack 0 by rule 4 (line 26):
1736 Reading a token: Now at end of input.
1737 Stack 0 Entering state 7
1738 Now at end of input.
1739 Splitting off stack 1 from 0.
1740 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1741 Stack 1 Entering state 2
1742 Now at end of input.
1743 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1744 Merging stack 0 into stack 1.
1745 Stack 1 Entering state 2
1746 Now at end of input.
1747 Removing dead stacks.
1748 Rename stack 1 -> 0.
1749 On stack 0, shifting token $end ()
1750 Stack 0 now in state #5
1753 start -> <Rule 1, tokens 1 .. 3>
1760 start -> <Rule 2, tokens 1 .. 3>
1767 Cleanup: popping token $end ()
1768 Cleanup: popping unresolved nterm start ()
1769 Cleanup: popping nterm d ()
1770 Cleanup: popping token 'c' ()
1771 Cleanup: popping nterm b ()
1772 Cleanup: popping token 'a' ()