1 # Checking GLR Parsing: Regression Tests -*- Autotest -*-
2 # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2009 Free Software
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 AT_BANNER([[GLR Regression Tests]])
20 ## --------------------------- ##
21 ## Badly Collapsed GLR States. ##
22 ## --------------------------- ##
24 AT_SETUP([Badly Collapsed GLR States])
26 AT_DATA_GRAMMAR([glr-regr1.y],
27 [[/* Regression Test: Improper state compression */
28 /* Reported by Scott McPeak */
35 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
37 void yyerror (char const *msg);
44 /* -------- productions ------ */
47 StartSymbol: E { $$=0; } %merge <exprMerge>
50 E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); } %merge <exprMerge>
51 | 'B' { $$=2; printf("E -> 'B'\n"); } %merge <exprMerge>
56 /* ---------- C code ----------- */
59 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
74 yyerror (char const *msg)
76 fprintf (stderr, "%s\n", msg);
91 else if (ch == 'B' || ch == 'P')
97 AT_BISON_CHECK([[-o glr-regr1.c glr-regr1.y]], 0, [],
98 [glr-regr1.y: conflicts: 1 shift/reduce
100 AT_COMPILE([glr-regr1])
101 AT_PARSER_CHECK([[echo BPBPB | ./glr-regr1]], 0,
115 ## ------------------------------------------------------------ ##
116 ## Improper handling of embedded actions and $-N in GLR parsers ##
117 ## ------------------------------------------------------------ ##
119 AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers])
121 AT_DATA_GRAMMAR([glr-regr2a.y],
122 [[/* Regression Test: Improper handling of embedded actions and $-N */
123 /* Reported by S. Eken */
126 #define YYSTYPE char *
133 void yyerror (char const *);
142 { printf ("Variable: '%s'\n", $2); }
145 | 's' var_list 't' 'e'
146 { printf ("Varlist: '%s'\n", $2); free ($2); }
147 | 's' var 't' var_printer 'x'
161 char *s = (char *) realloc ($1, strlen ($1) + 1 + strlen ($3) + 1);
170 { printf ("Variable: '%s'\n", $-1); }
183 switch (fscanf (input, " %1[a-z,]", buf)) {
191 if (fscanf (input, "%49s", buf) != 1)
193 if (sizeof buf - 1 <= strlen (buf))
195 s = (char *) malloc (strlen (buf) + 1);
202 yyerror (char const *s)
203 { printf ("%s\n", s);
207 main (int argc, char **argv)
210 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
215 AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [],
216 [glr-regr2a.y: conflicts: 2 shift/reduce
218 AT_COMPILE([glr-regr2a])
220 AT_PARSER_CHECK([[echo s VARIABLE_1 t v x q | ./glr-regr2a]], 0,
221 [[Variable: 'VARIABLE_1'
223 AT_PARSER_CHECK([[echo s VARIABLE_1 , ANOTHER_VARIABLE_2 t e | ./glr-regr2a]],
225 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
227 AT_PARSER_CHECK([[echo s VARIABLE_3 t v x | ./glr-regr2a]], 0,
228 [[Variable: 'VARIABLE_3'
234 ## ------------------------------------------------------------ ##
235 ## Improper merging of GLR delayed action sets ##
236 ## ------------------------------------------------------------ ##
238 AT_SETUP([Improper merging of GLR delayed action sets])
240 AT_DATA_GRAMMAR([glr-regr3.y],
241 [[/* Regression Test: Improper merging of GLR delayed action sets. */
242 /* Reported by M. Rosien */
249 static int MergeRule (int x0, int x1);
250 static void yyerror (char const * s);
253 #define RULE(x) (1 << (x))
260 %token P1 P2 T1 T2 T3 T4 O1 O2
264 S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); }
267 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge<MergeRule>
270 NT2 : NT1 { $$ = RULE(3); } %merge<MergeRule>
271 | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
274 NT3 : T3 { $$ = RULE(5); } %merge<MergeRule>
275 | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
278 NT4 : NT3 { $$ = RULE(7); } %merge<MergeRule>
279 | NT2 { $$ = RULE(8); } %merge<MergeRule>
280 | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
283 NT5 : NT4 { $$ = RULE(10); } %merge<MergeRule>
286 NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge<MergeRule>
287 | NT5 { $$ = RULE(12) | $1; } %merge<MergeRule>
292 static int MergeRule (int x0, int x1) {
296 static void yyerror(char const * s) {
297 fprintf(stderr,"error: %s\n",s);
302 int P[] = { P1, P2 };
303 int O[] = { O1, O2 };
304 int T[] = { T1, T2, T3, T4 };
311 if (fscanf (input, "%2s", inp) == EOF)
315 case 'p': return P[inp[1] - '1'];
316 case 't': return T[inp[1] - '1'];
317 case 'o': return O[inp[1] - '1'];
322 int main(int argc, char* argv[]) {
324 if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3;
329 AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
330 [glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce
332 AT_COMPILE([glr-regr3])
334 AT_PARSER_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]],
342 ## ------------------------------------------------------------------------- ##
343 ## Duplicate representation of merged trees. See ##
344 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>. ##
345 ## ------------------------------------------------------------------------- ##
347 AT_SETUP([Duplicate representation of merged trees])
349 AT_DATA_GRAMMAR([glr-regr4.y],
351 %union { char *ptr; }
352 %type <ptr> S A A1 A2 B
359 static char *merge (YYSTYPE, YYSTYPE);
360 static char *make_value (char const *, char const *);
361 static void yyerror (char const *);
362 static int yylex (void);
363 static char *ptrs[100];
364 static char **ptrs_next = ptrs;
369 tree: S { printf ("%s\n", $1); } ;
372 A %merge<merge> { $$ = make_value ("S", $1); }
373 | B %merge<merge> { $$ = make_value ("S", $1); }
377 A1 %merge<merge> { $$ = make_value ("A", $1); }
378 | A2 %merge<merge> { $$ = make_value ("A", $1); }
381 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
382 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
383 B: 'a' { $$ = make_value ("B", "'a'"); } ;
390 static char const input[] = "a";
391 static size_t toknum;
392 if (! (toknum < sizeof input))
394 return input[toknum++];
400 int status = yyparse ();
401 while (ptrs_next != ptrs)
407 make_value (char const *parent, char const *child)
409 char const format[] = "%s <- %s";
410 char *value = *ptrs_next++ =
411 (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
412 sprintf (value, format, parent, child);
417 merge (YYSTYPE s1, YYSTYPE s2)
419 char const format[] = "merge{ %s and %s }";
420 char *value = *ptrs_next++ =
421 (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
422 sprintf (value, format, s1.ptr, s2.ptr);
427 yyerror (char const *msg)
429 fprintf (stderr, "%s\n", msg);
433 AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
434 [glr-regr4.y: conflicts: 1 reduce/reduce
436 AT_COMPILE([glr-regr4])
438 AT_PARSER_CHECK([[./glr-regr4]], 0,
439 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
445 ## -------------------------------------------------------------------------- ##
446 ## User destructor for unresolved GLR semantic value. See ##
447 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>. ##
448 ## -------------------------------------------------------------------------- ##
450 AT_SETUP([User destructor for unresolved GLR semantic value])
452 AT_DATA_GRAMMAR([glr-regr5.y],
457 static void yyerror (char const *);
458 static int yylex (void);
459 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
463 %union { int value; }
467 if ($$ != MAGIC_VALUE)
469 fprintf (stderr, "Bad destructor call.\n");
477 'a' { $$ = MAGIC_VALUE; }
478 | 'a' { $$ = MAGIC_VALUE; }
486 static char const input[] = "a";
487 static size_t toknum;
488 if (! (toknum < sizeof input))
490 return input[toknum++];
494 yyerror (char const *msg)
496 fprintf (stderr, "%s\n", msg);
502 return yyparse () != 1;
506 AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
507 [glr-regr5.y: conflicts: 1 reduce/reduce
509 AT_COMPILE([glr-regr5])
511 AT_PARSER_CHECK([[./glr-regr5]], 0, [],
518 ## -------------------------------------------------------------------------- ##
519 ## User destructor after an error during a split parse. See ##
520 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>. ##
521 ## -------------------------------------------------------------------------- ##
523 AT_SETUP([User destructor after an error during a split parse])
525 AT_DATA_GRAMMAR([glr-regr6.y],
530 static void yyerror (char const *);
531 static int yylex (void);
535 %union { int value; }
539 printf ("Destructor called.\n");
551 static char const input[] = "a";
552 static size_t toknum;
553 if (! (toknum < sizeof input))
555 return input[toknum++];
559 yyerror (char const *msg)
561 fprintf (stderr, "%s\n", msg);
567 return yyparse () != 1;
571 AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
572 [glr-regr6.y: conflicts: 1 reduce/reduce
574 AT_COMPILE([glr-regr6])
576 AT_PARSER_CHECK([[./glr-regr6]], 0,
585 ## ------------------------------------------------------------------------- ##
586 ## Duplicated user destructor for lookahead. See ##
587 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>. ##
588 ## ------------------------------------------------------------------------- ##
590 AT_SETUP([Duplicated user destructor for lookahead])
592 AT_DATA_GRAMMAR([glr-regr7.y],
597 static void yyerror (char const *);
598 static int yylex (void);
599 #define YYSTACKEXPANDABLE 0
600 typedef struct count_node {
602 struct count_node *prev;
604 static count_node *tail;
608 %union { count_node *node; }
613 fprintf (stderr, "Destructor called on same value twice.\n");
631 yylval.node = (count_node*) malloc (sizeof *yylval.node);
634 fprintf (stderr, "Test inconclusive.\n");
637 yylval.node->count = 0;
638 yylval.node->prev = tail;
644 yyerror (char const *msg)
646 fprintf (stderr, "%s\n", msg);
652 int status = yyparse ();
655 count_node *prev = tail->prev;
663 AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
664 [glr-regr7.y: conflicts: 2 reduce/reduce
666 AT_COMPILE([glr-regr7])
668 AT_PARSER_CHECK([[./glr-regr7]], 2, [],
675 ## ------------------------------------------------------------------------- ##
676 ## Incorrect default location for empty right-hand sides. Adapted from bug ##
677 ## report by Claudia Hermann. ##
678 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
679 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html ##
680 ## ------------------------------------------------------------------------- ##
682 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
684 AT_DATA_GRAMMAR([glr-regr8.y],
689 static void yyerror (char const *);
690 static int yylex (void);
691 static void yyerror (char const *msg);
703 PortClause : T_PORT InterfaceDeclaration T_PORT
704 { printf("%d/%d - %d/%d - %d/%d\n",
705 @1.first_column, @1.last_column,
706 @2.first_column, @2.last_column,
707 @3.first_column, @3.last_column); }
710 InterfaceDeclaration : OptConstantWord %dprec 1
711 | OptSignalWord %dprec 2
714 OptConstantWord : /* empty */
718 OptSignalWord : /* empty */
719 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
726 yyerror (char const *msg)
728 fprintf (stderr, "%s\n", msg);
741 yylloc.first_column = 1;
742 yylloc.last_column = 9;
745 yylloc.first_column = 13;
746 yylloc.last_column = 17;
761 AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
762 [glr-regr8.y: conflicts: 1 reduce/reduce
764 AT_COMPILE([glr-regr8])
766 AT_PARSER_CHECK([[./glr-regr8]], 0,
775 ## ------------------------------------------------------------------------- ##
776 ## No users destructors if stack 0 deleted. See ##
777 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
778 ## ------------------------------------------------------------------------- ##
780 AT_SETUP([No users destructors if stack 0 deleted])
782 AT_DATA_GRAMMAR([glr-regr9.y],
787 static void yyerror (char const *);
788 static int yylex (void);
789 # define YYSTACKEXPANDABLE 0
790 static int tokens = 0;
791 static int destructors = 0;
796 %union { int dummy; }
806 ambig0 'a' { destructors += 2; USE ($2); }
807 | ambig1 start { destructors += 1; }
808 | ambig2 start { destructors += 1; }
825 yyerror (char const *msg)
827 fprintf (stderr, "%s\n", msg);
834 exit_status = yyparse ();
835 if (tokens != destructors)
837 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
844 AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
845 [glr-regr9.y: conflicts: 1 reduce/reduce
847 AT_COMPILE([glr-regr9])
849 AT_PARSER_CHECK([[./glr-regr9]], 0, [],
856 ## ------------------------------------------------------------------------- ##
857 ## Corrupted semantic options if user action cuts parse. ##
858 ## ------------------------------------------------------------------------- ##
860 AT_SETUP([Corrupted semantic options if user action cuts parse])
862 AT_DATA_GRAMMAR([glr-regr10.y],
867 static void yyerror (char const *);
868 static int yylex (void);
869 #define GARBAGE_SIZE 50
870 static char garbage[GARBAGE_SIZE];
874 %union { char *ptr; }
880 %dprec 2 { $$ = garbage; YYACCEPT; }
881 | %dprec 1 { $$ = garbage; YYACCEPT; }
887 yyerror (char const *msg)
889 fprintf (stderr, "%s\n", msg);
905 for (i = 0; i < GARBAGE_SIZE; i+=1)
911 AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
912 [glr-regr10.y: conflicts: 1 reduce/reduce
914 AT_COMPILE([glr-regr10])
916 AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
921 ## ------------------------------------------------------------------------- ##
922 ## Undesirable destructors if user action cuts parse. ##
923 ## ------------------------------------------------------------------------- ##
925 AT_SETUP([Undesirable destructors if user action cuts parse])
927 AT_DATA_GRAMMAR([glr-regr11.y],
931 static void yyerror (char const *);
932 static int yylex (void);
933 static int destructors = 0;
938 %union { int dummy; }
940 %destructor { destructors += 1; } 'a'
945 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
946 | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
952 yyerror (char const *msg)
954 fprintf (stderr, "%s\n", msg);
960 static char const input[] = "a";
961 static size_t toknum;
962 if (! (toknum < sizeof input))
964 return input[toknum++];
970 int exit_status = yyparse ();
971 if (destructors != 1)
973 fprintf (stderr, "Destructor calls: %d\n", destructors);
980 AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
981 [glr-regr11.y: conflicts: 1 reduce/reduce
983 AT_COMPILE([glr-regr11])
985 AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
990 ## ------------------------------------------------------------------------- ##
991 ## Leaked semantic values if user action cuts parse. ##
992 ## ------------------------------------------------------------------------- ##
994 AT_SETUP([Leaked semantic values if user action cuts parse])
996 AT_DATA_GRAMMAR([glr-regr12.y],
999 %union { int dummy; }
1000 %token PARENT_RHS_AFTER
1001 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
1002 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1003 %destructor { merged_value = 0; } merged
1004 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
1007 # include <stdlib.h>
1008 static int merge (YYSTYPE, YYSTYPE);
1009 static void yyerror (char const *);
1010 static int yylex (void);
1011 static int parent_rhs_before_value = 0;
1012 static int merged_value = 0;
1013 static int parent_rhs_after_value = 0;
1027 parent_rhs_after_value = 0;
1032 parent_rhs_before merged PARENT_RHS_AFTER {
1034 parent_rhs_before_value = 0;
1036 parent_rhs_after_value = 0;
1043 parent_rhs_before_value = 1;
1052 | cut %merge<merge> {
1058 cut: { YYACCEPT; } ;
1063 merge (YYSTYPE s1, YYSTYPE s2)
1066 char dummy = s1.dummy + s2.dummy;
1071 yyerror (char const *msg)
1073 fprintf (stderr, "%s\n", msg);
1079 static int const input[] = { PARENT_RHS_AFTER, 0 };
1080 static size_t toknum;
1081 if (! (toknum < sizeof input / sizeof *input))
1083 if (input[toknum] == PARENT_RHS_AFTER)
1084 parent_rhs_after_value = 1;
1085 return input[toknum++];
1091 int exit_status = yyparse ();
1092 if (parent_rhs_before_value)
1094 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1099 fprintf (stderr, "`merged' destructor not called.\n");
1102 if (parent_rhs_after_value)
1104 fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
1111 AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
1112 [glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
1114 AT_COMPILE([glr-regr12])
1116 AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
1121 ## ------------------------------------------------------------------------- ##
1122 ## Incorrect lookahead during deterministic GLR. See ##
1123 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and ##
1124 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>. ##
1125 ## ------------------------------------------------------------------------- ##
1127 AT_SETUP([Incorrect lookahead during deterministic GLR])
1129 AT_DATA_GRAMMAR([glr-regr13.y],
1132 - Defaulted state with initial yychar: yychar == YYEMPTY.
1133 - Nondefaulted state: yychar != YYEMPTY.
1134 - Defaulted state after lookahead: yychar != YYEMPTY.
1135 - Defaulted state after shift: yychar == YYEMPTY.
1136 - User action changing the lookahead. */
1140 static void yyerror (char const *);
1141 static int yylex (void);
1142 static void print_lookahead (char const *);
1146 %union { char value; }
1147 %type <value> 'a' 'b'
1154 defstate_init defstate_shift 'b' change_lookahead 'a' {
1156 print_lookahead ("start <- defstate_init defstate_shift 'b'");
1161 print_lookahead ("defstate_init <- empty string");
1165 nondefstate defstate_look 'a' {
1167 print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1172 print_lookahead ("defstate_look <- empty string");
1177 print_lookahead ("nondefstate <- empty string");
1181 print_lookahead ("nondefstate <- 'b'");
1193 yyerror (char const *msg)
1195 fprintf (stderr, "%s\n", msg);
1201 static char const input[] = "ab";
1202 static size_t toknum;
1203 if (! (toknum < sizeof input))
1205 yylloc.first_line = yylloc.last_line = 1;
1206 yylloc.first_column = yylloc.last_column = toknum + 1;
1207 yylval.value = input[toknum] + 'A' - 'a';
1208 return input[toknum++];
1212 print_lookahead (char const *reduction)
1214 printf ("%s:\n yychar=", reduction);
1215 if (yychar == YYEMPTY)
1217 else if (yychar == YYEOF)
1221 printf ("'%c', yylval='", yychar);
1222 if (yylval.value > ' ')
1223 printf ("%c", yylval.value);
1224 printf ("', yylloc=(%d,%d),(%d,%d)",
1225 yylloc.first_line, yylloc.first_column,
1226 yylloc.last_line, yylloc.last_column);
1234 yychar = '#'; /* Not a token in the grammar. */
1240 AT_BISON_CHECK([[-o glr-regr13.c glr-regr13.y]], 0, [], [])
1241 AT_COMPILE([glr-regr13])
1243 AT_PARSER_CHECK([[./glr-regr13]], 0,
1244 [defstate_init <- empty string:
1246 nondefstate <- empty string:
1247 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1248 defstate_look <- empty string:
1249 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1250 defstate_shift <- nondefstate defstate_look 'a':
1252 start <- defstate_init defstate_shift 'b':
1259 ## ------------------------------------------------------------------------- ##
1260 ## Incorrect lookahead during nondeterministic GLR. ##
1261 ## ------------------------------------------------------------------------- ##
1263 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1265 AT_DATA_GRAMMAR([glr-regr14.y],
1268 - Conflicting actions (split-off parse, which copies lookahead need,
1269 which is necessarily yytrue) and nonconflicting actions (non-split-off
1270 parse) for nondefaulted state: yychar != YYEMPTY.
1271 - Merged deferred actions (lookahead need and RHS from different stack
1272 than the target state) and nonmerged deferred actions (same stack).
1273 - Defaulted state after lookahead: yychar != YYEMPTY.
1274 - Defaulted state after shift: yychar == YYEMPTY.
1275 - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1276 seen the lookahead but current stack has not).
1277 - Exceeding stack capacity (stack explosion), and thus reallocating
1278 lookahead need array.
1279 Note that it does not seem possible to see the initial yychar value during
1280 nondeterministic operation since:
1281 - In order to preserve the initial yychar, only defaulted states may be
1283 - If only defaulted states are entered, there are no conflicts, so
1284 nondeterministic operation does not start. */
1286 %union { char value; }
1291 static void yyerror (char const *);
1292 static int yylex (void);
1293 static void print_lookahead (char const *);
1294 static char merge (union YYSTYPE, union YYSTYPE);
1298 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1305 merge 'c' stack_explosion {
1307 print_lookahead ("start <- merge 'c' stack_explosion");
1311 /* When merging the 2 deferred actions, the lookahead needs are different. */
1313 nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1315 print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1317 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1319 print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1326 print_lookahead ("nonconflict1 <- empty string");
1331 print_lookahead ("nonconflict2 <- empty string");
1335 print_lookahead ("nonconflict2 <- 'a'");
1340 print_lookahead ("conflict <- empty string");
1345 print_lookahead ("defstate_look <- empty string");
1349 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1352 print_lookahead ("defstate_shift <- empty string");
1358 | alt1 stack_explosion %merge<merge> { $$ = $2; }
1359 | alt2 stack_explosion %merge<merge> { $$ = $2; }
1360 | alt3 stack_explosion %merge<merge> { $$ = $2; }
1365 if (yychar != 'd' && yychar != YYEOF)
1367 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1374 if (yychar != 'd' && yychar != YYEOF)
1376 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1383 if (yychar != 'd' && yychar != YYEOF)
1385 fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1391 if (yychar != YYEMPTY)
1394 "Found lookahead where shouldn't during stack explosion.\n");
1402 yyerror (char const *msg)
1404 fprintf (stderr, "%s\n", msg);
1410 static char const input[] = "abcdddd";
1411 static size_t toknum;
1412 if (! (toknum < sizeof input))
1414 yylloc.first_line = yylloc.last_line = 1;
1415 yylloc.first_column = yylloc.last_column = toknum + 1;
1416 yylval.value = input[toknum] + 'A' - 'a';
1417 return input[toknum++];
1421 print_lookahead (char const *reduction)
1423 printf ("%s:\n yychar=", reduction);
1424 if (yychar == YYEMPTY)
1426 else if (yychar == YYEOF)
1430 printf ("'%c', yylval='", yychar);
1431 if (yylval.value > ' ')
1432 printf ("%c", yylval.value);
1433 printf ("', yylloc=(%d,%d),(%d,%d)",
1434 yylloc.first_line, yylloc.first_column,
1435 yylloc.last_line, yylloc.last_column);
1441 merge (union YYSTYPE s1, union YYSTYPE s2)
1443 char dummy = s1.value + s2.value;
1450 yychar = '#'; /* Not a token in the grammar. */
1456 AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
1457 [glr-regr14.y: conflicts: 3 reduce/reduce
1459 AT_COMPILE([glr-regr14])
1461 AT_PARSER_CHECK([[./glr-regr14]], 0,
1462 [conflict <- empty string:
1463 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1464 defstate_look <- empty string:
1465 yychar='a', yylval='A', yylloc=(1,1),(1,1)
1466 nonconflict2 <- empty string:
1467 yychar='b', yylval='B', yylloc=(1,2),(1,2)
1468 defstate_shift <- empty string:
1470 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1472 start <- merge 'c' stack_explosion:
1479 ## ------------------------------------------------------------------------- ##
1480 ## Leaked semantic values when reporting ambiguity. ##
1481 ## ------------------------------------------------------------------------- ##
1483 AT_SETUP([Leaked semantic values when reporting ambiguity])
1485 AT_DATA_GRAMMAR([glr-regr15.y],
1488 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1491 # include <stdlib.h>
1492 static void yyerror (char const *);
1493 static int yylex (void);
1494 static int parent_rhs_before_value = 0;
1505 /* This stack must be merged into the other stacks *last* (added at the
1506 beginning of the semantic options list) so that yyparse will choose to clean
1507 it up rather than the tree for which some semantic actions have been
1508 performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1509 those other trees are not cleaned up. */
1513 parent_rhs_before ambiguity {
1515 parent_rhs_before_value = 0;
1522 parent_rhs_before_value = 1;
1526 ambiguity: ambiguity1 | ambiguity2 ;
1533 yyerror (char const *msg)
1535 fprintf (stderr, "%s\n", msg);
1550 int exit_status = yyparse () != 1;
1551 if (parent_rhs_before_value)
1553 fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
1560 AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
1561 [glr-regr15.y: conflicts: 2 reduce/reduce
1563 AT_COMPILE([glr-regr15])
1565 AT_PARSER_CHECK([[./glr-regr15]], 0, [],
1566 [syntax is ambiguous
1572 ## ------------------------------------------------------------------------- ##
1573 ## Leaked lookahead after nondeterministic parse syntax error. ##
1574 ## ------------------------------------------------------------------------- ##
1576 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1577 AT_DATA_GRAMMAR([glr-regr16.y],
1580 %destructor { lookahead_value = 0; } 'b'
1583 # include <stdlib.h>
1584 static void yyerror (char const *);
1585 static int yylex (void);
1586 static int lookahead_value = 0;
1592 start: alt1 'a' | alt2 'a' ;
1599 yyerror (char const *msg)
1601 fprintf (stderr, "%s\n", msg);
1607 static char const input[] = "ab";
1608 static size_t toknum;
1609 if (! (toknum < sizeof input))
1611 if (input[toknum] == 'b')
1612 lookahead_value = 1;
1613 return input[toknum++];
1619 int exit_status = yyparse () != 1;
1620 if (lookahead_value)
1622 fprintf (stderr, "Lookahead destructor not called.\n");
1629 AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
1630 [glr-regr16.y: conflicts: 1 reduce/reduce
1632 AT_COMPILE([glr-regr16])
1634 AT_PARSER_CHECK([[./glr-regr16]], 0, [],
1641 ## ------------------------------------------------------------------------- ##
1642 ## Uninitialized location when reporting ambiguity. ##
1643 ## ------------------------------------------------------------------------- ##
1645 AT_SETUP([Uninitialized location when reporting ambiguity])
1646 AT_DATA_GRAMMAR([glr-regr17.y],
1653 %union { int dummy; }
1656 static void yyerror (YYLTYPE *, char const *);
1657 static int yylex (YYSTYPE *, YYLTYPE *);
1662 @$.first_column = 1;
1669 /* Tests the case of an empty RHS that has inherited the location of the
1670 previous nonterminal, which is unresolved. That location is reported as the
1671 last position of the ambiguity. */
1672 start: ambig1 empty1 | ambig2 empty2 ;
1674 /* Tests multiple levels of yyresolveLocations recursion. */
1675 ambig1: sub_ambig1 | sub_ambig2 ;
1676 ambig2: sub_ambig1 | sub_ambig2 ;
1678 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1679 has inherited the initial location. The empty RHS's location is reported as
1680 the first position in the ambiguity. */
1681 sub_ambig1: empty1 'a' 'b' ;
1682 sub_ambig2: empty2 'a' 'b' ;
1689 yyerror (YYLTYPE *locp, char const *msg)
1691 fprintf (stderr, "Error at %d.%d-%d.%d: %s.\n", locp->first_line,
1692 locp->first_column, locp->last_line, locp->last_column, msg);
1696 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1698 static char const input[] = "ab";
1699 static size_t toknum;
1700 if (! (toknum < sizeof input))
1703 llocp->first_line = llocp->last_line = 2;
1704 llocp->first_column = toknum + 1;
1705 llocp->last_column = llocp->first_column + 1;
1706 return input[toknum++];
1712 return yyparse () != 1;
1716 AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
1717 [glr-regr17.y: conflicts: 3 reduce/reduce
1719 AT_COMPILE([glr-regr17])
1721 AT_PARSER_CHECK([[./glr-regr17]], 0, [],
1722 [Error at 1.1-2.3: syntax is ambiguous.
1728 ## -------------------------------------------------------------##
1729 ## Missed %merge type warnings when LHS type is declared later. ##
1730 ## -------------------------------------------------------------##
1732 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1733 AT_DATA_GRAMMAR([glr-regr18.y],
1738 static void yyerror (char const *);
1739 static int yylex ();
1750 sym1: sym2 %merge<merge> { $$ = $1; } ;
1751 sym2: sym3 %merge<merge> { $$ = $1; } ;
1752 sym3: %merge<merge> { $$ = 0; } ;
1761 yyerror (char const *msg)
1763 fprintf (stderr, "%s\n", msg);
1782 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
1783 [glr-regr18.y:26.18-24: result type clash on merge function `merge': <type2> != <type1>
1784 glr-regr18.y:25.18-24: previous declaration
1785 glr-regr18.y:27.13-19: result type clash on merge function `merge': <type3> != <type2>
1786 glr-regr18.y:26.18-24: previous declaration