glr.cc, glr2.cc: don't publish compiler pragmas
[bison.git] / tests / glr-regression.at
blobf59647566246b39a7122d5f2d9389a3d9769d7bc
1 # Checking GLR Parsing: Regression Tests           -*- Autotest -*-
3 # Copyright (C) 2002-2003, 2005-2007, 2009-2015, 2018-2020 Free Software
4 # Foundation, Inc.
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 */
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <assert.h>
37 #define YYSTYPE int
38 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
39 ]AT_YYERROR_DECLARE[
40 ]AT_YYLEX_DECLARE[
44 %define parse.assert
45 %glr-parser
47 /* -------- productions ------ */
50 StartSymbol: E  { $$=0; }                   %merge <exprMerge>
51            ;
53 E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); }  %merge <exprMerge>
54  | 'B'     { $$=2; printf("E -> 'B'\n"); }      %merge <exprMerge>
55  ;
59 /* ---------- C code ----------- */
62 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
64   (void) x0;
65   (void) x1;
66   printf ("<OR>\n");
67   return 0;
70 const char *input = YY_NULLPTR;
72 int
73 main (int argc, const char* argv[])
75   assert (argc == 2); (void) argc;
76   input = argv[1];
77   return yyparse ();
80 ]AT_YYERROR_DEFINE[
82 int
83 yylex (void)
85   return *input++;
87 ]])
88 AT_BISON_OPTION_POPDEFS
90 AT_BISON_CHECK([[-o glr-regr1.c -rall glr-regr1.y]], 0, [],
91 [[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
92 glr-regr1.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
93 ]])
94 AT_COMPILE([glr-regr1])
95 AT_PARSER_CHECK([[glr-regr1 BPBPB]], 0,
96 [[E -> 'B'
97 E -> 'B'
98 E -> E 'P' E
99 E -> 'B'
100 E -> E 'P' E
101 E -> 'B'
102 E -> E 'P' E
103 E -> E 'P' E
104 <OR>
105 ]], [])
107 AT_CLEANUP
109 ## -------------------------------------------------------------- ##
110 ## Improper handling of embedded actions and $-N in GLR parsers.  ##
111 ## -------------------------------------------------------------- ##
113 AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers])
115 AT_BISON_OPTION_PUSHDEFS
116 AT_DATA_GRAMMAR([glr-regr2a.y],
117 [[/* Regression Test: Improper handling of embedded actions and $-N  */
118 /* Reported by S. Eken */
121   #define YYSTYPE char *
123   #include <ctype.h>
124   #include <stdio.h>
125   #include <stdlib.h>
126   #include <string.h>
127   #include <assert.h>
128   ]AT_YYERROR_DECLARE[
129   ]AT_YYLEX_DECLARE[
132 %define parse.assert
133 %glr-parser
137 command:
138     's' var 't'
139        { printf ("Variable: '%s'\n", $2); }
140     'v' 'x' 'q'
141        { free ($2); }
142   | 's' var_list 't' 'e'
143        { printf ("Varlist: '%s'\n", $2); free ($2); }
144   | 's' var 't' var_printer 'x'
145        { free ($2); }
146   ;
148 var:
149   'V'
150      { $$ = $1; }
151   ;
153 var_list:
154   var
155     { $$ = $1; }
156   | var ',' var_list
157     {
158       char *s = YY_CAST (char *, realloc ($1, strlen ($1) + 1 + strlen ($3) + 1));
159       strcat (s, ",");
160       strcat (s, $3);
161       free ($3);
162       $$ = s;
163     }
164   ;
166 var_printer: 'v'
167    { printf ("Variable: '%s'\n", $-1); }
170 ]AT_YYERROR_DEFINE[
171 FILE *input;
174 yylex (void)
176   char buf[50];
177   assert (!feof (stdin));
178   switch (fscanf (input, " %1[a-z,]", buf))
179   {
180   case 1:
181     return buf[0];
182   case EOF:
183     return 0;
184   default:
185     if (fscanf (input, "%49s", buf) != 1)
186       return 0;
187     else
188       {
189         char *s;
190         assert (strlen (buf) < sizeof buf - 1);
191         s = YY_CAST (char *, malloc (strlen (buf) + 1));
192         strcpy (s, buf);
193         yylval = s;
194         return 'V';
195       }
196     break;
197   }
201 main (int argc, char **argv)
203   int res;
204   input = stdin;
205   if (argc == 2 && !(input = fopen (argv[1], "r")))
206     return 3;
207   res = yyparse ();
208   if (argc == 2 && fclose (input))
209     return 4;
210   return res;
213 AT_BISON_OPTION_POPDEFS
215 AT_BISON_CHECK([[-o glr-regr2a.c -rall glr-regr2a.y]], 0, [],
216 [[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
217 glr-regr2a.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
219 AT_COMPILE([glr-regr2a])
221 AT_DATA([input1.txt],
222 [[s VARIABLE_1 t v x q
224 AT_PARSER_CHECK([[glr-regr2a input1.txt]], 0,
225 [[Variable: 'VARIABLE_1'
228 AT_DATA([input2.txt],
229 [[s VARIABLE_1 , ANOTHER_VARIABLE_2 t e
231 AT_PARSER_CHECK([[glr-regr2a input2.txt]],
233 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
236 AT_DATA([input3.txt],
237 [[s VARIABLE_3 t v x
239 AT_PARSER_CHECK([[glr-regr2a input3.txt]], 0,
240 [[Variable: 'VARIABLE_3'
244 AT_CLEANUP
246 ## --------------------------------------------- ##
247 ## Improper merging of GLR delayed action sets.  ##
248 ## --------------------------------------------- ##
250 AT_SETUP([Improper merging of GLR delayed action sets])
252 AT_BISON_OPTION_PUSHDEFS
253 AT_DATA_GRAMMAR([glr-regr3.y],
254 [[/* Regression Test: Improper merging of GLR delayed action sets.  */
255 /* Reported by M. Rosien */
258 #include <stdio.h>
259 #include <stdlib.h>
260 #include <stdarg.h>
261 #include <assert.h>
263 static int MergeRule (int x0, int x1);
264 ]AT_YYERROR_DECLARE[
265 ]AT_YYLEX_DECLARE[
267 #define RULE(x) (1 << (x))
271 %define parse.assert
272 %glr-parser
274 %token BAD_CHAR
275 %token P1 P2 T1 T2 T3 T4 O1 O2
279 S : P1 T4 O2 NT6 P2  { printf ("Result: %x\n", $4); }
282 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); }  %merge<MergeRule>
285 NT2 : NT1             { $$ = RULE(3); } %merge<MergeRule>
286     | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
289 NT3 : T3              { $$ = RULE(5); } %merge<MergeRule>
290     | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
293 NT4 : NT3              { $$ = RULE(7); } %merge<MergeRule>
294     | NT2              { $$ = RULE(8); } %merge<MergeRule>
295     | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
298 NT5 : NT4              { $$ = RULE(10); } %merge<MergeRule>
301 NT6 : P1 NT1 O1 T3 P2  { $$ = RULE(11) | $2; } %merge<MergeRule>
302     | NT5              { $$ = RULE(12) | $1; } %merge<MergeRule>
307 static int
308 MergeRule (int x0, int x1)
310   return x0 | x1;
312 ]AT_YYERROR_DEFINE[
314 FILE *input = YY_NULLPTR;
316 int P[] = { P1, P2 };
317 int O[] = { O1, O2 };
318 int T[] = { T1, T2, T3, T4 };
320 int yylex (void)
322   char inp[3];
323   assert (!feof (stdin));
324   if (fscanf (input, "%2s", inp) == EOF)
325     return 0;
326   switch (inp[0])
327     {
328     case 'p': return P[inp[1] - '1'];
329     case 't': return T[inp[1] - '1'];
330     case 'o': return O[inp[1] - '1'];
331     }
332   return BAD_CHAR;
336 main (int argc, char* argv[])
338   int res;
339   input = stdin;
340   if (argc == 2 && !(input = fopen (argv[1], "r")))
341     return 3;
342   res = yyparse ();
343   if (argc == 2 && fclose (input))
344     return 4;
345   return res;
348 AT_BISON_OPTION_POPDEFS
350 AT_BISON_CHECK([[-o glr-regr3.c -rall glr-regr3.y]], 0, [],
351 [[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
352 glr-regr3.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
353 glr-regr3.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
355 AT_COMPILE([glr-regr3])
357 AT_DATA([input.txt],
358 [[p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2
360 AT_PARSER_CHECK([[glr-regr3 input.txt]],
362 [[Result: 1c04
365 AT_CLEANUP
368 ## ---------------------------------------------------------------------- ##
369 ## Duplicate representation of merged trees.  See                         ##
370 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>.  ##
371 ## ---------------------------------------------------------------------- ##
373 AT_SETUP([Duplicate representation of merged trees])
375 AT_BISON_OPTION_PUSHDEFS
376 AT_DATA_GRAMMAR([glr-regr4.y],
378 %define parse.assert
379 %union { char *ptr; }
380 %type <ptr> S A A1 A2 B
381 %glr-parser
384   #include <stdio.h>
385   #include <stdlib.h>
386   #include <string.h>
387   static char *merge (YYSTYPE, YYSTYPE);
388   static char *make_value (char const *, char const *);
389   ]AT_YYERROR_DECLARE[
390   ]AT_YYLEX_DECLARE[
391   static char *ptrs[100];
392   static char **ptrs_next = ptrs;
397 tree: S { printf ("%s\n", $1); } ;
400   A   %merge<merge> { $$ = make_value ("S", $1); }
401   | B %merge<merge> { $$ = make_value ("S", $1); }
402   ;
405   A1   %merge<merge> { $$ = make_value ("A", $1); }
406   | A2 %merge<merge> { $$ = make_value ("A", $1); }
407   ;
409 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
410 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
411 B:  'a' { $$ = make_value ("B", "'a'");  } ;
414 ]AT_YYERROR_DEFINE[
415 ]AT_YYLEX_DEFINE(["a"])[
418 main (void)
420   int status = yyparse ();
421   while (ptrs_next != ptrs)
422     free (*--ptrs_next);
423   return status;
426 static char *
427 make_value (char const *parent, char const *child)
429   char const format[] = "%s <- %s";
430   char *value = *ptrs_next++ =
431     YY_CAST (char *, malloc (strlen (parent) + strlen (child) + sizeof format));
432   sprintf (value, format, parent, child);
433   return value;
436 static char *
437 merge (YYSTYPE s1, YYSTYPE s2)
439   char const format[] = "merge{ %s and %s }";
440   char *value = *ptrs_next++ =
441     YY_CAST (char *, malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format));
442   sprintf (value, format, s1.ptr, s2.ptr);
443   return value;
446 AT_BISON_OPTION_POPDEFS
448 AT_BISON_CHECK([[-o glr-regr4.c -rall glr-regr4.y]], 0, [],
449 [[glr-regr4.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
450 glr-regr4.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
452 AT_COMPILE([glr-regr4])
454 AT_PARSER_CHECK([[glr-regr4]], 0,
455 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
456 ]], [])
458 AT_CLEANUP
461 ## ------------------------------------------------------------------------- ##
462 ## User destructor for unresolved GLR semantic value.  See                   ##
463 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>.  ##
464 ## ------------------------------------------------------------------------- ##
466 AT_SETUP([User destructor for unresolved GLR semantic value])
468 AT_BISON_OPTION_PUSHDEFS
469 AT_DATA_GRAMMAR([glr-regr5.y],
472   #include <stdio.h>
473   #include <stdlib.h>
474   ]AT_YYERROR_DECLARE[
475   ]AT_YYLEX_DECLARE[
476   enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
479 %define parse.assert
480 %glr-parser
481 %union { int value; }
482 %type <value> start
484 %destructor {
485   if ($$ != MAGIC_VALUE)
486     {
487       fprintf (stderr, "Bad destructor call.\n");
488       exit (EXIT_FAILURE);
489     }
490 } start
494 start:
495    'a' { $$ = MAGIC_VALUE; }
496    | 'a' { $$ = MAGIC_VALUE; }
497    ;
500 ]AT_YYERROR_DEFINE[
501 ]AT_YYLEX_DEFINE(["a"])[
502 ]AT_MAIN_DEFINE[
504 AT_BISON_OPTION_POPDEFS
506 AT_BISON_CHECK([[-o glr-regr5.c -rall glr-regr5.y]], 0, [],
507 [[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
508 glr-regr5.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
510 AT_COMPILE([glr-regr5])
512 AT_PARSER_CHECK([[glr-regr5]], 1, [],
513 [syntax is ambiguous
516 AT_CLEANUP
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_BISON_OPTION_PUSHDEFS
527 AT_DATA_GRAMMAR([glr-regr6.y],
530   #include <stdio.h>
531   #include <stdlib.h>
532   ]AT_YYERROR_DECLARE[
533   ]AT_YYLEX_DECLARE[
536 %define parse.assert
537 %glr-parser
538 %union { int value; }
539 %type <value> 'a'
541 %destructor {
542   printf ("Destructor called.\n");
543 } 'a'
547 start: 'a' | 'a' ;
550 ]AT_YYERROR_DEFINE[
551 ]AT_YYLEX_DEFINE(["a"])[
552 ]AT_MAIN_DEFINE[
554 AT_BISON_OPTION_POPDEFS
556 AT_BISON_CHECK([[-o glr-regr6.c -rall glr-regr6.y]], 0, [],
557 [[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
558 glr-regr6.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
560 AT_COMPILE([glr-regr6])
562 AT_PARSER_CHECK([[glr-regr6]], 1,
563 [Destructor called.
565 [syntax is ambiguous
568 AT_CLEANUP
571 ## ------------------------------------------------------------------------- ##
572 ## Duplicated user destructor for lookahead.  See                            ##
573 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>.  ##
574 ## ------------------------------------------------------------------------- ##
576 AT_SETUP([Duplicated user destructor for lookahead])
578 AT_BISON_OPTION_PUSHDEFS
579 AT_DATA_GRAMMAR([glr-regr7.y],
582   #include <stdio.h>
583   #include <stdlib.h>
584   ]AT_YYERROR_DECLARE[
585   ]AT_YYLEX_DECLARE[
586   #define YYSTACKEXPANDABLE 0
587   typedef struct count_node {
588     int count;
589     struct count_node *prev;
590   } count_node;
591   static count_node *tail;
594 %define parse.assert
595 %glr-parser
596 %union { count_node *node; }
597 %type <node> 'a'
599 %destructor {
600   if ($$->count++)
601     fprintf (stderr, "Destructor called on same value twice.\n");
602 } 'a'
606 start:
607     stack1 start
608   | stack2 start
609   | %empty
610   ;
611 stack1: 'a' ;
612 stack2: 'a' ;
616 static int
617 yylex (void)
619   yylval.node = YY_CAST (count_node*, malloc (sizeof *yylval.node));
620   if (!yylval.node)
621     {
622       fprintf (stderr, "Test inconclusive.\n");
623       exit (EXIT_FAILURE);
624     }
625   yylval.node->count = 0;
626   yylval.node->prev = tail;
627   tail = yylval.node;
628   return 'a';
631 ]AT_YYERROR_DEFINE[
633 main (void)
635   int status = yyparse ();
636   while (tail)
637     {
638       count_node *prev = tail->prev;
639       free (tail);
640       tail = prev;
641     }
642   return status;
645 AT_BISON_OPTION_POPDEFS
647 AT_BISON_CHECK([[-o glr-regr7.c -rall glr-regr7.y]], 0, [],
648 [[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
649 glr-regr7.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
651 AT_COMPILE([glr-regr7])
653 AT_PARSER_CHECK([[glr-regr7]], 2, [],
654 [memory exhausted
657 AT_CLEANUP
660 ## ------------------------------------------------------------------------- ##
661 ## Incorrect default location for empty right-hand sides.  Adapted from bug  ##
662 ## report by Claudia Hermann.                                                ##
663 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
664 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html         ##
665 ## ------------------------------------------------------------------------- ##
667 AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR])
669 AT_BISON_OPTION_PUSHDEFS
670 AT_DATA_GRAMMAR([glr-regr8.y],
673   #include <stdio.h>
674   #include <stdlib.h>
675   ]AT_YYERROR_DECLARE[
676   ]AT_YYLEX_DECLARE[
679 %token T_CONSTANT
680 %token T_PORT
681 %token T_SIGNAL
683 %define parse.assert
684 %glr-parser
689 PortClause      : T_PORT InterfaceDeclaration T_PORT
690                 { printf("%d/%d - %d/%d - %d/%d\n",
691                          @1.first_column, @1.last_column,
692                          @2.first_column, @2.last_column,
693                          @3.first_column, @3.last_column); }
694         ;
696 InterfaceDeclaration    : OptConstantWord       %dprec 1
697         | OptSignalWord %dprec 2
698         ;
700 OptConstantWord : %empty
701         | T_CONSTANT
702         ;
704 OptSignalWord   : %empty
705                 { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
706         | T_SIGNAL
707         ;
711 ]AT_YYERROR_DEFINE[
712 static int lexIndex;
714 int yylex (void)
716   lexIndex += 1;
717   switch (lexIndex)
718     {
719     default:
720       abort ();
721     case 1:
722       yylloc.first_column = 1;
723       yylloc.last_column = 9;
724       return T_PORT;
725     case 2:
726       yylloc.first_column = 13;
727       yylloc.last_column = 17;
728       return T_PORT;
729     case 3:
730       return 0;
731     }
734 ]AT_MAIN_DEFINE[
736 AT_BISON_OPTION_POPDEFS
738 AT_BISON_CHECK([[-o glr-regr8.c -rall glr-regr8.y]], 0, [],
739 [[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
740 glr-regr8.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
742 AT_COMPILE([glr-regr8])
744 AT_PARSER_CHECK([[glr-regr8]], 0,
745 [empty: 9/9
746 1/9 - 9/9 - 13/17
750 AT_CLEANUP
753 ## ------------------------------------------------------------------------- ##
754 ## No users destructors if stack 0 deleted.  See                             ##
755 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>.  ##
756 ## ------------------------------------------------------------------------- ##
758 AT_SETUP([No users destructors if stack 0 deleted])
760 AT_BISON_OPTION_PUSHDEFS
761 AT_DATA_GRAMMAR([glr-regr9.y],
764 # include <stdio.h>
765 # include <stdlib.h>
766   ]AT_YYERROR_DECLARE[
767   ]AT_YYLEX_DECLARE[
768 # define YYSTACKEXPANDABLE 0
769   static int tokens = 0;
770   static int destructors = 0;
771 # define USE(Var)
774 %define parse.assert
775 %glr-parser
776 %union { int dummy; }
777 %type <dummy> 'a'
779 %destructor {
780   destructors += 1;
781 } 'a'
785 start:
786     ambig0 'a'   { destructors += 2; USE ($2); }
787   | ambig1 start { destructors += 1; }
788   | ambig2 start { destructors += 1; }
789   ;
791 ambig0: 'a' ;
792 ambig1: 'a' ;
793 ambig2: 'a' ;
797 static int
798 yylex (void)
800   tokens += 1;
801   return 'a';
804 ]AT_YYERROR_DEFINE[
806 main (void)
808   int exit_status;
809   exit_status = yyparse ();
810   if (tokens != destructors)
811     {
812       fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
813       return 1;
814     }
815   return !exit_status;
818 AT_BISON_OPTION_POPDEFS
820 AT_BISON_CHECK([[-o glr-regr9.c -rall glr-regr9.y]], 0, [],
821 [[glr-regr9.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
822 glr-regr9.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
824 AT_COMPILE([glr-regr9])
826 AT_PARSER_CHECK([[glr-regr9]], 0, [],
827 [memory exhausted
830 AT_CLEANUP
833 ## ------------------------------------------------------ ##
834 ## Corrupted semantic options if user action cuts parse.  ##
835 ## ------------------------------------------------------ ##
837 AT_SETUP([Corrupted semantic options if user action cuts parse])
839 AT_BISON_OPTION_PUSHDEFS
840 AT_DATA_GRAMMAR([glr-regr10.y],
843 # include <stdlib.h>
844 # include <stdio.h>
845   ]AT_YYERROR_DECLARE[
846   ]AT_YYLEX_DECLARE[
847   #define GARBAGE_SIZE 50
848   static char garbage[GARBAGE_SIZE];
851 %define parse.assert
852 %glr-parser
853 %union { char *ptr; }
854 %type <ptr> start
858 start:
859     %dprec 2 { $$ = garbage; YYACCEPT; }
860   | %dprec 1 { $$ = garbage; YYACCEPT; }
861   ;
864 ]AT_YYERROR_DEFINE[
865 ]AT_YYLEX_DEFINE[
868 main (void)
870   int i;
871   for (i = 0; i < GARBAGE_SIZE; i+=1)
872     garbage[i] = 108;
873   return yyparse ();
876 AT_BISON_OPTION_POPDEFS
878 AT_BISON_CHECK([[-o glr-regr10.c -rall glr-regr10.y]], 0, [],
879 [[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
880 glr-regr10.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
882 AT_COMPILE([glr-regr10])
884 AT_PARSER_CHECK([[glr-regr10]], 0, [], [])
886 AT_CLEANUP
889 ## --------------------------------------------------- ##
890 ## Undesirable destructors if user action cuts parse.  ##
891 ## --------------------------------------------------- ##
893 AT_SETUP([Undesirable destructors if user action cuts parse])
895 AT_BISON_OPTION_PUSHDEFS
896 AT_DATA_GRAMMAR([glr-regr11.y],
899 # include <stdlib.h>
900   ]AT_YYERROR_DECLARE[
901   ]AT_YYLEX_DECLARE[
902   static int destructors = 0;
903 # define USE(val)
906 %define parse.assert
907 %glr-parser
908 %union { int dummy; }
909 %type <int> 'a'
910 %destructor { destructors += 1; } 'a'
914 start:
915     'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; }
916   | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; }
917   ;
921 ]AT_YYERROR_DEFINE[
922 ]AT_YYLEX_DEFINE(["a"])[
925 main (void)
927   int exit_status = yyparse ();
928   if (destructors != 1)
929     {
930       fprintf (stderr, "Destructor calls: %d\n", destructors);
931       return 1;
932     }
933   return exit_status;
936 AT_BISON_OPTION_POPDEFS
938 AT_BISON_CHECK([[-o glr-regr11.c -rall glr-regr11.y]], 0, [],
939 [[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
940 glr-regr11.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
942 AT_COMPILE([glr-regr11])
944 AT_PARSER_CHECK([[glr-regr11]], 0, [], [])
946 AT_CLEANUP
949 ## -------------------------------------------------- ##
950 ## Leaked semantic values if user action cuts parse.  ##
951 ## -------------------------------------------------- ##
953 AT_SETUP([Leaked semantic values if user action cuts parse])
955 AT_BISON_OPTION_PUSHDEFS
956 AT_DATA_GRAMMAR([glr-regr12.y],
958 %define parse.assert
959 %glr-parser
960 %union { int dummy; }
961 %token PARENT_RHS_AFTER
962 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
963 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
964 %destructor { merged_value = 0; } merged
965 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
968 # include <stdlib.h>
969 # include <assert.h>
970   static int merge (YYSTYPE, YYSTYPE);
971   ]AT_YYERROR_DECLARE[
972   ]AT_YYLEX_DECLARE[
973   static int parent_rhs_before_value = 0;
974   static int merged_value = 0;
975   static int parent_rhs_after_value = 0;
976 # define USE(val)
981 start:
982   alt1 %dprec 1
983   | alt2 %dprec 2
984   ;
986 alt1:
987   PARENT_RHS_AFTER {
988     USE ($1);
989     parent_rhs_after_value = 0;
990   }
991   ;
993 alt2:
994   parent_rhs_before merged PARENT_RHS_AFTER {
995     USE (($1, $2, $3));
996     parent_rhs_before_value = 0;
997     merged_value = 0;
998     parent_rhs_after_value = 0;
999   }
1000   ;
1002 parent_rhs_before:
1003   {
1004     USE ($$);
1005     parent_rhs_before_value = 1;
1006   }
1007   ;
1009 merged:
1010   %merge<merge> {
1011     USE ($$);
1012     merged_value = 1;
1013   }
1014   | cut %merge<merge> {
1015     USE ($$);
1016     merged_value = 1;
1017   }
1018   ;
1020 cut: { YYACCEPT; } ;
1024 static int
1025 merge (YYSTYPE s1, YYSTYPE s2)
1027   /* Not invoked. */
1028   return s1.dummy + s2.dummy;
1031 ]AT_YYERROR_DEFINE[
1032 ]AT_YYLEX_DEFINE([{ PARENT_RHS_AFTER, 0 }],
1033  [if (res == PARENT_RHS_AFTER)
1034     parent_rhs_after_value = 1;])[
1037 main (void)
1039   int exit_status = yyparse ();
1040   if (parent_rhs_before_value)
1041     {
1042       fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1043       exit_status = 1;
1044     }
1045   if (merged_value)
1046     {
1047       fprintf (stderr, "'merged' destructor not called.\n");
1048       exit_status = 1;
1049     }
1050   if (parent_rhs_after_value)
1051     {
1052       fprintf (stderr, "'PARENT_RHS_AFTER' destructor not called.\n");
1053       exit_status = 1;
1054     }
1055   return exit_status;
1058 AT_BISON_OPTION_POPDEFS
1060 AT_BISON_CHECK([[-o glr-regr12.c -rall glr-regr12.y]], 0, [],
1061 [[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
1062 glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1063 glr-regr12.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1065 AT_COMPILE([glr-regr12])
1067 AT_PARSER_CHECK([[glr-regr12]], 0, [], [])
1069 AT_CLEANUP
1072 ## ------------------------------------------------------------------------- ##
1073 ## Incorrect lookahead during deterministic GLR.  See                        ##
1074 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and  ##
1075 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>.  ##
1076 ## ------------------------------------------------------------------------- ##
1078 AT_SETUP([Incorrect lookahead during deterministic GLR])
1080 AT_BISON_OPTION_PUSHDEFS
1081 AT_DATA_GRAMMAR([glr-regr13.y],
1083 /* Tests:
1084      - Defaulted state with initial yychar: yychar == YYEMPTY.
1085      - Nondefaulted state: yychar != YYEMPTY.
1086      - Defaulted state after lookahead: yychar != YYEMPTY.
1087      - Defaulted state after shift: yychar == YYEMPTY.
1088      - User action changing the lookahead.  */
1091   #include <stdio.h>
1092   #include <assert.h>
1093   ]AT_YYERROR_DECLARE[
1094   ]AT_YYLEX_DECLARE[
1095   static void print_lookahead (char const *);
1096   #define USE(value)
1099 %define parse.assert
1100 %union { char value; }
1101 %type <value> 'a' 'b'
1102 %glr-parser
1103 %locations
1107 start:
1108   defstate_init defstate_shift 'b' change_lookahead 'a' {
1109     USE ($3);
1110     print_lookahead ("start <- defstate_init defstate_shift 'b'");
1111   }
1112   ;
1113 defstate_init:
1114   {
1115     print_lookahead ("defstate_init <- empty string");
1116   }
1117   ;
1118 defstate_shift:
1119   nondefstate defstate_look 'a' {
1120     USE ($3);
1121     print_lookahead ("defstate_shift <- nondefstate defstate_look 'a'");
1122   }
1123   ;
1124 defstate_look:
1125   {
1126     print_lookahead ("defstate_look <- empty string");
1127   }
1128   ;
1129 nondefstate:
1130   {
1131     print_lookahead ("nondefstate <- empty string");
1132   }
1133   | 'b' {
1134     USE ($1);
1135     print_lookahead ("nondefstate <- 'b'");
1136   }
1137   ;
1138 change_lookahead:
1139   {
1140     yychar = 'a';
1141   }
1142   ;
1146 ]AT_YYERROR_DEFINE[
1147 ]AT_YYLEX_DEFINE(["ab"],
1148                  [yylval.value = YY_CAST (char, res + 'A' - 'a')])[
1150 static void
1151 print_lookahead (char const *reduction)
1153   printf ("%s:\n  yychar=", reduction);
1154   if (yychar == YYEMPTY)
1155     printf ("YYEMPTY");
1156   else if (yychar == YYEOF)
1157     printf ("YYEOF");
1158   else
1159     {
1160       printf ("'%c', yylval='", yychar);
1161       if (yylval.value > ' ')
1162         printf ("%c", yylval.value);
1163       printf ("', yylloc=(%d,%d),(%d,%d)",
1164               yylloc.first_line, yylloc.first_column,
1165               yylloc.last_line, yylloc.last_column);
1166     }
1167   printf ("\n");
1171 main (void)
1173   yychar = '#'; /* Not a token in the grammar.  */
1174   yylval.value = '!';
1175   return yyparse ();
1178 AT_BISON_OPTION_POPDEFS
1180 AT_BISON_CHECK([[-o glr-regr13.c -rall glr-regr13.y]], 0, [], [])
1181 AT_COMPILE([glr-regr13])
1183 AT_PARSER_CHECK([[glr-regr13]], 0,
1184 [defstate_init <- empty string:
1185   yychar=YYEMPTY
1186 nondefstate <- empty string:
1187   yychar='a', yylval='A', yylloc=(1,1),(1,1)
1188 defstate_look <- empty string:
1189   yychar='a', yylval='A', yylloc=(1,1),(1,1)
1190 defstate_shift <- nondefstate defstate_look 'a':
1191   yychar=YYEMPTY
1192 start <- defstate_init defstate_shift 'b':
1193   yychar=YYEMPTY
1194 ], [])
1196 AT_CLEANUP
1199 ## ------------------------------------------------- ##
1200 ## Incorrect lookahead during nondeterministic GLR.  ##
1201 ## ------------------------------------------------- ##
1203 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
1205 AT_BISON_OPTION_PUSHDEFS
1206 AT_DATA_GRAMMAR([glr-regr14.y],
1208 /* Tests:
1209      - Conflicting actions (split-off parse, which copies lookahead need,
1210        which is necessarily yytrue) and nonconflicting actions (non-split-off
1211        parse) for nondefaulted state: yychar != YYEMPTY.
1212      - Merged deferred actions (lookahead need and RHS from different stack
1213        than the target state) and nonmerged deferred actions (same stack).
1214      - Defaulted state after lookahead: yychar != YYEMPTY.
1215      - Defaulted state after shift: yychar == YYEMPTY.
1216      - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1217        seen the lookahead but current stack has not).
1218      - Exceeding stack capacity (stack explosion), and thus reallocating
1219        lookahead need array.
1220    Note that it does not seem possible to see the initial yychar value during
1221    nondeterministic operation since:
1222      - In order to preserve the initial yychar, only defaulted states may be
1223        entered.
1224      - If only defaulted states are entered, there are no conflicts, so
1225        nondeterministic operation does not start.  */
1227 %union { char value; }
1230   #include <stdlib.h>
1231   #include <stdio.h>
1232   #include <assert.h>
1233   ]AT_YYERROR_DECLARE[
1234   ]AT_YYLEX_DECLARE[
1235   static void print_lookahead (char const *);
1236   static char merge (union YYSTYPE, union YYSTYPE);
1237   #define USE(value)
1240 %define parse.assert
1241 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1242 %glr-parser
1243 %locations
1247 start:
1248   merge 'c' stack_explosion {
1249     USE ($2); USE ($3);
1250     print_lookahead ("start <- merge 'c' stack_explosion");
1251   }
1252   ;
1254 /* When merging the 2 deferred actions, the lookahead needs are different.  */
1255 merge:
1256   nonconflict1 'a' 'b' nonconflict2 %dprec 1 {
1257     USE ($2); USE ($3);
1258     print_lookahead ("merge <- nonconflict1 'a' 'b' nonconflict2");
1259   }
1260   | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
1261     USE ($3); USE ($5);
1262     print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1263                       " defstate_shift");
1264   }
1265   ;
1267 nonconflict1:
1268   {
1269     print_lookahead ("nonconflict1 <- empty string");
1270   }
1271   ;
1272 nonconflict2:
1273   {
1274     print_lookahead ("nonconflict2 <- empty string");
1275   }
1276   | 'a' {
1277     USE ($1);
1278     print_lookahead ("nonconflict2 <- 'a'");
1279   }
1280   ;
1281 conflict:
1282   {
1283     print_lookahead ("conflict <- empty string");
1284   }
1285   ;
1286 defstate_look:
1287   {
1288     print_lookahead ("defstate_look <- empty string");
1289   }
1290   ;
1292 /* yychar != YYEMPTY but lookahead need is yyfalse.  */
1293 defstate_shift:
1294   {
1295     print_lookahead ("defstate_shift <- empty string");
1296   }
1297   ;
1299 stack_explosion:
1300   { $$ = '\0'; }
1301   | alt1 stack_explosion %merge<merge> { $$ = $2; }
1302   | alt2 stack_explosion %merge<merge> { $$ = $2; }
1303   | alt3 stack_explosion %merge<merge> { $$ = $2; }
1304   ;
1305 alt1:
1306   'd' no_look {
1307     USE ($1);
1308     if (yychar != 'd' && yychar != YYEOF)
1309       {
1310         fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1311       }
1312   }
1313   ;
1314 alt2:
1315   'd' no_look {
1316     USE ($1);
1317     if (yychar != 'd' && yychar != YYEOF)
1318       {
1319         fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1320       }
1321   }
1322   ;
1323 alt3:
1324   'd' no_look {
1325     USE ($1);
1326     if (yychar != 'd' && yychar != YYEOF)
1327       {
1328         fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
1329       }
1330   }
1331   ;
1332 no_look:
1333   {
1334     if (yychar != YYEMPTY)
1335       {
1336         fprintf (stderr,
1337                  "Found lookahead where shouldn't during stack explosion.\n");
1338       }
1339   }
1340   ;
1344 ]AT_YYERROR_DEFINE[
1345 static int
1346 yylex (void)
1348   static char const input[] = "abcdddd";
1349   static int toknum = 0;
1350   assert (toknum < YY_CAST (int, sizeof input));
1351   yylloc.first_line = yylloc.last_line = 1;
1352   yylloc.first_column = yylloc.last_column = toknum + 1;
1353   yylval.value = YY_CAST (char, input[toknum] + 'A' - 'a');
1354   return input[toknum++];
1357 static void
1358 print_lookahead (char const *reduction)
1360   printf ("%s:\n  yychar=", reduction);
1361   if (yychar == YYEMPTY)
1362     printf ("YYEMPTY");
1363   else if (yychar == YYEOF)
1364     printf ("YYEOF");
1365   else
1366     {
1367       printf ("'%c', yylval='", yychar);
1368       if (yylval.value > ' ')
1369         printf ("%c", yylval.value);
1370       printf ("', yylloc=(%d,%d),(%d,%d)",
1371               yylloc.first_line, yylloc.first_column,
1372               yylloc.last_line, yylloc.last_column);
1373     }
1374   printf ("\n");
1377 static char
1378 merge (union YYSTYPE s1, union YYSTYPE s2)
1380   return YY_CAST (char, s1.value + s2.value);
1384 main (void)
1386   yychar = '#'; /* Not a token in the grammar.  */
1387   yylval.value = '!';
1388   return yyparse ();
1391 AT_BISON_OPTION_POPDEFS
1393 AT_BISON_CHECK([[-o glr-regr14.c -rall glr-regr14.y]], 0, [],
1394 [[glr-regr14.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
1395 glr-regr14.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1397 AT_COMPILE([glr-regr14])
1399 AT_PARSER_CHECK([[glr-regr14]], 0,
1400 [conflict <- empty string:
1401   yychar='a', yylval='A', yylloc=(1,1),(1,1)
1402 defstate_look <- empty string:
1403   yychar='a', yylval='A', yylloc=(1,1),(1,1)
1404 nonconflict2 <- empty string:
1405   yychar='b', yylval='B', yylloc=(1,2),(1,2)
1406 defstate_shift <- empty string:
1407   yychar=YYEMPTY
1408 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1409   yychar=YYEMPTY
1410 start <- merge 'c' stack_explosion:
1411   yychar=YYEOF
1412 ], [])
1414 AT_CLEANUP
1417 ## ------------------------------------------------- ##
1418 ## Leaked semantic values when reporting ambiguity.  ##
1419 ## ------------------------------------------------- ##
1421 AT_SETUP([Leaked semantic values when reporting ambiguity])
1423 AT_BISON_OPTION_PUSHDEFS
1424 AT_DATA_GRAMMAR([glr-regr15.y],
1426 %define parse.assert
1427 %glr-parser
1428 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1431 # include <stdlib.h>
1432   ]AT_YYERROR_DECLARE[
1433   ]AT_YYLEX_DECLARE[
1434   static int parent_rhs_before_value = 0;
1435 # define USE(val)
1440 start:
1441   alt1 %dprec 1
1442   | alt2 %dprec 2
1443   ;
1445 /* This stack must be merged into the other stacks *last* (added at the
1446    beginning of the semantic options list) so that yyparse will choose to clean
1447    it up rather than the tree for which some semantic actions have been
1448    performed.  Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1449    those other trees are not cleaned up.  */
1450 alt1: ;
1452 alt2:
1453   parent_rhs_before ambiguity {
1454     USE ($1);
1455     parent_rhs_before_value = 0;
1456   }
1457   ;
1459 parent_rhs_before:
1460   {
1461     USE ($$);
1462     parent_rhs_before_value = 1;
1463   }
1464   ;
1466 ambiguity: ambiguity1 | ambiguity2 ;
1467 ambiguity1: ;
1468 ambiguity2: ;
1471 ]AT_YYERROR_DEFINE[
1472 ]AT_YYLEX_DEFINE[
1475 main (void)
1477   int exit_status = yyparse () != 1;
1478   if (parent_rhs_before_value)
1479     {
1480       fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1481       exit_status = 1;
1482     }
1483   return exit_status;
1486 AT_BISON_OPTION_POPDEFS
1488 AT_BISON_CHECK([[-o glr-regr15.c -rall glr-regr15.y]], 0, [],
1489 [[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
1490 glr-regr15.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1492 AT_COMPILE([glr-regr15])
1494 AT_PARSER_CHECK([[glr-regr15]], 0, [],
1495 [syntax is ambiguous
1498 AT_CLEANUP
1501 ## ------------------------------------------------------------ ##
1502 ## Leaked lookahead after nondeterministic parse syntax error.  ##
1503 ## ------------------------------------------------------------ ##
1505 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
1507 AT_BISON_OPTION_PUSHDEFS
1508 AT_DATA_GRAMMAR([glr-regr16.y],
1510 %define parse.assert
1511 %glr-parser
1512 %destructor { lookahead_value = 0; } 'b'
1515 # include <stdlib.h>
1516 # include <assert.h>
1517   ]AT_YYERROR_DECLARE[
1518   ]AT_YYLEX_DECLARE[
1519   static int lookahead_value = 0;
1520 # define USE(val)
1525 start: alt1 'a' | alt2 'a' ;
1526 alt1: ;
1527 alt2: ;
1531 ]AT_YYERROR_DEFINE[
1532 ]AT_YYLEX_DEFINE(["ab"],
1533   [if (res == 'b')
1534     lookahead_value = 1])[
1537 main (void)
1539   int exit_status = yyparse () != 1;
1540   if (lookahead_value)
1541     {
1542       fprintf (stderr, "Lookahead destructor not called.\n");
1543       exit_status = 1;
1544     }
1545   return exit_status;
1548 AT_BISON_OPTION_POPDEFS
1550 AT_BISON_CHECK([[-o glr-regr16.c -rall glr-regr16.y]], 0, [],
1551 [[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1552 glr-regr16.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1554 AT_COMPILE([glr-regr16])
1556 AT_PARSER_CHECK([[glr-regr16]], 0, [],
1557 [syntax error
1560 AT_CLEANUP
1563 ## ------------------------------------------------- ##
1564 ## Uninitialized location when reporting ambiguity.  ##
1565 ## ------------------------------------------------- ##
1567 AT_SETUP([Uninitialized location when reporting ambiguity])
1569 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
1571 AT_DATA_GRAMMAR([glr-regr17.y],
1573 %define parse.assert
1574 %glr-parser
1575 %locations
1576 %define api.pure
1577 %define parse.error verbose
1579 %union { int dummy; }
1582   ]AT_YYERROR_DECLARE[
1583   ]AT_YYLEX_DECLARE[
1588 /* Tests the case of an empty RHS that has inherited the location of the
1589    previous nonterminal, which is unresolved.  That location is reported as the
1590    last position of the ambiguity.  */
1591 start: ambig1 empty1 | ambig2 empty2 ;
1593 /* Tests multiple levels of yyresolveLocations recursion.  */
1594 ambig1: sub_ambig1 | sub_ambig2 ;
1595 ambig2: sub_ambig1 | sub_ambig2 ;
1597 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1598    has inherited the initial location.  The empty RHS's location is reported as
1599    the first position in the ambiguity.  */
1600 sub_ambig1: empty1 'a' 'b' ;
1601 sub_ambig2: empty2 'a' 'b' ;
1602 empty1: ;
1603 empty2: ;
1606 # include <assert.h>
1608 ]AT_YYERROR_DEFINE[
1609 static int
1610 yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
1612   static char const input[] = "ab";
1613   static int toknum = 0;
1614   assert (toknum < YY_CAST (int, sizeof input));
1615   lvalp->dummy = 0;
1616   llocp->first_line = llocp->last_line = 2;
1617   llocp->first_column = toknum + 1;
1618   llocp->last_column = llocp->first_column + 1;
1619   return input[toknum++];
1622 ]AT_MAIN_DEFINE[
1624 AT_BISON_OPTION_POPDEFS
1626 AT_BISON_CHECK([[-o glr-regr17.c -rall glr-regr17.y]], 0, [],
1627 [[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
1628 glr-regr17.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1630 AT_COMPILE([glr-regr17])
1632 AT_PARSER_CHECK([[glr-regr17]], 1, [],
1633 [1.1-2.2: syntax is ambiguous
1636 AT_CLEANUP
1639 ## ------------------------------------------------------------- ##
1640 ## Missed %merge type warnings when LHS type is declared later.  ##
1641 ## ------------------------------------------------------------- ##
1643 AT_SETUP([Missed %merge type warnings when LHS type is declared later])
1645 AT_BISON_OPTION_PUSHDEFS
1646 AT_DATA_GRAMMAR([glr-regr18.y],
1647 [[%define parse.assert
1648 %glr-parser
1651   #include <stdlib.h>
1652   ]AT_YYERROR_DECLARE[
1653   ]AT_YYLEX_DECLARE[
1656 %union {
1657   int type1;
1658   int type2;
1659   int type3;
1663 sym1: sym2 %merge<merge> { $$ = $1; } ;
1664 sym2: sym3 %merge<merge> { $$ = $1; } ;
1665 sym3: %merge<merge> { $$ = 0; } ;
1667 %type <type1> sym1;
1668 %type <type2> sym2;
1669 %type <type3> sym3;
1672 ]AT_YYERROR_DEFINE[
1673 ]AT_YYLEX_DEFINE[
1674 ]AT_MAIN_DEFINE[
1676 AT_BISON_OPTION_POPDEFS
1678 AT_BISON_CHECK([[-o glr-regr18.c -rall glr-regr18.y]], 1, [],
1679 [[glr-regr18.y:28.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
1680 glr-regr18.y:27.18-24: note: previous declaration
1681 glr-regr18.y:29.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
1682 glr-regr18.y:28.18-24: note: previous declaration
1685 AT_CLEANUP
1688 ## ------------------- ##
1689 ## Ambiguity reports.  ##
1690 ## ------------------- ##
1692 AT_SETUP([Ambiguity reports])
1694 AT_BISON_OPTION_PUSHDEFS([%debug])
1695 AT_DATA_GRAMMAR([input.y],
1696 [[%{
1697   #include <stdio.h>
1698   #include <stdlib.h>
1699   ]AT_YYERROR_DECLARE[
1700   ]AT_YYLEX_DECLARE[
1703 %define parse.assert
1704 %debug
1705 %glr-parser
1708 start:
1709   'a' b 'c' d
1710 | 'a' b 'c' d
1712 b: 'b';
1713 d: /* nada.  */;
1715 ]AT_YYERROR_DEFINE[
1716 ]AT_YYLEX_DEFINE(["abc"])[
1717 ]AT_MAIN_DEFINE[
1720 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
1721 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
1722 input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
1724 AT_COMPILE([input])
1726 AT_PARSER_CHECK([[input --debug]], 1, [],
1727 [Starting parse
1728 Entering state 0
1729 Reading a token
1730 Next token is token 'a' ()
1731 Shifting token 'a' ()
1732 Entering state 1
1733 Reading a token
1734 Next token is token 'b' ()
1735 Shifting token 'b' ()
1736 Entering state 3
1737 Reducing stack 0 by rule 3 (line 27):
1738    $1 = token 'b' ()
1739 -> $$ = nterm b ()
1740 Entering state 4
1741 Reading a token
1742 Next token is token 'c' ()
1743 Shifting token 'c' ()
1744 Entering state 6
1745 Reducing stack 0 by rule 4 (line 28):
1746 -> $$ = nterm d ()
1747 Entering state 7
1748 Reading a token
1749 Now at end of input.
1750 Stack 0 Entering state 7
1751 Now at end of input.
1752 Splitting off stack 1 from 0.
1753 Reduced stack 1 by rule 2 (line 24); action deferred.  Now in state 2.
1754 Stack 1 Entering state 2
1755 Now at end of input.
1756 Reduced stack 0 by rule 1 (line 24); action deferred.  Now in state 2.
1757 Merging stack 0 into stack 1.
1758 Stack 1 Entering state 2
1759 Now at end of input.
1760 Removing dead stacks.
1761 Rename stack 1 -> 0.
1762 On stack 0, shifting token "end of file" ()
1763 Stack 0 now in state #5
1764 Ambiguity detected.
1765 Option 1,
1766   start -> <Rule 1, tokens 1 .. 3>
1767     'a' <tokens 1 .. 1>
1768     b <tokens 2 .. 2>
1769     'c' <tokens 3 .. 3>
1770     d <empty>
1772 Option 2,
1773   start -> <Rule 2, tokens 1 .. 3>
1774     'a' <tokens 1 .. 1>
1775     b <tokens 2 .. 2>
1776     'c' <tokens 3 .. 3>
1777     d <empty>
1779 syntax is ambiguous
1780 Cleanup: popping token "end of file" ()
1781 Cleanup: popping unresolved nterm start ()
1782 Cleanup: popping nterm d ()
1783 Cleanup: popping token 'c' ()
1784 Cleanup: popping nterm b ()
1785 Cleanup: popping token 'a' ()
1788 AT_BISON_OPTION_POPDEFS
1789 AT_CLEANUP
1792 ## ----------------------------------------------------------------- ##
1793 ## Predicates.                                                       ##
1794 ##                                                                   ##
1795 ## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ##
1796 ## http://lists.gnu.org/archive/html/bug-bison/2018-05/msg00033.html ##
1797 ## ----------------------------------------------------------------- ##
1799 AT_SETUP([Predicates])
1801 AT_BISON_OPTION_PUSHDEFS
1802 AT_DATA_GRAMMAR([input.y],
1803 [[%define parse.assert
1804 %glr-parser
1805 %define parse.error verbose
1806 %expect-rr 1
1807 %code requires
1809   #include <assert.h>
1810   #include <stdbool.h>
1811   bool new_syntax = false;
1812   const char *input = YY_NULLPTR;
1813   ]AT_YYERROR_DECLARE[
1814   ]AT_YYLEX_DECLARE[
1817 widget:
1818   %? {new_syntax} 'w' id new_args  { printf("new"); }
1819 | %?{!new_syntax} 'w' id old_args  { printf("old"); }
1821 id: 'i';
1822 new_args: 'n';
1823 old_args: 'o';
1825 ]AT_YYERROR_DEFINE[
1828 yylex (void)
1830   return *input++;
1834 main (int argc, const char* argv[])
1836   assert (argc == 2); (void) argc;
1837   // First char decides whether new, or old syntax.
1838   // Then the input.
1839   new_syntax = argv[1][0] == 'N';
1840   input = argv[1] + 1;
1841   return yyparse ();
1845 AT_BISON_CHECK([[-o input.c input.y]])
1846 AT_COMPILE([input])
1847 AT_PARSER_CHECK([[input Nwin]], [0], [new])
1848 AT_PARSER_CHECK([[input Owin]], [1], [], [[syntax error, unexpected 'n', expecting 'o'
1850 AT_PARSER_CHECK([[input Owio]], [0], [old])
1851 AT_PARSER_CHECK([[input Nwio]], [1], [], [[syntax error, unexpected 'o', expecting 'n'
1854 AT_BISON_OPTION_POPDEFS
1855 AT_CLEANUP