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 = YY_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)
200 if (argc == 2 && !(input = fopen (argv[1], "r")))
203 if (argc == 2 && fclose (input))
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_DATA([input1.txt],
216 [[s VARIABLE_1 t v x q
218 AT_PARSER_CHECK([[./glr-regr2a input1.txt]], 0,
219 [[Variable: 'VARIABLE_1'
222 AT_DATA([input2.txt],
223 [[s VARIABLE_1 , ANOTHER_VARIABLE_2 t e
225 AT_PARSER_CHECK([[./glr-regr2a input2.txt]],
227 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
230 AT_DATA([input3.txt],
233 AT_PARSER_CHECK([[./glr-regr2a input3.txt]], 0,
234 [[Variable: 'VARIABLE_3'
240 ## --------------------------------------------- ##
241 ## Improper merging of GLR delayed action sets. ##
242 ## --------------------------------------------- ##
244 AT_SETUP([Improper merging of GLR delayed action sets])
246 AT_BISON_OPTION_PUSHDEFS
247 AT_DATA_GRAMMAR([glr-regr3.y],
248 [[/* Regression Test: Improper merging of GLR delayed action sets. */
249 /* Reported by M. Rosien */
257 static int MergeRule (int x0, int x1);
261 #define RULE(x) (1 << (x))
268 %token P1 P2 T1 T2 T3 T4 O1 O2
272 S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
275 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
278 NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
279 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
282 NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
283 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
286 NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
287 | NT2 { $$ = RULE(8); } %merge<MergeRule>
288 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
291 NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
294 NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
295 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
301 MergeRule (int x0, int x1)
307 FILE *input = YY_NULL;
309 int P[] = { P1, P2 };
310 int O[] = { O1, O2 };
311 int T[] = { T1, T2, T3, T4 };
316 assert (!feof (stdin));
317 if (fscanf (input, "%2s", inp) == EOF)
321 case 'p': return P[inp[1] - '1'];
322 case 't': return T[inp[1] - '1'];
323 case 'o': return O[inp[1] - '1'];
329 main(int argc, char* argv[])
333 if (argc == 2 && !(input = fopen (argv[1], "r")))
336 if (argc == 2 && fclose (input))
341 AT_BISON_OPTION_POPDEFS
343 AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
344 [[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
345 glr-regr3.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
347 AT_COMPILE([glr-regr3])
350 [[p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2
352 AT_PARSER_CHECK([[./glr-regr3 input.txt]],
360 ## ---------------------------------------------------------------------- ##
361 ## Duplicate representation of merged trees. See ##
362 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
363 ## ---------------------------------------------------------------------- ##
365 AT_SETUP([Duplicate representation of merged trees])
367 AT_BISON_OPTION_PUSHDEFS
368 AT_DATA_GRAMMAR([glr-regr4.y],
370 %union { char *ptr; }
371 %type <ptr> S A A1 A2 B
378 static char *merge (YYSTYPE, YYSTYPE);
379 static char *make_value (char const *, char const *);
382 static char *ptrs[100];
383 static char **ptrs_next = ptrs;
388 tree: S { printf ("%s\n", $1); } ;
391 A %merge<merge> { $$ = make_value ("S", $1); }
392 | B %merge<merge> { $$ = make_value ("S", $1); }
396 A1 %merge<merge> { $$ = make_value ("A", $1); }
397 | A2 %merge<merge> { $$ = make_value ("A", $1); }
400 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
401 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
402 B: 'a' { $$ = make_value ("B", "'a'"); } ;
406 ]AT_YYLEX_DEFINE(["a"])[
411 int status = yyparse ();
412 while (ptrs_next != ptrs)
418 make_value (char const *parent, char const *child)
420 char const format[] = "%s <- %s";
421 char *value = *ptrs_next++ =
422 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
423 sprintf (value, format, parent, child);
428 merge (YYSTYPE s1, YYSTYPE s2)
430 char const format[] = "merge{ %s and %s }";
431 char *value = *ptrs_next++ =
432 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
433 sprintf (value, format, s1.ptr, s2.ptr);
437 AT_BISON_OPTION_POPDEFS
439 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
440 [[glr-regr4.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
442 AT_COMPILE([glr-regr4])
444 AT_PARSER_CHECK([[./glr-regr4]], 0,
445 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
451 ## ------------------------------------------------------------------------- ##
452 ## User destructor for unresolved GLR semantic value. See ##
453 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
454 ## ------------------------------------------------------------------------- ##
456 AT_SETUP([User destructor for unresolved GLR semantic value])
458 AT_BISON_OPTION_PUSHDEFS
459 AT_DATA_GRAMMAR([glr-regr5.y],
466 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
470 %union { int value; }
474 if ($$ != MAGIC_VALUE)
476 fprintf (stderr, "Bad destructor call.\n");
484 'a' { $$ = MAGIC_VALUE; }
485 | 'a' { $$ = MAGIC_VALUE; }
489 ]AT_YYLEX_DEFINE(["a"])[
494 return yyparse () != 1;
497 AT_BISON_OPTION_POPDEFS
499 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
500 [[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
502 AT_COMPILE([glr-regr5])
504 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
511 ## ------------------------------------------------------------------------- ##
512 ## User destructor after an error during a split parse. See ##
513 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
514 ## ------------------------------------------------------------------------- ##
516 AT_SETUP([User destructor after an error during a split parse])
518 AT_BISON_OPTION_PUSHDEFS
519 AT_DATA_GRAMMAR([glr-regr6.y],
529 %union { int value; }
533 printf ("Destructor called.\n");
542 ]AT_YYLEX_DEFINE(["a"])[
546 return yyparse () != 1;
549 AT_BISON_OPTION_POPDEFS
551 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
552 [[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
554 AT_COMPILE([glr-regr6])
556 AT_PARSER_CHECK([[./glr-regr6]], 0,
565 ## ------------------------------------------------------------------------- ##
566 ## Duplicated user destructor for lookahead. See ##
567 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
568 ## ------------------------------------------------------------------------- ##
570 AT_SETUP([Duplicated user destructor for lookahead])
572 AT_BISON_OPTION_PUSHDEFS
573 AT_DATA_GRAMMAR([glr-regr7.y],
580 #define YYSTACKEXPANDABLE 0
581 typedef struct count_node {
583 struct count_node *prev;
585 static count_node *tail;
589 %union { count_node *node; }
594 fprintf (stderr, "Destructor called on same value twice.\n");
612 yylval.node = (count_node*) malloc (sizeof *yylval.node);
615 fprintf (stderr, "Test inconclusive.\n");
618 yylval.node->count = 0;
619 yylval.node->prev = tail;
628 int status = yyparse ();
631 count_node *prev = tail->prev;
638 AT_BISON_OPTION_POPDEFS
640 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
641 [[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
643 AT_COMPILE([glr-regr7])
645 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
652 ## ------------------------------------------------------------------------- ##
653 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
654 ## report by Claudia Hermann. ##
655 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
656 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
657 ## ------------------------------------------------------------------------- ##
659 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
661 AT_BISON_OPTION_PUSHDEFS
662 AT_DATA_GRAMMAR([glr-regr8.y],
680 PortClause : T_PORT InterfaceDeclaration T_PORT
681 { printf("%d/%d - %d/%d - %d/%d\n",
682 @1.first_column, @1.last_column,
683 @2.first_column, @2.last_column,
684 @3.first_column, @3.last_column); }
687 InterfaceDeclaration : OptConstantWord %dprec 1
688 | OptSignalWord %dprec 2
691 OptConstantWord : /* empty */
695 OptSignalWord : /* empty */
696 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
713 yylloc.first_column = 1;
714 yylloc.last_column = 9;
717 yylloc.first_column = 13;
718 yylloc.last_column = 17;
732 AT_BISON_OPTION_POPDEFS
734 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
735 [[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
737 AT_COMPILE([glr-regr8])
739 AT_PARSER_CHECK([[./glr-regr8]], 0,
748 ## ------------------------------------------------------------------------- ##
749 ## No users destructors if stack 0 deleted. See ##
750 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
751 ## ------------------------------------------------------------------------- ##
753 AT_SETUP([No users destructors if stack 0 deleted])
755 AT_BISON_OPTION_PUSHDEFS
756 AT_DATA_GRAMMAR([glr-regr9.y],
763 # define YYSTACKEXPANDABLE 0
764 static int tokens = 0;
765 static int destructors = 0;
770 %union { int dummy; }
780 ambig0 'a' { destructors += 2; USE ($2); }
781 | ambig1 start { destructors += 1; }
782 | ambig2 start { destructors += 1; }
803 exit_status = yyparse ();
804 if (tokens != destructors)
806 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
812 AT_BISON_OPTION_POPDEFS
814 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
815 [[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
817 AT_COMPILE([glr-regr9])
819 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
826 ## ------------------------------------------------------ ##
827 ## Corrupted semantic options if user action cuts parse. ##
828 ## ------------------------------------------------------ ##
830 AT_SETUP([Corrupted semantic options if user action cuts parse])
832 AT_BISON_OPTION_PUSHDEFS
833 AT_DATA_GRAMMAR([glr-regr10.y],
840 #define GARBAGE_SIZE 50
841 static char garbage[GARBAGE_SIZE];
845 %union { char *ptr; }
851 %dprec 2 { $$ = garbage; YYACCEPT; }
852 | %dprec 1 { $$ = garbage; YYACCEPT; }
863 for (i = 0; i < GARBAGE_SIZE; i+=1)
868 AT_BISON_OPTION_POPDEFS
870 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
871 [[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
873 AT_COMPILE([glr-regr10])
875 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
880 ## --------------------------------------------------- ##
881 ## Undesirable destructors if user action cuts parse. ##
882 ## --------------------------------------------------- ##
884 AT_SETUP([Undesirable destructors if user action cuts parse])
886 AT_BISON_OPTION_PUSHDEFS
887 AT_DATA_GRAMMAR([glr-regr11.y],
893 static int destructors = 0;
898 %union { int dummy; }
900 %destructor { destructors += 1; } 'a'
905 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
906 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
912 ]AT_YYLEX_DEFINE(["a"])[
917 int exit_status = yyparse ();
918 if (destructors != 1)
920 fprintf (stderr, "Destructor calls: %d\n", destructors);
926 AT_BISON_OPTION_POPDEFS
928 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
929 [[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
931 AT_COMPILE([glr-regr11])
933 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
938 ## -------------------------------------------------- ##
939 ## Leaked semantic values if user action cuts parse. ##
940 ## -------------------------------------------------- ##
942 AT_SETUP([Leaked semantic values if user action cuts parse])
944 AT_BISON_OPTION_PUSHDEFS
945 AT_DATA_GRAMMAR([glr-regr12.y],
948 %union { int dummy; }
949 %token PARENT_RHS_AFTER
950 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
951 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
952 %destructor { merged_value = 0; } merged
953 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
958 static int merge (YYSTYPE, YYSTYPE);
961 static int parent_rhs_before_value = 0;
962 static int merged_value = 0;
963 static int parent_rhs_after_value = 0;
977 parent_rhs_after_value = 0;
982 parent_rhs_before merged PARENT_RHS_AFTER {
984 parent_rhs_before_value = 0;
986 parent_rhs_after_value = 0;
993 parent_rhs_before_value = 1;
1002 | cut %merge<merge> {
1008 cut: { YYACCEPT; } ;
1013 merge (YYSTYPE s1, YYSTYPE s2)
1016 char dummy = s1.dummy + s2.dummy;
1021 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1022 [if (res == PARENT_RHS_AFTER)
1023 parent_rhs_after_value = 1;])[
1028 int exit_status = yyparse ();
1029 if (parent_rhs_before_value)
1031 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1036 fprintf (stderr, "`merged' destructor not called.\n");
1039 if (parent_rhs_after_value)
1041 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1047 AT_BISON_OPTION_POPDEFS
1049 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1050 [[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1051 glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1053 AT_COMPILE([glr-regr12])
1055 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1060 ## ------------------------------------------------------------------------- ##
1061 ## Incorrect lookahead during deterministic GLR. See ##
1062 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1063 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1064 ## ------------------------------------------------------------------------- ##
1066 AT_SETUP([Incorrect lookahead during deterministic GLR])
1068 AT_BISON_OPTION_PUSHDEFS
1069 AT_DATA_GRAMMAR([glr-regr13.y],
1072 - Defaulted state with initial yychar: yychar == YYEMPTY.
1073 - Nondefaulted state: yychar != YYEMPTY.
1074 - Defaulted state after lookahead: yychar != YYEMPTY.
1075 - Defaulted state after shift: yychar == YYEMPTY.
1076 - User action changing the lookahead. */
1081 ]AT_YYERROR_DECLARE[
1083 static void print_lookahead (char const *);
1087 %union { char value; }
1088 %type <value> 'a' 'b'
1095 defstate_init defstate_shift 'b' change_lookahead 'a' {
1097 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1102 print_lookahead ("defstate_init <- empty string");
1106 nondefstate defstate_look 'a' {
1108 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1113 print_lookahead ("defstate_look <- empty string");
1118 print_lookahead ("nondefstate <- empty string");
1122 print_lookahead ("nondefstate <- 'b'");
1134 ]AT_YYLEX_DEFINE(["ab"],
1135 [yylval.value = res + 'A' - 'a'])[
1138 print_lookahead (char const *reduction)
1140 printf ("%s:\n yychar=", reduction);
1141 if (yychar == YYEMPTY)
1143 else if (yychar == YYEOF)
1147 printf ("'%c', yylval='", yychar);
1148 if (yylval.value > ' ')
1149 printf ("%c", yylval.value);
1150 printf ("', yylloc=(%d,%d),(%d,%d)",
1151 yylloc.first_line, yylloc.first_column,
1152 yylloc.last_line, yylloc.last_column);
1160 yychar = '#'; /* Not a token in the grammar. */
1165 AT_BISON_OPTION_POPDEFS
1167 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1168 AT_COMPILE([glr-regr13])
1170 AT_PARSER_CHECK([[./glr-regr13]], 0,
1171 [defstate_init <- empty string:
1173 nondefstate <- empty string:
1174 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1175 defstate_look <- empty string:
1176 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1177 defstate_shift <- nondefstate defstate_look 'a':
1179 start <- defstate_init defstate_shift 'b':
1186 ## ------------------------------------------------- ##
1187 ## Incorrect lookahead during nondeterministic GLR. ##
1188 ## ------------------------------------------------- ##
1190 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1192 AT_BISON_OPTION_PUSHDEFS
1193 AT_DATA_GRAMMAR([glr-regr14.y],
1196 - Conflicting actions (split-off parse, which copies lookahead need,
1197 which is necessarily yytrue) and nonconflicting actions (non-split-off
1198 parse) for nondefaulted state: yychar != YYEMPTY.
1199 - Merged deferred actions (lookahead need and RHS from different stack
1200 than the target state) and nonmerged deferred actions (same stack).
1201 - Defaulted state after lookahead: yychar != YYEMPTY.
1202 - Defaulted state after shift: yychar == YYEMPTY.
1203 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1204 seen the lookahead but current stack has not).
1205 - Exceeding stack capacity (stack explosion), and thus reallocating
1206 lookahead need array.
1207 Note that it does not seem possible to see the initial yychar value during
1208 nondeterministic operation since:
1209 - In order to preserve the initial yychar, only defaulted states may be
1211 - If only defaulted states are entered, there are no conflicts, so
1212 nondeterministic operation does not start. */
1214 %union { char value; }
1220 ]AT_YYERROR_DECLARE[
1222 static void print_lookahead (char const *);
1223 static char merge (union YYSTYPE, union YYSTYPE);
1227 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1234 merge 'c' stack_explosion {
1236 print_lookahead ("start <- merge 'c' stack_explosion");
1240 /* When merging the 2 deferred actions, the lookahead needs are different. */
1242 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1244 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1246 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1248 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1255 print_lookahead ("nonconflict1 <- empty string");
1260 print_lookahead ("nonconflict2 <- empty string");
1264 print_lookahead ("nonconflict2 <- 'a'");
1269 print_lookahead ("conflict <- empty string");
1274 print_lookahead ("defstate_look <- empty string");
1278 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1281 print_lookahead ("defstate_shift <- empty string");
1287 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1288 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1289 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1294 if (yychar != 'd' && yychar != YYEOF)
1296 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1303 if (yychar != 'd' && yychar != YYEOF)
1305 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1312 if (yychar != 'd' && yychar != YYEOF)
1314 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1320 if (yychar != YYEMPTY)
1323 "Found lookahead where shouldn't during stack explosion.\n");
1334 static char const input[] = "abcdddd";
1335 static size_t toknum;
1336 assert (toknum < sizeof input);
1337 yylloc.first_line = yylloc.last_line = 1;
1338 yylloc.first_column = yylloc.last_column = toknum + 1;
1339 yylval.value = input[toknum] + 'A' - 'a';
1340 return input[toknum++];
1344 print_lookahead (char const *reduction)
1346 printf ("%s:\n yychar=", reduction);
1347 if (yychar == YYEMPTY)
1349 else if (yychar == YYEOF)
1353 printf ("'%c', yylval='", yychar);
1354 if (yylval.value > ' ')
1355 printf ("%c", yylval.value);
1356 printf ("', yylloc=(%d,%d),(%d,%d)",
1357 yylloc.first_line, yylloc.first_column,
1358 yylloc.last_line, yylloc.last_column);
1364 merge (union YYSTYPE s1, union YYSTYPE s2)
1366 char dummy = s1.value + s2.value;
1373 yychar = '#'; /* Not a token in the grammar. */
1378 AT_BISON_OPTION_POPDEFS
1380 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1381 [[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1383 AT_COMPILE([glr-regr14])
1385 AT_PARSER_CHECK([[./glr-regr14]], 0,
1386 [conflict <- empty string:
1387 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1388 defstate_look <- empty string:
1389 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1390 nonconflict2 <- empty string:
1391 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1392 defstate_shift <- empty string:
1394 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1396 start <- merge 'c' stack_explosion:
1403 ## ------------------------------------------------- ##
1404 ## Leaked semantic values when reporting ambiguity. ##
1405 ## ------------------------------------------------- ##
1407 AT_SETUP([Leaked semantic values when reporting ambiguity])
1409 AT_BISON_OPTION_PUSHDEFS
1410 AT_DATA_GRAMMAR([glr-regr15.y],
1413 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1416 # include <stdlib.h>
1417 ]AT_YYERROR_DECLARE[
1419 static int parent_rhs_before_value = 0;
1430 /* This stack must be merged into the other stacks *last* (added at the
1431 beginning of the semantic options list) so that yyparse will choose to clean
1432 it up rather than the tree for which some semantic actions have been
1433 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1434 those other trees are not cleaned up. */
1438 parent_rhs_before ambiguity {
1440 parent_rhs_before_value = 0;
1447 parent_rhs_before_value = 1;
1451 ambiguity: ambiguity1 | ambiguity2 ;
1462 int exit_status = yyparse () != 1;
1463 if (parent_rhs_before_value)
1465 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1471 AT_BISON_OPTION_POPDEFS
1473 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1474 [[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1476 AT_COMPILE([glr-regr15])
1478 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1479 [syntax is ambiguous
1485 ## ------------------------------------------------------------ ##
1486 ## Leaked lookahead after nondeterministic parse syntax error. ##
1487 ## ------------------------------------------------------------ ##
1489 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1491 AT_BISON_OPTION_PUSHDEFS
1492 AT_DATA_GRAMMAR([glr-regr16.y],
1495 %destructor { lookahead_value = 0; } 'b'
1498 # include <stdlib.h>
1499 # include <assert.h>
1500 ]AT_YYERROR_DECLARE[
1502 static int lookahead_value = 0;
1508 start: alt1 'a' | alt2 'a' ;
1515 ]AT_YYLEX_DEFINE(["ab"],
1517 lookahead_value = 1])[
1522 int exit_status = yyparse () != 1;
1523 if (lookahead_value)
1525 fprintf (stderr, "Lookahead destructor not called.\n");
1531 AT_BISON_OPTION_POPDEFS
1533 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1534 [[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1536 AT_COMPILE([glr-regr16])
1538 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1545 ## ------------------------------------------------- ##
1546 ## Uninitialized location when reporting ambiguity. ##
1547 ## ------------------------------------------------- ##
1549 AT_SETUP([Uninitialized location when reporting ambiguity])
1551 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1553 AT_DATA_GRAMMAR([glr-regr17.y],
1560 %union { int dummy; }
1563 ]AT_YYERROR_DECLARE[
1569 /* Tests the case of an empty RHS that has inherited the location of the
1570 previous nonterminal, which is unresolved. That location is reported as the
1571 last position of the ambiguity. */
1572 start: ambig1 empty1 | ambig2 empty2 ;
1574 /* Tests multiple levels of yyresolveLocations recursion. */
1575 ambig1: sub_ambig1 | sub_ambig2 ;
1576 ambig2: sub_ambig1 | sub_ambig2 ;
1578 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1579 has inherited the initial location. The empty RHS's location is reported as
1580 the first position in the ambiguity. */
1581 sub_ambig1: empty1 'a' 'b' ;
1582 sub_ambig2: empty2 'a' 'b' ;
1587 # include <assert.h>
1591 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1593 static char const input[] = "ab";
1594 static size_t toknum;
1595 assert (toknum < sizeof input);
1597 llocp->first_line = llocp->last_line = 2;
1598 llocp->first_column = toknum + 1;
1599 llocp->last_column = llocp->first_column + 1;
1600 return input[toknum++];
1606 return yyparse () != 1;
1609 AT_BISON_OPTION_POPDEFS
1611 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1612 [[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1614 AT_COMPILE([glr-regr17])
1616 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1617 [1.1-2.2: syntax is ambiguous
1623 ## ------------------------------------------------------------- ##
1624 ## Missed %merge type warnings when LHS type is declared later. ##
1625 ## ------------------------------------------------------------- ##
1627 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1629 AT_BISON_OPTION_PUSHDEFS
1630 AT_DATA_GRAMMAR([glr-regr18.y],
1635 ]AT_YYERROR_DECLARE[
1647 sym1: sym2 %merge<merge> { $$ = $1; } ;
1648 sym2: sym3 %merge<merge> { $$ = $1; } ;
1649 sym3: %merge<merge> { $$ = 0; } ;
1664 AT_BISON_OPTION_POPDEFS
1666 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1667 [[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
1668 glr-regr18.y:25.18-24: previous declaration
1669 glr-regr18.y:27.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
1670 glr-regr18.y:26.18-24: previous declaration
1676 ## ------------------- ##
1677 ## Ambiguity reports. ##
1678 ## ------------------- ##
1680 AT_SETUP([Ambiguity reports])
1682 AT_BISON_OPTION_PUSHDEFS
1683 AT_DATA_GRAMMAR([input.y],
1688 ]AT_YYERROR_DECLARE[
1703 ]AT_YYLEX_DEFINE(["abc"])[
1709 return !!yyparse ();
1712 AT_BISON_OPTION_POPDEFS
1714 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1715 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1719 AT_PARSER_CHECK([[./input]], 1, [],
1722 Reading a token: Next token is token 'a' ()
1723 Shifting token 'a' ()
1725 Reading a token: Next token is token 'b' ()
1726 Shifting token 'b' ()
1728 Reducing stack 0 by rule 3 (line 25):
1732 Reading a token: Next token is token 'c' ()
1733 Shifting token 'c' ()
1735 Reducing stack 0 by rule 4 (line 26):
1738 Reading a token: Now at end of input.
1739 Stack 0 Entering state 7
1740 Now at end of input.
1741 Splitting off stack 1 from 0.
1742 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1743 Stack 1 Entering state 2
1744 Now at end of input.
1745 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1746 Merging stack 0 into stack 1.
1747 Stack 1 Entering state 2
1748 Now at end of input.
1749 Removing dead stacks.
1750 Rename stack 1 -> 0.
1751 On stack 0, shifting token $end ()
1752 Stack 0 now in state #5
1755 start -> <Rule 1, tokens 1 .. 3>
1762 start -> <Rule 2, tokens 1 .. 3>
1769 Cleanup: popping token $end ()
1770 Cleanup: popping unresolved nterm start ()
1771 Cleanup: popping nterm d ()
1772 Cleanup: popping token 'c' ()
1773 Cleanup: popping nterm b ()
1774 Cleanup: popping token 'a' ()