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_DATA_GRAMMAR([glr-regr1.y],
28 [[/* Regression Test: Improper state compression */
29 /* Reported by Scott McPeak */
36 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
38 void yyerror (char const *msg);
45 /* -------- productions ------ */
48 StartSymbol: E { $$=0; } %merge <exprMerge>
51 E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); } %merge <exprMerge>
52 | 'B' { $$=2; printf("E -> 'B'\n"); } %merge <exprMerge>
57 /* ---------- C code ----------- */
60 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
75 yyerror (char const *msg)
77 fprintf (stderr, "%s\n", msg);
92 else if (ch == 'B' || ch == 'P')
98 AT_BISON_CHECK([[-o glr-regr1.c glr-regr1.y]], 0, [],
99 [glr-regr1.y: conflicts: 1 shift/reduce
101 AT_COMPILE([glr-regr1])
102 AT_PARSER_CHECK([[echo BPBPB | ./glr-regr1]], 0,
116 ## ------------------------------------------------------------ ##
117 ## Improper handling of embedded actions and $-N in GLR parsers ##
118 ## ------------------------------------------------------------ ##
120 AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers])
122 AT_DATA_GRAMMAR([glr-regr2a.y],
123 [[/* Regression Test: Improper handling of embedded actions and $-N */
124 /* Reported by S. Eken */
127 #define YYSTYPE char *
134 void yyerror (char const *);
143 { printf ("Variable: '%s'\n", $2); }
146 | 's' var_list 't' 'e'
147 { printf ("Varlist: '%s'\n", $2); free ($2); }
148 | 's' var 't' var_printer 'x'
162 char *s = (char *) realloc ($1, strlen ($1) + 1 + strlen ($3) + 1);
171 { printf ("Variable: '%s'\n", $-1); }
184 switch (fscanf (input, " %1[a-z,]", buf)) {
192 if (fscanf (input, "%49s", buf) != 1)
194 if (sizeof buf - 1 <= strlen (buf))
196 s = (char *) malloc (strlen (buf) + 1);
203 yyerror (char const *s)
204 { printf ("%s\n", s);
208 main (int argc, char **argv)
211 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
216 AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [],
217 [glr-regr2a.y: conflicts: 2 shift/reduce
219 AT_COMPILE([glr-regr2a])
221 AT_PARSER_CHECK([[echo s VARIABLE_1 t v x q | ./glr-regr2a]], 0,
222 [[Variable: 'VARIABLE_1'
224 AT_PARSER_CHECK([[echo s VARIABLE_1 , ANOTHER_VARIABLE_2 t e | ./glr-regr2a]],
226 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
228 AT_PARSER_CHECK([[echo s VARIABLE_3 t v x | ./glr-regr2a]], 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_DATA_GRAMMAR([glr-regr3.y],
242 [[/* Regression Test: Improper merging of GLR delayed action sets. */
243 /* Reported by M. Rosien */
250 static int MergeRule (int x0, int x1);
251 static void yyerror (char const * s);
254 #define RULE(x) (1 << (x))
261 %token P1 P2 T1 T2 T3 T4 O1 O2
265 S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
268 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
271 NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
272 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
275 NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
276 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
279 NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
280 | NT2 { $$ = RULE(8); } %merge<MergeRule>
281 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
284 NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
287 NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
288 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
293 static int MergeRule (int x0, int x1) {
297 static void yyerror(char const * s) {
298 fprintf(stderr,"error: %s\n",s);
301 FILE *input = YY_NULL;
303 int P[] = { P1, P2 };
304 int O[] = { O1, O2 };
305 int T[] = { T1, T2, T3, T4 };
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'];
323 int main(int argc, char* argv[]) {
325 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
330 AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
331 [glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce
333 AT_COMPILE([glr-regr3])
335 AT_PARSER_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]],
343 ## ------------------------------------------------------------------------- ##
344 ## Duplicate representation of merged trees. See ##
345 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
346 ## ------------------------------------------------------------------------- ##
348 AT_SETUP([Duplicate representation of merged trees])
350 AT_DATA_GRAMMAR([glr-regr4.y],
352 %union { char *ptr; }
353 %type <ptr> S A A1 A2 B
360 static char *merge (YYSTYPE, YYSTYPE);
361 static char *make_value (char const *, char const *);
362 static void yyerror (char const *);
363 static int yylex (void);
364 static char *ptrs[100];
365 static char **ptrs_next = ptrs;
370 tree: S { printf ("%s\n", $1); } ;
373 A %merge<merge> { $$ = make_value ("S", $1); }
374 | B %merge<merge> { $$ = make_value ("S", $1); }
378 A1 %merge<merge> { $$ = make_value ("A", $1); }
379 | A2 %merge<merge> { $$ = make_value ("A", $1); }
382 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
383 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
384 B: 'a' { $$ = make_value ("B", "'a'"); } ;
391 static char const input[] = "a";
392 static size_t toknum;
393 if (! (toknum < sizeof input))
395 return input[toknum++];
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);
428 yyerror (char const *msg)
430 fprintf (stderr, "%s\n", msg);
434 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
435 [glr-regr4.y: conflicts: 1 reduce/reduce
437 AT_COMPILE([glr-regr4])
439 AT_PARSER_CHECK([[./glr-regr4]], 0,
440 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
446 ## -------------------------------------------------------------------------- ##
447 ## User destructor for unresolved GLR semantic value. See ##
448 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
449 ## -------------------------------------------------------------------------- ##
451 AT_SETUP([User destructor for unresolved GLR semantic value])
453 AT_DATA_GRAMMAR([glr-regr5.y],
458 static void yyerror (char const *);
459 static int yylex (void);
460 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
464 %union { int value; }
468 if ($$ != MAGIC_VALUE)
470 fprintf (stderr, "Bad destructor call.\n");
478 'a' { $$ = MAGIC_VALUE; }
479 | 'a' { $$ = MAGIC_VALUE; }
487 static char const input[] = "a";
488 static size_t toknum;
489 if (! (toknum < sizeof input))
491 return input[toknum++];
495 yyerror (char const *msg)
497 fprintf (stderr, "%s\n", msg);
503 return yyparse () != 1;
507 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
508 [glr-regr5.y: conflicts: 1 reduce/reduce
510 AT_COMPILE([glr-regr5])
512 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
519 ## -------------------------------------------------------------------------- ##
520 ## User destructor after an error during a split parse. See ##
521 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
522 ## -------------------------------------------------------------------------- ##
524 AT_SETUP([User destructor after an error during a split parse])
526 AT_DATA_GRAMMAR([glr-regr6.y],
531 static void yyerror (char const *);
532 static int yylex (void);
536 %union { int value; }
540 printf ("Destructor called.\n");
552 static char const input[] = "a";
553 static size_t toknum;
554 if (! (toknum < sizeof input))
556 return input[toknum++];
560 yyerror (char const *msg)
562 fprintf (stderr, "%s\n", msg);
568 return yyparse () != 1;
572 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
573 [glr-regr6.y: conflicts: 1 reduce/reduce
575 AT_COMPILE([glr-regr6])
577 AT_PARSER_CHECK([[./glr-regr6]], 0,
586 ## ------------------------------------------------------------------------- ##
587 ## Duplicated user destructor for lookahead. See ##
588 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
589 ## ------------------------------------------------------------------------- ##
591 AT_SETUP([Duplicated user destructor for lookahead])
593 AT_DATA_GRAMMAR([glr-regr7.y],
598 static void yyerror (char const *);
599 static int yylex (void);
600 #define YYSTACKEXPANDABLE 0
601 typedef struct count_node {
603 struct count_node *prev;
605 static count_node *tail;
609 %union { count_node *node; }
614 fprintf (stderr, "Destructor called on same value twice.\n");
632 yylval.node = (count_node*) malloc (sizeof *yylval.node);
635 fprintf (stderr, "Test inconclusive.\n");
638 yylval.node->count = 0;
639 yylval.node->prev = tail;
645 yyerror (char const *msg)
647 fprintf (stderr, "%s\n", msg);
653 int status = yyparse ();
656 count_node *prev = tail->prev;
664 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
665 [glr-regr7.y: conflicts: 2 reduce/reduce
667 AT_COMPILE([glr-regr7])
669 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
676 ## ------------------------------------------------------------------------- ##
677 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
678 ## report by Claudia Hermann. ##
679 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
680 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
681 ## ------------------------------------------------------------------------- ##
683 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
685 AT_DATA_GRAMMAR([glr-regr8.y],
690 static void yyerror (char const *);
691 static int yylex (void);
692 static void yyerror (char const *msg);
704 PortClause : T_PORT InterfaceDeclaration T_PORT
705 { printf("%d/%d - %d/%d - %d/%d\n",
706 @1.first_column, @1.last_column,
707 @2.first_column, @2.last_column,
708 @3.first_column, @3.last_column); }
711 InterfaceDeclaration : OptConstantWord %dprec 1
712 | OptSignalWord %dprec 2
715 OptConstantWord : /* empty */
719 OptSignalWord : /* empty */
720 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
727 yyerror (char const *msg)
729 fprintf (stderr, "%s\n", msg);
742 yylloc.first_column = 1;
743 yylloc.last_column = 9;
746 yylloc.first_column = 13;
747 yylloc.last_column = 17;
762 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
763 [glr-regr8.y: conflicts: 1 reduce/reduce
765 AT_COMPILE([glr-regr8])
767 AT_PARSER_CHECK([[./glr-regr8]], 0,
776 ## ------------------------------------------------------------------------- ##
777 ## No users destructors if stack 0 deleted. See ##
778 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
779 ## ------------------------------------------------------------------------- ##
781 AT_SETUP([No users destructors if stack 0 deleted])
783 AT_DATA_GRAMMAR([glr-regr9.y],
788 static void yyerror (char const *);
789 static int yylex (void);
790 # define YYSTACKEXPANDABLE 0
791 static int tokens = 0;
792 static int destructors = 0;
797 %union { int dummy; }
807 ambig0 'a' { destructors += 2; USE ($2); }
808 | ambig1 start { destructors += 1; }
809 | ambig2 start { destructors += 1; }
826 yyerror (char const *msg)
828 fprintf (stderr, "%s\n", msg);
835 exit_status = yyparse ();
836 if (tokens != destructors)
838 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
845 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
846 [glr-regr9.y: conflicts: 1 reduce/reduce
848 AT_COMPILE([glr-regr9])
850 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
857 ## ------------------------------------------------------------------------- ##
858 ## Corrupted semantic options if user action cuts parse. ##
859 ## ------------------------------------------------------------------------- ##
861 AT_SETUP([Corrupted semantic options if user action cuts parse])
863 AT_DATA_GRAMMAR([glr-regr10.y],
868 static void yyerror (char const *);
869 static int yylex (void);
870 #define GARBAGE_SIZE 50
871 static char garbage[GARBAGE_SIZE];
875 %union { char *ptr; }
881 %dprec 2 { $$ = garbage; YYACCEPT; }
882 | %dprec 1 { $$ = garbage; YYACCEPT; }
888 yyerror (char const *msg)
890 fprintf (stderr, "%s\n", msg);
906 for (i = 0; i < GARBAGE_SIZE; i+=1)
912 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
913 [glr-regr10.y: conflicts: 1 reduce/reduce
915 AT_COMPILE([glr-regr10])
917 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
922 ## ------------------------------------------------------------------------- ##
923 ## Undesirable destructors if user action cuts parse. ##
924 ## ------------------------------------------------------------------------- ##
926 AT_SETUP([Undesirable destructors if user action cuts parse])
928 AT_DATA_GRAMMAR([glr-regr11.y],
932 static void yyerror (char const *);
933 static int yylex (void);
934 static int destructors = 0;
939 %union { int dummy; }
941 %destructor { destructors += 1; } 'a'
946 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
947 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
953 yyerror (char const *msg)
955 fprintf (stderr, "%s\n", msg);
961 static char const input[] = "a";
962 static size_t toknum;
963 if (! (toknum < sizeof input))
965 return input[toknum++];
971 int exit_status = yyparse ();
972 if (destructors != 1)
974 fprintf (stderr, "Destructor calls: %d\n", destructors);
981 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
982 [glr-regr11.y: conflicts: 1 reduce/reduce
984 AT_COMPILE([glr-regr11])
986 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
991 ## ------------------------------------------------------------------------- ##
992 ## Leaked semantic values if user action cuts parse. ##
993 ## ------------------------------------------------------------------------- ##
995 AT_SETUP([Leaked semantic values if user action cuts parse])
997 AT_DATA_GRAMMAR([glr-regr12.y],
1000 %union { int dummy; }
1001 %token PARENT_RHS_AFTER
1002 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
1003 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1004 %destructor { merged_value = 0; } merged
1005 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
1008 # include <stdlib.h>
1009 static int merge (YYSTYPE, YYSTYPE);
1010 static void yyerror (char const *);
1011 static int yylex (void);
1012 static int parent_rhs_before_value = 0;
1013 static int merged_value = 0;
1014 static int parent_rhs_after_value = 0;
1028 parent_rhs_after_value = 0;
1033 parent_rhs_before merged PARENT_RHS_AFTER {
1035 parent_rhs_before_value = 0;
1037 parent_rhs_after_value = 0;
1044 parent_rhs_before_value = 1;
1053 | cut %merge<merge> {
1059 cut: { YYACCEPT; } ;
1064 merge (YYSTYPE s1, YYSTYPE s2)
1067 char dummy = s1.dummy + s2.dummy;
1072 yyerror (char const *msg)
1074 fprintf (stderr, "%s\n", msg);
1080 static int const input[] = { PARENT_RHS_AFTER, 0 };
1081 static size_t toknum;
1082 if (! (toknum < sizeof input / sizeof *input))
1084 if (input[toknum] == PARENT_RHS_AFTER)
1085 parent_rhs_after_value = 1;
1086 return input[toknum++];
1092 int exit_status = yyparse ();
1093 if (parent_rhs_before_value)
1095 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1100 fprintf (stderr, "`merged' destructor not called.\n");
1103 if (parent_rhs_after_value)
1105 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1112 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1113 [glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
1115 AT_COMPILE([glr-regr12])
1117 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1122 ## ------------------------------------------------------------------------- ##
1123 ## Incorrect lookahead during deterministic GLR. See ##
1124 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1125 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1126 ## ------------------------------------------------------------------------- ##
1128 AT_SETUP([Incorrect lookahead during deterministic GLR])
1130 AT_DATA_GRAMMAR([glr-regr13.y],
1133 - Defaulted state with initial yychar: yychar == YYEMPTY.
1134 - Nondefaulted state: yychar != YYEMPTY.
1135 - Defaulted state after lookahead: yychar != YYEMPTY.
1136 - Defaulted state after shift: yychar == YYEMPTY.
1137 - User action changing the lookahead. */
1141 static void yyerror (char const *);
1142 static int yylex (void);
1143 static void print_lookahead (char const *);
1147 %union { char value; }
1148 %type <value> 'a' 'b'
1155 defstate_init defstate_shift 'b' change_lookahead 'a' {
1157 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1162 print_lookahead ("defstate_init <- empty string");
1166 nondefstate defstate_look 'a' {
1168 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1173 print_lookahead ("defstate_look <- empty string");
1178 print_lookahead ("nondefstate <- empty string");
1182 print_lookahead ("nondefstate <- 'b'");
1194 yyerror (char const *msg)
1196 fprintf (stderr, "%s\n", msg);
1202 static char const input[] = "ab";
1203 static size_t toknum;
1204 if (! (toknum < sizeof input))
1206 yylloc.first_line = yylloc.last_line = 1;
1207 yylloc.first_column = yylloc.last_column = toknum + 1;
1208 yylval.value = input[toknum] + 'A' - 'a';
1209 return input[toknum++];
1213 print_lookahead (char const *reduction)
1215 printf ("%s:\n yychar=", reduction);
1216 if (yychar == YYEMPTY)
1218 else if (yychar == YYEOF)
1222 printf ("'%c', yylval='", yychar);
1223 if (yylval.value > ' ')
1224 printf ("%c", yylval.value);
1225 printf ("', yylloc=(%d,%d),(%d,%d)",
1226 yylloc.first_line, yylloc.first_column,
1227 yylloc.last_line, yylloc.last_column);
1235 yychar = '#'; /* Not a token in the grammar. */
1241 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1242 AT_COMPILE([glr-regr13])
1244 AT_PARSER_CHECK([[./glr-regr13]], 0,
1245 [defstate_init <- empty string:
1247 nondefstate <- empty string:
1248 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1249 defstate_look <- empty string:
1250 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1251 defstate_shift <- nondefstate defstate_look 'a':
1253 start <- defstate_init defstate_shift 'b':
1260 ## ------------------------------------------------------------------------- ##
1261 ## Incorrect lookahead during nondeterministic GLR. ##
1262 ## ------------------------------------------------------------------------- ##
1264 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1266 AT_DATA_GRAMMAR([glr-regr14.y],
1269 - Conflicting actions (split-off parse, which copies lookahead need,
1270 which is necessarily yytrue) and nonconflicting actions (non-split-off
1271 parse) for nondefaulted state: yychar != YYEMPTY.
1272 - Merged deferred actions (lookahead need and RHS from different stack
1273 than the target state) and nonmerged deferred actions (same stack).
1274 - Defaulted state after lookahead: yychar != YYEMPTY.
1275 - Defaulted state after shift: yychar == YYEMPTY.
1276 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1277 seen the lookahead but current stack has not).
1278 - Exceeding stack capacity (stack explosion), and thus reallocating
1279 lookahead need array.
1280 Note that it does not seem possible to see the initial yychar value during
1281 nondeterministic operation since:
1282 - In order to preserve the initial yychar, only defaulted states may be
1284 - If only defaulted states are entered, there are no conflicts, so
1285 nondeterministic operation does not start. */
1287 %union { char value; }
1292 static void yyerror (char const *);
1293 static int yylex (void);
1294 static void print_lookahead (char const *);
1295 static char merge (union YYSTYPE, union YYSTYPE);
1299 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1306 merge 'c' stack_explosion {
1308 print_lookahead ("start <- merge 'c' stack_explosion");
1312 /* When merging the 2 deferred actions, the lookahead needs are different. */
1314 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1316 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1318 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1320 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1327 print_lookahead ("nonconflict1 <- empty string");
1332 print_lookahead ("nonconflict2 <- empty string");
1336 print_lookahead ("nonconflict2 <- 'a'");
1341 print_lookahead ("conflict <- empty string");
1346 print_lookahead ("defstate_look <- empty string");
1350 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1353 print_lookahead ("defstate_shift <- empty string");
1359 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1360 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1361 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1366 if (yychar != 'd' && yychar != YYEOF)
1368 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1375 if (yychar != 'd' && yychar != YYEOF)
1377 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1384 if (yychar != 'd' && yychar != YYEOF)
1386 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1392 if (yychar != YYEMPTY)
1395 "Found lookahead where shouldn't during stack explosion.\n");
1403 yyerror (char const *msg)
1405 fprintf (stderr, "%s\n", msg);
1411 static char const input[] = "abcdddd";
1412 static size_t toknum;
1413 if (! (toknum < sizeof input))
1415 yylloc.first_line = yylloc.last_line = 1;
1416 yylloc.first_column = yylloc.last_column = toknum + 1;
1417 yylval.value = input[toknum] + 'A' - 'a';
1418 return input[toknum++];
1422 print_lookahead (char const *reduction)
1424 printf ("%s:\n yychar=", reduction);
1425 if (yychar == YYEMPTY)
1427 else if (yychar == YYEOF)
1431 printf ("'%c', yylval='", yychar);
1432 if (yylval.value > ' ')
1433 printf ("%c", yylval.value);
1434 printf ("', yylloc=(%d,%d),(%d,%d)",
1435 yylloc.first_line, yylloc.first_column,
1436 yylloc.last_line, yylloc.last_column);
1442 merge (union YYSTYPE s1, union YYSTYPE s2)
1444 char dummy = s1.value + s2.value;
1451 yychar = '#'; /* Not a token in the grammar. */
1457 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1458 [glr-regr14.y: conflicts: 3 reduce/reduce
1460 AT_COMPILE([glr-regr14])
1462 AT_PARSER_CHECK([[./glr-regr14]], 0,
1463 [conflict <- empty string:
1464 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1465 defstate_look <- empty string:
1466 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1467 nonconflict2 <- empty string:
1468 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1469 defstate_shift <- empty string:
1471 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1473 start <- merge 'c' stack_explosion:
1480 ## ------------------------------------------------------------------------- ##
1481 ## Leaked semantic values when reporting ambiguity. ##
1482 ## ------------------------------------------------------------------------- ##
1484 AT_SETUP([Leaked semantic values when reporting ambiguity])
1486 AT_DATA_GRAMMAR([glr-regr15.y],
1489 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1492 # include <stdlib.h>
1493 static void yyerror (char const *);
1494 static int yylex (void);
1495 static int parent_rhs_before_value = 0;
1506 /* This stack must be merged into the other stacks *last* (added at the
1507 beginning of the semantic options list) so that yyparse will choose to clean
1508 it up rather than the tree for which some semantic actions have been
1509 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1510 those other trees are not cleaned up. */
1514 parent_rhs_before ambiguity {
1516 parent_rhs_before_value = 0;
1523 parent_rhs_before_value = 1;
1527 ambiguity: ambiguity1 | ambiguity2 ;
1534 yyerror (char const *msg)
1536 fprintf (stderr, "%s\n", msg);
1551 int exit_status = yyparse () != 1;
1552 if (parent_rhs_before_value)
1554 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1561 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1562 [glr-regr15.y: conflicts: 2 reduce/reduce
1564 AT_COMPILE([glr-regr15])
1566 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1567 [syntax is ambiguous
1573 ## ------------------------------------------------------------------------- ##
1574 ## Leaked lookahead after nondeterministic parse syntax error. ##
1575 ## ------------------------------------------------------------------------- ##
1577 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1578 AT_DATA_GRAMMAR([glr-regr16.y],
1581 %destructor { lookahead_value = 0; } 'b'
1584 # include <stdlib.h>
1585 static void yyerror (char const *);
1586 static int yylex (void);
1587 static int lookahead_value = 0;
1593 start: alt1 'a' | alt2 'a' ;
1600 yyerror (char const *msg)
1602 fprintf (stderr, "%s\n", msg);
1608 static char const input[] = "ab";
1609 static size_t toknum;
1610 if (! (toknum < sizeof input))
1612 if (input[toknum] == 'b')
1613 lookahead_value = 1;
1614 return input[toknum++];
1620 int exit_status = yyparse () != 1;
1621 if (lookahead_value)
1623 fprintf (stderr, "Lookahead destructor not called.\n");
1630 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1631 [glr-regr16.y: conflicts: 1 reduce/reduce
1633 AT_COMPILE([glr-regr16])
1635 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1642 ## ------------------------------------------------------------------------- ##
1643 ## Uninitialized location when reporting ambiguity. ##
1644 ## ------------------------------------------------------------------------- ##
1646 AT_SETUP([Uninitialized location when reporting ambiguity])
1647 AT_DATA_GRAMMAR([glr-regr17.y],
1654 %union { int dummy; }
1657 static void yyerror (YYLTYPE *, char const *);
1658 static int yylex (YYSTYPE *, YYLTYPE *);
1663 @$.first_column = 1;
1670 /* Tests the case of an empty RHS that has inherited the location of the
1671 previous nonterminal, which is unresolved. That location is reported as the
1672 last position of the ambiguity. */
1673 start: ambig1 empty1 | ambig2 empty2 ;
1675 /* Tests multiple levels of yyresolveLocations recursion. */
1676 ambig1: sub_ambig1 | sub_ambig2 ;
1677 ambig2: sub_ambig1 | sub_ambig2 ;
1679 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1680 has inherited the initial location. The empty RHS's location is reported as
1681 the first position in the ambiguity. */
1682 sub_ambig1: empty1 'a' 'b' ;
1683 sub_ambig2: empty2 'a' 'b' ;
1690 yyerror (YYLTYPE *locp, char const *msg)
1692 fprintf (stderr, "%d.%d-%d.%d: %s.\n", locp->first_line,
1693 locp->first_column, locp->last_line, locp->last_column, msg);
1697 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1699 static char const input[] = "ab";
1700 static size_t toknum;
1701 if (! (toknum < sizeof input))
1704 llocp->first_line = llocp->last_line = 2;
1705 llocp->first_column = toknum + 1;
1706 llocp->last_column = llocp->first_column + 1;
1707 return input[toknum++];
1713 return yyparse () != 1;
1717 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1718 [glr-regr17.y: conflicts: 3 reduce/reduce
1720 AT_COMPILE([glr-regr17])
1722 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1723 [1.1-2.3: syntax is ambiguous.
1729 ## -------------------------------------------------------------##
1730 ## Missed %merge type warnings when LHS type is declared later. ##
1731 ## -------------------------------------------------------------##
1733 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1734 AT_DATA_GRAMMAR([glr-regr18.y],
1739 static void yyerror (char const *);
1740 static int yylex ();
1751 sym1: sym2 %merge<merge> { $$ = $1; } ;
1752 sym2: sym3 %merge<merge> { $$ = $1; } ;
1753 sym3: %merge<merge> { $$ = 0; } ;
1762 yyerror (char const *msg)
1764 fprintf (stderr, "%s\n", msg);
1783 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1784 [glr-regr18.y:26.18-24: result type clash on merge function 'merge': <type2> != <type1>
1785 glr-regr18.y:25.18-24: previous declaration
1786 glr-regr18.y:27.13-19: result type clash on merge function 'merge': <type3> != <type2>
1787 glr-regr18.y:26.18-24: previous declaration
1793 ## ------------------- ##
1794 ## Ambiguity reports. ##
1795 ## ------------------- ##
1797 AT_SETUP([Ambiguity reports])
1799 AT_DATA_GRAMMAR([input.y],
1804 static void yyerror (char const *);
1805 static int yylex (void);
1823 static char const input[] = "abc";
1824 static size_t toknum;
1825 if (! (toknum < sizeof input))
1827 return input[toknum++];
1831 yyerror (char const *msg)
1833 fprintf (stderr, "%s\n", msg);
1840 return !!yyparse ();
1844 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1845 [input.y: conflicts: 1 reduce/reduce
1849 AT_PARSER_CHECK([[./input]], 1, [],
1852 Reading a token: Next token is token 'a' ()
1853 Shifting token 'a' ()
1855 Reading a token: Next token is token 'b' ()
1856 Shifting token 'b' ()
1858 Reducing stack 0 by rule 3 (line 25):
1862 Reading a token: Next token is token 'c' ()
1863 Shifting token 'c' ()
1865 Reducing stack 0 by rule 4 (line 26):
1868 Reading a token: Now at end of input.
1869 Stack 0 Entering state 7
1870 Now at end of input.
1871 Splitting off stack 1 from 0.
1872 Reduced stack 1 by rule #2; action deferred. Now in state 2.
1873 Stack 1 Entering state 2
1874 Now at end of input.
1875 Reduced stack 0 by rule #1; action deferred. Now in state 2.
1876 Merging stack 0 into stack 1.
1877 Stack 1 Entering state 2
1878 Now at end of input.
1879 Removing dead stacks.
1880 Rename stack 1 -> 0.
1881 On stack 0, shifting token $end ()
1882 Stack 0 now in state #5
1885 start -> <Rule 1, tokens 1 .. 3>
1892 start -> <Rule 2, tokens 1 .. 3>
1899 Cleanup: popping token $end ()
1900 Cleanup: popping unresolved nterm start ()
1901 Cleanup: popping nterm d ()
1902 Cleanup: popping token 'c' ()
1903 Cleanup: popping nterm b ()
1904 Cleanup: popping token 'a' ()