1 # Checking GLR Parsing: Regression Tests -*- Autotest -*-
2 # Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 AT_BANNER([[GLR Regression Tests]])
19 ## --------------------------- ##
20 ## Badly Collapsed GLR States. ##
21 ## --------------------------- ##
23 AT_SETUP([Badly Collapsed GLR States])
25 AT_DATA_GRAMMAR([glr-regr1.y],
26 [[/* Regression Test: Improper state compression */
27 /* Reported by Scott McPeak */
34 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
36 void yyerror (char const *msg);
43 /* -------- productions ------ */
46 StartSymbol: E { $$=0; } %merge <exprMerge>
49 E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); } %merge <exprMerge>
50 | 'B' { $$=2; printf("E -> 'B'\n"); } %merge <exprMerge>
55 /* ---------- C code ----------- */
58 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
73 yyerror (char const *msg)
75 fprintf (stderr, "%s\n", msg);
90 else if (ch == 'B' || ch == 'P')
96 AT_CHECK([[bison -o glr-regr1.c glr-regr1.y]], 0, [],
97 [glr-regr1.y: conflicts: 1 shift/reduce
99 AT_COMPILE([glr-regr1])
100 AT_PARSER_CHECK([[echo BPBPB | ./glr-regr1]], 0,
114 ## ------------------------------------------------------------ ##
115 ## Improper handling of embedded actions and $-N in GLR parsers ##
116 ## ------------------------------------------------------------ ##
118 AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers])
120 AT_DATA_GRAMMAR([glr-regr2a.y],
121 [[/* Regression Test: Improper handling of embedded actions and $-N */
122 /* Reported by S. Eken */
125 #define YYSTYPE char *
132 void yyerror (char const *);
141 { printf ("Variable: '%s'\n", $2); }
144 | 's' var_list 't' 'e'
145 { printf ("Varlist: '%s'\n", $2); free ($2); }
146 | 's' var 't' var_printer 'x'
160 char *s = (char *) realloc ($1, strlen ($1) + 1 + strlen ($3) + 1);
169 { printf ("Variable: '%s'\n", $-1); }
182 switch (fscanf (input, " %1[a-z,]", buf)) {
190 if (fscanf (input, "%49s", buf) != 1)
192 if (sizeof buf - 1 <= strlen (buf))
194 s = (char *) malloc (strlen (buf) + 1);
201 yyerror (char const *s)
202 { printf ("%s\n", s);
206 main (int argc, char **argv)
209 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
214 AT_CHECK([[bison -o glr-regr2a.c glr-regr2a.y]], 0, [],
215 [glr-regr2a.y: conflicts: 2 shift/reduce
217 AT_COMPILE([glr-regr2a])
219 AT_PARSER_CHECK([[echo s VARIABLE_1 t v x q | ./glr-regr2a]], 0,
220 [[Variable: 'VARIABLE_1'
222 AT_PARSER_CHECK([[echo s VARIABLE_1 , ANOTHER_VARIABLE_2 t e | ./glr-regr2a]],
224 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
226 AT_PARSER_CHECK([[echo s VARIABLE_3 t v x | ./glr-regr2a]], 0,
227 [[Variable: 'VARIABLE_3'
233 ## ------------------------------------------------------------ ##
234 ## Improper merging of GLR delayed action sets ##
235 ## ------------------------------------------------------------ ##
237 AT_SETUP([Improper merging of GLR delayed action sets])
239 AT_DATA_GRAMMAR([glr-regr3.y],
240 [[/* Regression Test: Improper merging of GLR delayed action sets. */
241 /* Reported by M. Rosien */
248 static int MergeRule (int x0, int x1);
249 static void yyerror (char const * s);
252 #define RULE(x) (1 << (x))
259 %token P1 P2 T1 T2 T3 T4 O1 O2
263 S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
266 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
269 NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
270 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
273 NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
274 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
277 NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
278 | NT2 { $$ = RULE(8); } %merge<MergeRule>
279 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
282 NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
285 NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
286 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
291 static int MergeRule (int x0, int x1) {
295 static void yyerror(char const * s) {
296 fprintf(stderr,"error: %s\n",s);
301 int P[] = { P1, P2 };
302 int O[] = { O1, O2 };
303 int T[] = { T1, T2, T3, T4 };
310 if (fscanf (input, "%2s", inp) == EOF)
314 case 'p': return P[inp[1] - '1'];
315 case 't': return T[inp[1] - '1'];
316 case 'o': return O[inp[1] - '1'];
321 int main(int argc, char* argv[]) {
323 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
328 AT_CHECK([[bison -o glr-regr3.c glr-regr3.y]], 0, [],
329 [glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce
331 AT_COMPILE([glr-regr3])
333 AT_PARSER_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]],
341 ## ------------------------------------------------------------------------- ##
342 ## Duplicate representation of merged trees. See ##
343 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
344 ## ------------------------------------------------------------------------- ##
346 AT_SETUP([Duplicate representation of merged trees])
348 AT_DATA_GRAMMAR([glr-regr4.y],
350 %union { char *ptr; }
351 %type <ptr> S A A1 A2 B
358 static char *merge (YYSTYPE, YYSTYPE);
359 static char *make_value (char const *, char const *);
360 static void yyerror (char const *);
361 static int yylex (void);
362 static char *ptrs[100];
363 static char **ptrs_next = ptrs;
368 tree: S { printf ("%s\n", $1); } ;
371 A %merge<merge> { $$ = make_value ("S", $1); }
372 | B %merge<merge> { $$ = make_value ("S", $1); }
376 A1 %merge<merge> { $$ = make_value ("A", $1); }
377 | A2 %merge<merge> { $$ = make_value ("A", $1); }
380 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
381 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
382 B: 'a' { $$ = make_value ("B", "'a'"); } ;
389 static char const input[] = "a";
390 static size_t toknum;
391 if (! (toknum < sizeof input))
393 return input[toknum++];
399 int status = yyparse ();
400 while (ptrs_next != ptrs)
406 make_value (char const *parent, char const *child)
408 char const format[] = "%s <- %s";
409 char *value = *ptrs_next++ =
410 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
411 sprintf (value, format, parent, child);
416 merge (YYSTYPE s1, YYSTYPE s2)
418 char const format[] = "merge{ %s and %s }";
419 char *value = *ptrs_next++ =
420 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
421 sprintf (value, format, s1.ptr, s2.ptr);
426 yyerror (char const *msg)
428 fprintf (stderr, "%s\n", msg);
432 AT_CHECK([[bison -o glr-regr4.c glr-regr4.y]], 0, [],
433 [glr-regr4.y: conflicts: 1 reduce/reduce
435 AT_COMPILE([glr-regr4])
437 AT_PARSER_CHECK([[./glr-regr4]], 0,
438 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
444 ## -------------------------------------------------------------------------- ##
445 ## User destructor for unresolved GLR semantic value. See ##
446 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
447 ## -------------------------------------------------------------------------- ##
449 AT_SETUP([User destructor for unresolved GLR semantic value])
451 AT_DATA_GRAMMAR([glr-regr5.y],
456 static void yyerror (char const *);
457 static int yylex (void);
458 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
462 %union { int value; }
466 if ($$ != MAGIC_VALUE)
468 fprintf (stderr, "Bad destructor call.\n");
476 'a' { $$ = MAGIC_VALUE; }
477 | 'a' { $$ = MAGIC_VALUE; }
485 static char const input[] = "a";
486 static size_t toknum;
487 if (! (toknum < sizeof input))
489 return input[toknum++];
493 yyerror (char const *msg)
495 fprintf (stderr, "%s\n", msg);
501 return yyparse () != 1;
505 AT_CHECK([[bison -o glr-regr5.c glr-regr5.y]], 0, [],
506 [glr-regr5.y: conflicts: 1 reduce/reduce
508 AT_COMPILE([glr-regr5])
510 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
517 ## -------------------------------------------------------------------------- ##
518 ## User destructor after an error during a split parse. See ##
519 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
520 ## -------------------------------------------------------------------------- ##
522 AT_SETUP([User destructor after an error during a split parse])
524 AT_DATA_GRAMMAR([glr-regr6.y],
529 static void yyerror (char const *);
530 static int yylex (void);
534 %union { int value; }
538 printf ("Destructor called.\n");
550 static char const input[] = "a";
551 static size_t toknum;
552 if (! (toknum < sizeof input))
554 return input[toknum++];
558 yyerror (char const *msg)
560 fprintf (stderr, "%s\n", msg);
566 return yyparse () != 1;
570 AT_CHECK([[bison -o glr-regr6.c glr-regr6.y]], 0, [],
571 [glr-regr6.y: conflicts: 1 reduce/reduce
573 AT_COMPILE([glr-regr6])
575 AT_PARSER_CHECK([[./glr-regr6]], 0,
584 ## ------------------------------------------------------------------------- ##
585 ## Duplicated user destructor for lookahead. See ##
586 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
587 ## ------------------------------------------------------------------------- ##
589 AT_SETUP([Duplicated user destructor for lookahead])
591 AT_DATA_GRAMMAR([glr-regr7.y],
596 static void yyerror (char const *);
597 static int yylex (void);
598 #define YYSTACKEXPANDABLE 0
599 typedef struct count_node {
601 struct count_node *prev;
603 static count_node *tail;
607 %union { count_node *node; }
612 fprintf (stderr, "Destructor called on same value twice.\n");
630 yylval.node = (count_node*) malloc (sizeof *yylval.node);
633 fprintf (stderr, "Test inconclusive.\n");
636 yylval.node->count = 0;
637 yylval.node->prev = tail;
643 yyerror (char const *msg)
645 fprintf (stderr, "%s\n", msg);
651 int status = yyparse ();
654 count_node *prev = tail->prev;
662 AT_CHECK([[bison -o glr-regr7.c glr-regr7.y]], 0, [],
663 [glr-regr7.y: conflicts: 2 reduce/reduce
665 AT_COMPILE([glr-regr7])
667 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
674 ## ------------------------------------------------------------------------- ##
675 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
676 ## report by Claudia Hermann. ##
677 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
678 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
679 ## ------------------------------------------------------------------------- ##
681 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
683 AT_DATA_GRAMMAR([glr-regr8.y],
688 static void yyerror (char const *);
689 static int yylex (void);
690 static void yyerror (char const *msg);
702 PortClause : T_PORT InterfaceDeclaration T_PORT
703 { printf("%d/%d - %d/%d - %d/%d\n",
704 @1.first_column, @1.last_column,
705 @2.first_column, @2.last_column,
706 @3.first_column, @3.last_column); }
709 InterfaceDeclaration : OptConstantWord %dprec 1
710 | OptSignalWord %dprec 2
713 OptConstantWord : /* empty */
717 OptSignalWord : /* empty */
718 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
725 yyerror (char const *msg)
727 fprintf (stderr, "%s\n", msg);
740 yylloc.first_column = 1;
741 yylloc.last_column = 9;
744 yylloc.first_column = 13;
745 yylloc.last_column = 17;
760 AT_CHECK([[bison -o glr-regr8.c glr-regr8.y]], 0, [],
761 [glr-regr8.y: conflicts: 1 reduce/reduce
763 AT_COMPILE([glr-regr8])
765 AT_PARSER_CHECK([[./glr-regr8]], 0,
774 ## ------------------------------------------------------------------------- ##
775 ## No users destructors if stack 0 deleted. See ##
776 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
777 ## ------------------------------------------------------------------------- ##
779 AT_SETUP([No users destructors if stack 0 deleted])
781 AT_DATA_GRAMMAR([glr-regr9.y],
786 static void yyerror (char const *);
787 static int yylex (void);
788 # define YYSTACKEXPANDABLE 0
789 static int tokens = 0;
790 static int destructors = 0;
795 %union { int dummy; }
805 ambig0 'a' { destructors += 2; USE ($2); }
806 | ambig1 start { destructors += 1; }
807 | ambig2 start { destructors += 1; }
824 yyerror (char const *msg)
826 fprintf (stderr, "%s\n", msg);
833 exit_status = yyparse ();
834 if (tokens != destructors)
836 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
843 AT_CHECK([[bison -o glr-regr9.c glr-regr9.y]], 0, [],
844 [glr-regr9.y: conflicts: 1 reduce/reduce
846 AT_COMPILE([glr-regr9])
848 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
855 ## ------------------------------------------------------------------------- ##
856 ## Corrupted semantic options if user action cuts parse. ##
857 ## ------------------------------------------------------------------------- ##
859 AT_SETUP([Corrupted semantic options if user action cuts parse])
861 AT_DATA_GRAMMAR([glr-regr10.y],
866 static void yyerror (char const *);
867 static int yylex (void);
868 #define GARBAGE_SIZE 50
869 static char garbage[GARBAGE_SIZE];
873 %union { char *ptr; }
879 %dprec 2 { $$ = garbage; YYACCEPT; }
880 | %dprec 1 { $$ = garbage; YYACCEPT; }
886 yyerror (char const *msg)
888 fprintf (stderr, "%s\n", msg);
904 for (i = 0; i < GARBAGE_SIZE; i+=1)
910 AT_CHECK([[bison -o glr-regr10.c glr-regr10.y]], 0, [],
911 [glr-regr10.y: conflicts: 1 reduce/reduce
913 AT_COMPILE([glr-regr10])
915 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
920 ## ------------------------------------------------------------------------- ##
921 ## Undesirable destructors if user action cuts parse. ##
922 ## ------------------------------------------------------------------------- ##
924 AT_SETUP([Undesirable destructors if user action cuts parse])
926 AT_DATA_GRAMMAR([glr-regr11.y],
930 static void yyerror (char const *);
931 static int yylex (void);
932 static int destructors = 0;
937 %union { int dummy; }
939 %destructor { destructors += 1; } 'a'
944 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
945 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
951 yyerror (char const *msg)
953 fprintf (stderr, "%s\n", msg);
959 static char const input[] = "a";
960 static size_t toknum;
961 if (! (toknum < sizeof input))
963 return input[toknum++];
969 int exit_status = yyparse ();
970 if (destructors != 1)
972 fprintf (stderr, "Destructor calls: %d\n", destructors);
979 AT_CHECK([[bison -o glr-regr11.c glr-regr11.y]], 0, [],
980 [glr-regr11.y: conflicts: 1 reduce/reduce
982 AT_COMPILE([glr-regr11])
984 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
989 ## ------------------------------------------------------------------------- ##
990 ## Leaked semantic values if user action cuts parse. ##
991 ## ------------------------------------------------------------------------- ##
993 AT_SETUP([Leaked semantic values if user action cuts parse])
995 AT_DATA_GRAMMAR([glr-regr12.y],
998 %union { int dummy; }
999 %token PARENT_RHS_AFTER
1000 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
1001 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1002 %destructor { merged_value = 0; } merged
1003 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
1006 # include <stdlib.h>
1007 static int merge (YYSTYPE, YYSTYPE);
1008 static void yyerror (char const *);
1009 static int yylex (void);
1010 static int parent_rhs_before_value = 0;
1011 static int merged_value = 0;
1012 static int parent_rhs_after_value = 0;
1026 parent_rhs_after_value = 0;
1031 parent_rhs_before merged PARENT_RHS_AFTER {
1033 parent_rhs_before_value = 0;
1035 parent_rhs_after_value = 0;
1042 parent_rhs_before_value = 1;
1051 | cut %merge<merge> {
1057 cut: { YYACCEPT; } ;
1062 merge (YYSTYPE s1, YYSTYPE s2)
1065 char dummy = s1.dummy + s2.dummy;
1070 yyerror (char const *msg)
1072 fprintf (stderr, "%s\n", msg);
1078 static int const input[] = { PARENT_RHS_AFTER, 0 };
1079 static size_t toknum;
1080 if (! (toknum < sizeof input / sizeof *input))
1082 if (input[toknum] == PARENT_RHS_AFTER)
1083 parent_rhs_after_value = 1;
1084 return input[toknum++];
1090 int exit_status = yyparse ();
1091 if (parent_rhs_before_value)
1093 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1098 fprintf (stderr, "`merged' destructor not called.\n");
1101 if (parent_rhs_after_value)
1103 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1110 AT_CHECK([[bison -o glr-regr12.c glr-regr12.y]], 0, [],
1111 [glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
1113 AT_COMPILE([glr-regr12])
1115 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1120 ## ------------------------------------------------------------------------- ##
1121 ## Incorrect lookahead during deterministic GLR. See ##
1122 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1123 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1124 ## ------------------------------------------------------------------------- ##
1126 AT_SETUP([Incorrect lookahead during deterministic GLR])
1128 AT_DATA_GRAMMAR([glr-regr13.y],
1131 - Defaulted state with initial yychar: yychar == YYEMPTY.
1132 - Nondefaulted state: yychar != YYEMPTY.
1133 - Defaulted state after lookahead: yychar != YYEMPTY.
1134 - Defaulted state after shift: yychar == YYEMPTY.
1135 - User action changing the lookahead. */
1139 static void yyerror (char const *);
1140 static int yylex (void);
1141 static void print_lookahead (char const *);
1145 %union { char value; }
1146 %type <value> 'a' 'b'
1153 defstate_init defstate_shift 'b' change_lookahead 'a' {
1155 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1160 print_lookahead ("defstate_init <- empty string");
1164 nondefstate defstate_look 'a' {
1166 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1171 print_lookahead ("defstate_look <- empty string");
1176 print_lookahead ("nondefstate <- empty string");
1180 print_lookahead ("nondefstate <- 'b'");
1192 yyerror (char const *msg)
1194 fprintf (stderr, "%s\n", msg);
1200 static char const input[] = "ab";
1201 static size_t toknum;
1202 if (! (toknum < sizeof input))
1204 yylloc.first_line = yylloc.last_line = 1;
1205 yylloc.first_column = yylloc.last_column = toknum + 1;
1206 yylval.value = input[toknum] + 'A' - 'a';
1207 return input[toknum++];
1211 print_lookahead (char const *reduction)
1213 printf ("%s:\n yychar=", reduction);
1214 if (yychar == YYEMPTY)
1216 else if (yychar == YYEOF)
1220 printf ("'%c', yylval='", yychar);
1221 if (yylval.value > ' ')
1222 printf ("%c", yylval.value);
1223 printf ("', yylloc=(%d,%d),(%d,%d)",
1224 yylloc.first_line, yylloc.first_column,
1225 yylloc.last_line, yylloc.last_column);
1233 yychar = '#'; /* Not a token in the grammar. */
1239 AT_CHECK([[bison -o glr-regr13.c glr-regr13.y]], 0, [], [])
1240 AT_COMPILE([glr-regr13])
1242 AT_PARSER_CHECK([[./glr-regr13]], 0,
1243 [defstate_init <- empty string:
1245 nondefstate <- empty string:
1246 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1247 defstate_look <- empty string:
1248 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1249 defstate_shift <- nondefstate defstate_look 'a':
1251 start <- defstate_init defstate_shift 'b':
1258 ## ------------------------------------------------------------------------- ##
1259 ## Incorrect lookahead during nondeterministic GLR. ##
1260 ## ------------------------------------------------------------------------- ##
1262 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1264 AT_DATA_GRAMMAR([glr-regr14.y],
1267 - Conflicting actions (split-off parse, which copies lookahead need,
1268 which is necessarily yytrue) and nonconflicting actions (non-split-off
1269 parse) for nondefaulted state: yychar != YYEMPTY.
1270 - Merged deferred actions (lookahead need and RHS from different stack
1271 than the target state) and nonmerged deferred actions (same stack).
1272 - Defaulted state after lookahead: yychar != YYEMPTY.
1273 - Defaulted state after shift: yychar == YYEMPTY.
1274 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1275 seen the lookahead but current stack has not).
1276 - Exceeding stack capacity (stack explosion), and thus reallocating
1277 lookahead need array.
1278 Note that it does not seem possible to see the initial yychar value during
1279 nondeterministic operation since:
1280 - In order to preserve the initial yychar, only defaulted states may be
1282 - If only defaulted states are entered, there are no conflicts, so
1283 nondeterministic operation does not start. */
1285 %union { char value; }
1290 static void yyerror (char const *);
1291 static int yylex (void);
1292 static void print_lookahead (char const *);
1293 static char merge (union YYSTYPE, union YYSTYPE);
1297 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1304 merge 'c' stack_explosion {
1306 print_lookahead ("start <- merge 'c' stack_explosion");
1310 /* When merging the 2 deferred actions, the lookahead needs are different. */
1312 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1314 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1316 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1318 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1325 print_lookahead ("nonconflict1 <- empty string");
1330 print_lookahead ("nonconflict2 <- empty string");
1334 print_lookahead ("nonconflict2 <- 'a'");
1339 print_lookahead ("conflict <- empty string");
1344 print_lookahead ("defstate_look <- empty string");
1348 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1351 print_lookahead ("defstate_shift <- empty string");
1357 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1358 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1359 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1364 if (yychar != 'd' && yychar != YYEOF)
1366 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1373 if (yychar != 'd' && yychar != YYEOF)
1375 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1382 if (yychar != 'd' && yychar != YYEOF)
1384 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1390 if (yychar != YYEMPTY)
1393 "Found lookahead where shouldn't during stack explosion.\n");
1401 yyerror (char const *msg)
1403 fprintf (stderr, "%s\n", msg);
1409 static char const input[] = "abcdddd";
1410 static size_t toknum;
1411 if (! (toknum < sizeof input))
1413 yylloc.first_line = yylloc.last_line = 1;
1414 yylloc.first_column = yylloc.last_column = toknum + 1;
1415 yylval.value = input[toknum] + 'A' - 'a';
1416 return input[toknum++];
1420 print_lookahead (char const *reduction)
1422 printf ("%s:\n yychar=", reduction);
1423 if (yychar == YYEMPTY)
1425 else if (yychar == YYEOF)
1429 printf ("'%c', yylval='", yychar);
1430 if (yylval.value > ' ')
1431 printf ("%c", yylval.value);
1432 printf ("', yylloc=(%d,%d),(%d,%d)",
1433 yylloc.first_line, yylloc.first_column,
1434 yylloc.last_line, yylloc.last_column);
1440 merge (union YYSTYPE s1, union YYSTYPE s2)
1442 char dummy = s1.value + s2.value;
1449 yychar = '#'; /* Not a token in the grammar. */
1455 AT_CHECK([[bison -o glr-regr14.c glr-regr14.y]], 0, [],
1456 [glr-regr14.y: conflicts: 3 reduce/reduce
1458 AT_COMPILE([glr-regr14])
1460 AT_PARSER_CHECK([[./glr-regr14]], 0,
1461 [conflict <- empty string:
1462 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1463 defstate_look <- empty string:
1464 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1465 nonconflict2 <- empty string:
1466 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1467 defstate_shift <- empty string:
1469 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1471 start <- merge 'c' stack_explosion:
1478 ## ------------------------------------------------------------------------- ##
1479 ## Leaked semantic values when reporting ambiguity. ##
1480 ## ------------------------------------------------------------------------- ##
1482 AT_SETUP([Leaked semantic values when reporting ambiguity])
1484 AT_DATA_GRAMMAR([glr-regr15.y],
1487 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1490 # include <stdlib.h>
1491 static void yyerror (char const *);
1492 static int yylex (void);
1493 static int parent_rhs_before_value = 0;
1504 /* This stack must be merged into the other stacks *last* (added at the
1505 beginning of the semantic options list) so that yyparse will choose to clean
1506 it up rather than the tree for which some semantic actions have been
1507 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1508 those other trees are not cleaned up. */
1512 parent_rhs_before ambiguity {
1514 parent_rhs_before_value = 0;
1521 parent_rhs_before_value = 1;
1525 ambiguity: ambiguity1 | ambiguity2 ;
1532 yyerror (char const *msg)
1534 fprintf (stderr, "%s\n", msg);
1549 int exit_status = yyparse () != 1;
1550 if (parent_rhs_before_value)
1552 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1559 AT_CHECK([[bison -o glr-regr15.c glr-regr15.y]], 0, [],
1560 [glr-regr15.y: conflicts: 2 reduce/reduce
1562 AT_COMPILE([glr-regr15])
1564 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1565 [syntax is ambiguous
1571 ## ------------------------------------------------------------------------- ##
1572 ## Leaked lookahead after nondeterministic parse syntax error. ##
1573 ## ------------------------------------------------------------------------- ##
1575 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1576 AT_DATA_GRAMMAR([glr-regr16.y],
1579 %destructor { lookahead_value = 0; } 'b'
1582 # include <stdlib.h>
1583 static void yyerror (char const *);
1584 static int yylex (void);
1585 static int lookahead_value = 0;
1591 start: alt1 'a' | alt2 'a' ;
1598 yyerror (char const *msg)
1600 fprintf (stderr, "%s\n", msg);
1606 static char const input[] = "ab";
1607 static size_t toknum;
1608 if (! (toknum < sizeof input))
1610 if (input[toknum] == 'b')
1611 lookahead_value = 1;
1612 return input[toknum++];
1618 int exit_status = yyparse () != 1;
1619 if (lookahead_value)
1621 fprintf (stderr, "Lookahead destructor not called.\n");
1628 AT_CHECK([[bison -o glr-regr16.c glr-regr16.y]], 0, [],
1629 [glr-regr16.y: conflicts: 1 reduce/reduce
1631 AT_COMPILE([glr-regr16])
1633 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1640 ## ------------------------------------------------------------------------- ##
1641 ## Uninitialized location when reporting ambiguity. ##
1642 ## ------------------------------------------------------------------------- ##
1644 AT_SETUP([Uninitialized location when reporting ambiguity])
1645 AT_DATA_GRAMMAR([glr-regr17.y],
1652 %union { int dummy; }
1655 static void yyerror (YYLTYPE *, char const *);
1656 static int yylex (YYSTYPE *, YYLTYPE *);
1661 @$.first_column = 1;
1668 /* Tests the case of an empty RHS that has inherited the location of the
1669 previous nonterminal, which is unresolved. That location is reported as the
1670 last position of the ambiguity. */
1671 start: ambig1 empty1 | ambig2 empty2 ;
1673 /* Tests multiple levels of yyresolveLocations recursion. */
1674 ambig1: sub_ambig1 | sub_ambig2 ;
1675 ambig2: sub_ambig1 | sub_ambig2 ;
1677 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1678 has inherited the initial location. The empty RHS's location is reported as
1679 the first position in the ambiguity. */
1680 sub_ambig1: empty1 'a' 'b' ;
1681 sub_ambig2: empty2 'a' 'b' ;
1688 yyerror (YYLTYPE *locp, char const *msg)
1690 fprintf (stderr, "Error at %d.%d-%d.%d: %s.\n", locp->first_line,
1691 locp->first_column, locp->last_line, locp->last_column, msg);
1695 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1697 static char const input[] = "ab";
1698 static size_t toknum;
1699 if (! (toknum < sizeof input))
1702 llocp->first_line = llocp->last_line = 2;
1703 llocp->first_column = toknum + 1;
1704 llocp->last_column = llocp->first_column + 1;
1705 return input[toknum++];
1711 return yyparse () != 1;
1715 AT_CHECK([[bison -o glr-regr17.c glr-regr17.y]], 0, [],
1716 [glr-regr17.y: conflicts: 3 reduce/reduce
1718 AT_COMPILE([glr-regr17])
1720 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1721 [Error at 1.1-2.3: syntax is ambiguous.
1727 ## -------------------------------------------------------------##
1728 ## Missed %merge type warnings when LHS type is declared later. ##
1729 ## -------------------------------------------------------------##
1731 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1732 AT_DATA_GRAMMAR([glr-regr18.y],
1737 static void yyerror (char const *);
1738 static int yylex ();
1749 sym1: sym2 %merge<merge> { $$ = $1; } ;
1750 sym2: sym3 %merge<merge> { $$ = $1; } ;
1751 sym3: %merge<merge> { $$ = 0; } ;
1760 yyerror (char const *msg)
1762 fprintf (stderr, "%s\n", msg);
1781 AT_CHECK([[bison -o glr-regr18.c glr-regr18.y]], 1, [],
1782 [glr-regr18.y:26.18-24: result type clash on merge function `merge': <type2> != <type1>
1783 glr-regr18.y:25.18-24: previous declaration
1784 glr-regr18.y:27.13-19: result type clash on merge function `merge': <type3> != <type2>
1785 glr-regr18.y:26.18-24: previous declaration