tests: fix coding style
[bison.git] / tests / glr-regression.at
bloba10f69ba5a829ebbe0437b349735dc59933dbba7
1 # Checking GLR Parsing: Regression Tests           -*- Autotest -*-
3 # Copyright (C) 2002-2003, 2005-2007, 2009-2015, 2018-2021 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 <https://www.gnu.org/licenses/>.
19 AT_BANNER([[GLR Regression Tests]])
21 # You might wonder what's the point of having names different for each
22 # test case.  When some endlessly loop, it is nice to see their "name"
23 # in ps.
25 # AT_YYPARSE_DEFINE
26 # -----------------
27 # Wrap the C++ parser in a C-like function interface.
28 m4_pushdef([AT_YYPARSE_DEFINE],
29 [AT_CXX_IF([[
30 static int
31 yyparse ()
33   ]AT_NAMESPACE[::]AT_PARSER_CLASS[ p;]AT_DEBUG_IF([[
34   int debug = !!getenv ("YYDEBUG");
35   p.set_debug_level (debug);]])[
36   return p.parse ();
38 ]])])
41 # AT_PRINT_LOOKAHEAD_DECLARE
42 # --------------------------
43 m4_define([AT_PRINT_LOOKAHEAD_DECLARE],
44 [AT_GLR2_CC_IF(
45 [[static void
46   print_lookahead (yy::parser::symbol_type yylookahead, char const *reduction);
47 #define PRINT_LOOKAHEAD(Msg) \
48   print_lookahead (yyla, Msg)
49 ]],
50 [[static void
51   print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
52                    char const *reduction);
53 #define PRINT_LOOKAHEAD(Msg) \
54   print_lookahead (yychar, &yylval, &yylloc, Msg)
55 ]])])
57 # AT_PRINT_LOOKAHEAD_DEFINE
58 # -------------------------
59 m4_define([AT_PRINT_LOOKAHEAD_DEFINE],
60 [AT_GLR2_CC_IF(
61 [[static void
62 print_lookahead (yy::parser::symbol_type yylookahead, char const *reduction)
63 ]],
64 [[static void
65 print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
66                  char const *reduction)
67 ]])[
69 ]AT_GLR2_CC_IF([[
70   // We use -2 and 0 to avoid this warning:
71   //
72   // glr-regr13.y:114:53: error: enumeral and non-enumeral type in conditional expression [-Werror=extra]
73   //   114 |     : yytoken == yy::parser::symbol_kind::S_YYEOF   ? yy::parser::token::YYEOF
74   //       |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
75   //   115 |     : yytoken == yy::parser::yytranslate_ ('a')     ? 'a'
76   //       |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77   //   116 |     : yytoken == yy::parser::yytranslate_ ('b')     ? 'b'
78   //       |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79   //   117 |     : '?';
80   //       |     ~~~~~
81   int yytoken = yylookahead.kind ();
82   int yychr
83     = yytoken == yy::parser::symbol_kind::S_YYEMPTY ? -2
84     : yytoken == yy::parser::symbol_kind::S_YYEOF   ? 0
85     : yytoken == yy::parser::symbol_kind::S_3_a_    ? 'a'
86     : yytoken == yy::parser::symbol_kind::S_4_b_    ? 'b'
87     : '?';
88 ]])[
89   printf ("%s:\n  yychar=", reduction);
90   if (yychr == ]AT_TOKEN([YYEMPTY])[)
91     printf ("YYEMPTY");
92   else if (yychr == ]AT_TOKEN([YYEOF])[)
93     printf ("YYEOF");
94   else
95     {
96       printf ("'%c', yylval='", yychr);]AT_GLR2_CC_IF([[
97       if (yylookahead.value.value > ' ')
98         printf ("%c", yylookahead.value.value);
99       printf ("', yylloc=(%d,%d),(%d,%d)",
100               yylookahead.location.]AT_FIRST_LINE[, yylookahead.location.]AT_FIRST_COLUMN[,
101               yylookahead.location.]AT_LAST_LINE[,  yylookahead.location.]AT_LAST_COLUMN[);]], [[
102       if (yylvalp->value > ' ')
103         printf ("%c", yylvalp->value);
104       printf ("', yylloc=(%d,%d),(%d,%d)",
105               yyllocp->]AT_FIRST_LINE[, yyllocp->]AT_FIRST_COLUMN[,
106               yyllocp->]AT_LAST_LINE[, yyllocp->]AT_LAST_COLUMN[);]])[
107     }
108   printf ("\n");
113 ## ---------------------------- ##
114 ## Badly Collapsed GLR States.  ##
115 ## ---------------------------- ##
117 m4_pushdef([AT_TEST],
118 [AT_SETUP([Badly Collapsed GLR States: $1])
120 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
121 AT_KEYWORDS([%merge])
123 AT_DATA_GRAMMAR([glr-regr1.y],
124 [[/* Regression Test: Improper state compression */
125 /* Reported by Scott McPeak */
127 %define api.value.type {int}
129 %code {
130 #include <assert.h>
132 static ]AT_YYSTYPE[ exprMerge (]AT_YYSTYPE[ x0, ]AT_YYSTYPE[ x1);
133 ]AT_YYERROR_DECLARE[
134 ]AT_YYLEX_DECLARE[
137 %define parse.assert
138 %define parse.trace
139 %glr-parser
140 %expect 1
141 ]$1[
143 /* -------- productions ------ */
146 StartSymbol: E  { $$=0; }                   %merge <exprMerge>
147            ;
149 E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); }  %merge <exprMerge>
150  | 'B'     { $$=2; printf("E -> 'B'\n"); }      %merge <exprMerge>
155 /* ---------- C code ----------- */
158 static ]AT_YYSTYPE[ exprMerge (]AT_YYSTYPE[ x0, ]AT_YYSTYPE[ x1)
160   (void) x0;
161   (void) x1;
162   printf ("<OR>\n");
163   return 0;
166 ]AT_YYERROR_DEFINE[
167 ]AT_YYPARSE_DEFINE[
169 const char *input = YY_NULLPTR;
171 ]AT_YYLEX_PROTOTYPE[
173   ]AT_USE_LEX_ARGS[
174   return *input++;
178 main (int argc, const char* argv[])
180   assert (argc == 2); (void) argc;
181   input = argv[1];
182   if (getenv ("YYDEBUG"))
183     yydebug = 1;
184   return yyparse ();
188 AT_FULL_COMPILE([glr-regr1])
189 AT_PARSER_CHECK([[glr-regr1 BPBPB]], 0,
190 [[E -> 'B'
191 E -> 'B'
192 E -> E 'P' E
193 E -> 'B'
194 E -> E 'P' E
195 E -> 'B'
196 E -> E 'P' E
197 E -> E 'P' E
198 <OR>
201 AT_BISON_OPTION_POPDEFS
202 AT_CLEANUP
205 AT_TEST([%skeleton "glr.c"])
206 AT_TEST([%skeleton "glr.cc"])
207 AT_TEST([%skeleton "glr2.cc"])
209 m4_popdef([AT_TEST])
213 ## -------------------------------------------------------------- ##
214 ## Improper handling of embedded actions and $-N in GLR parsers.  ##
215 ## -------------------------------------------------------------- ##
217 m4_pushdef([AT_TEST],
218 [AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers: $1])
220 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
222 AT_DATA_GRAMMAR([glr-regr2a.y],
223 [[/* Regression Test: Improper handling of embedded actions and $-N  */
224 /* Reported by S. Eken */
226 %define api.value.type {char *}
227 %code {
228   #include <ctype.h>
229   #include <stdio.h>
230   #include <stdlib.h>
231   #include <string.h>
232   #include <assert.h>
233   ]AT_YYERROR_DECLARE[
234   ]AT_YYLEX_DECLARE[
237 %define parse.assert
238 %define parse.trace
239 %glr-parser
240 %expect 2
241 ]$1[
245 command:
246     's' var 't'
247        { printf ("Variable: '%s'\n", $][2); }
248     'v' 'x' 'q'
249        { free ($][2); }
250   | 's' var_list 't' 'e'
251        { printf ("Varlist: '%s'\n", $][2); free ($][2); }
252   | 's' var 't' var_printer 'x'
253        { free ($][2); }
254   ;
256 var:
257   'V'
258      { $$ = $][1; }
259   ;
261 var_list:
262   var
263     { $$ = $][1; }
264   | var ',' var_list
265     {
266       char *s = YY_CAST (char *, realloc ($][1, strlen ($][1) + 1 + strlen ($][3) + 1));
267       strcat (s, ",");
268       strcat (s, $][3);
269       free ($][3);
270       $$ = s;
271     }
272   ;
274 var_printer: 'v'
275    { printf ("Variable: '%s'\n", $-1); }
278 ]AT_YYERROR_DEFINE[
279 FILE *input;
281 ]AT_YYLEX_PROTOTYPE[
283   char buf[50];
284   ]AT_USE_LEX_ARGS[
285   assert (!feof (stdin));
286   switch (fscanf (input, " %1[a-z,]", buf))
287   {
288   case 1:
289     return buf[0];
290   case EOF:
291     return 0;
292   default:
293     if (fscanf (input, "%49s", buf) != 1)
294       return 0;
295     else
296       {
297         assert (strlen (buf) < sizeof buf - 1);
298         char *s = YY_CAST (char *, malloc (strlen (buf) + 1));
299         strcpy (s, buf);
300         ]AT_VAL[ = s;
301         return 'V';
302       }
303     break;
304   }
307 ]AT_YYPARSE_DEFINE[
310 main (int argc, char **argv)
312   int res;
313   input = stdin;
314   if (argc == 2 && !(input = fopen (argv[1], "r")))
315     return 3;
316   if (getenv ("YYDEBUG"))
317     yydebug = 1;
318   res = yyparse ();
319   if (argc == 2 && fclose (input))
320     return 4;
321   return res;
325 AT_FULL_COMPILE([glr-regr2a],,,,[-rall])
327 AT_DATA([input1.txt],
328 [[s VARIABLE_1 t v x q
330 AT_PARSER_CHECK([[glr-regr2a input1.txt]], 0,
331 [[Variable: 'VARIABLE_1'
334 AT_DATA([input2.txt],
335 [[s VARIABLE_1 , ANOTHER_VARIABLE_2 t e
337 AT_PARSER_CHECK([[glr-regr2a input2.txt]],
339 [[Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2'
342 AT_DATA([input3.txt],
343 [[s VARIABLE_3 t v x
345 AT_PARSER_CHECK([[glr-regr2a input3.txt]], 0,
346 [[Variable: 'VARIABLE_3'
349 AT_BISON_OPTION_POPDEFS
350 AT_CLEANUP
353 AT_TEST([%skeleton "glr.c"])
354 AT_TEST([%skeleton "glr.cc"])
355 AT_TEST([%skeleton "glr2.cc"])
357 m4_popdef([AT_TEST])
360 ## --------------------------------------------- ##
361 ## Improper merging of GLR delayed action sets.  ##
362 ## --------------------------------------------- ##
364 m4_pushdef([AT_TEST],
365 [AT_SETUP([Improper merging of GLR delayed action sets: $1])
366 AT_KEYWORDS([%merge])
368 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
370 AT_DATA_GRAMMAR([glr-regr3.y],
371 [[/* Regression Test: Improper merging of GLR delayed action sets.  */
372 /* Reported by M. Rosien */
374 %code {
375 #include <stdarg.h>
376 #include <assert.h>
378 static int MergeRule (int x0, int x1);
379 ]AT_YYERROR_DECLARE[
380 ]AT_YYLEX_DECLARE[
382 #define RULE(x) (1 << (x))
386 %define parse.assert
387 %define parse.trace
388 %glr-parser
389 %expect 1
390 %expect-rr 2
391 ]$1[
393 %token BAD_CHAR
394 %token P1 P2 T1 T2 T3 T4 O1 O2
398 S : P1 T4 O2 NT6 P2  { printf ("Result: %x\n", $][4); }
401 NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); }  %merge<MergeRule>
404 NT2 : NT1             { $$ = RULE(3); } %merge<MergeRule>
405     | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge<MergeRule>
408 NT3 : T3              { $$ = RULE(5); } %merge<MergeRule>
409     | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge<MergeRule>
412 NT4 : NT3              { $$ = RULE(7); } %merge<MergeRule>
413     | NT2              { $$ = RULE(8); } %merge<MergeRule>
414     | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge<MergeRule>
417 NT5 : NT4              { $$ = RULE(10); } %merge<MergeRule>
420 NT6 : P1 NT1 O1 T3 P2  { $$ = RULE(11) | $][2; } %merge<MergeRule>
421     | NT5              { $$ = RULE(12) | $][1; } %merge<MergeRule>
426 static int
427 MergeRule (int x0, int x1)
429   return x0 | x1;
431 ]AT_YYERROR_DEFINE[
433 FILE *input = YY_NULLPTR;
435 int P[] = { ]AT_TOKEN([P1])[, ]AT_TOKEN([P2])[ };
436 int O[] = { ]AT_TOKEN([O1])[, ]AT_TOKEN([O2])[ };
437 int T[] = { ]AT_TOKEN([T1])[, ]AT_TOKEN([T2])[, ]AT_TOKEN([T3])[, ]AT_TOKEN([T4])[ };
439 ]AT_YYLEX_PROTOTYPE[
441   char inp[3];
442   ]AT_USE_LEX_ARGS[
443   assert (!feof (stdin));
444   if (fscanf (input, "%2s", inp) == EOF)
445     return 0;
446   switch (inp[0])
447     {
448     case 'p': return P[inp[1] - '1'];
449     case 't': return T[inp[1] - '1'];
450     case 'o': return O[inp[1] - '1'];
451     }
452   return ]AT_TOKEN([BAD_CHAR])[;
455 ]AT_YYPARSE_DEFINE[
458 main (int argc, char* argv[])
460   int res;
461   input = stdin;
462   if (argc == 2 && !(input = fopen (argv[1], "r")))
463     return 3;
464   if (getenv ("YYDEBUG"))
465     yydebug = 1;
466   res = yyparse ();
467   if (argc == 2 && fclose (input))
468     return 4;
469   return res;
473 AT_FULL_COMPILE([glr-regr3],,,,[-rall])
475 AT_DATA([input.txt],
476 [[p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2
478 AT_PARSER_CHECK([[glr-regr3 input.txt]],
480 [[Result: 1c04
483 AT_BISON_OPTION_POPDEFS
484 AT_CLEANUP
487 AT_TEST([%skeleton "glr.c"])
488 AT_TEST([%skeleton "glr.cc"])
489 AT_TEST([%skeleton "glr2.cc"])
491 m4_popdef([AT_TEST])
494 ## ------------------------------------------------------------ ##
495 ## Duplicate representation of merged trees.  See               ##
496 ## <https://lists.gnu.org/r/help-bison/2005-07/msg00013.html>.  ##
497 ## ------------------------------------------------------------ ##
499 m4_pushdef([AT_TEST],
500 [AT_SETUP([Duplicate representation of merged trees: $1])
501 AT_KEYWORDS([%merge])
503 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
505 AT_DATA_GRAMMAR([glr-regr4.y],
507 %define parse.assert
508 %define parse.trace
509 %type <]AT_VALUE_UNION_IF([char*], [ptr])[> S A A1 A2 B
510 %glr-parser
511 %expect-rr 2
512 ]$1[
514 %code {
515   #include <string.h>
516   static char *merge (]AT_YYSTYPE[, ]AT_YYSTYPE[);
517   static char *make_value (char const *, char const *);
518   ]AT_YYERROR_DECLARE[
519   ]AT_YYLEX_DECLARE[
520   static char *ptrs[100];
521   static char **ptrs_next = ptrs;
526 tree: S { printf ("%s\n", $][1); } ;
528 S : A %merge<merge> { $$ = make_value ("S", $][1); }
529   | B %merge<merge> { $$ = make_value ("S", $][1); }
530   ;
532 A : A1 %merge<merge> { $$ = make_value ("A", $][1); }
533   | A2 %merge<merge> { $$ = make_value ("A", $][1); }
534   ;
536 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
537 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
538 B:  'a' { $$ = make_value ("B", "'a'");  } ;
541 ]AT_YYERROR_DEFINE[
542 ]AT_YYPARSE_DEFINE[
543 ]AT_YYLEX_DEFINE(["a"])[
546 main (void)
548   int status = -1;
549   if (getenv ("YYDEBUG"))
550     yydebug = 1;
551   status = yyparse ();
552   while (ptrs_next != ptrs)
553     free (*--ptrs_next);
554   return status;
557 static char *
558 make_value (char const *parent, char const *child)
560   char const format[] = "%s <- %s";
561   char *value = *ptrs_next++ =
562     YY_CAST (char *, malloc (strlen (parent) + strlen (child) + sizeof format));
563   sprintf (value, format, parent, child);
564   return value;
567 static char *
568 merge (]AT_YYSTYPE[ s1, ]AT_YYSTYPE[ s2)
570   char const format[] = "merge{ %s and %s }";]AT_VALUE_UNION_IF([[
571   char *res = *ptrs_next++ =
572     YY_CAST (char *, malloc (strlen (s1.S) + strlen (s2.S) + sizeof format));
573   sprintf (res, format, s1.S, s2.S);]], [[
574   char *res = *ptrs_next++ =
575     YY_CAST (char *, malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format));
576   sprintf (res, format, s1.ptr, s2.ptr);]])[
577   return res;
581 AT_FULL_COMPILE([glr-regr4],,,,[-rall])
583 AT_PARSER_CHECK([[glr-regr4]], 0,
584 [[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
585 ]], [])
587 AT_BISON_OPTION_POPDEFS
588 AT_CLEANUP
591 AT_TEST([%union { char *ptr; } %skeleton "glr.c"])
592 AT_TEST([%union { char *ptr; } %skeleton "glr.cc"])
593 AT_TEST([%union { char *ptr; } %skeleton "glr2.cc"])
595 AT_TEST([%define api.value.type union %skeleton "glr.c"])
596 AT_TEST([%define api.value.type union %skeleton "glr.cc"])
597 AT_TEST([%define api.value.type union %skeleton "glr2.cc"])
599 m4_popdef([AT_TEST])
602 ## --------------------------------------------------------------- ##
603 ## User destructor for unresolved GLR semantic value.  See         ##
604 ## <https://lists.gnu.org/r/bison-patches/2005-08/msg00016.html>.  ##
605 ## --------------------------------------------------------------- ##
607 m4_pushdef([AT_TEST],
608 [AT_SETUP([User destructor for unresolved GLR semantic value: $1])
610 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
611 AT_DATA_GRAMMAR([glr-regr5.y],
613 %code {
614   ]AT_YYERROR_DECLARE[
615   ]AT_YYLEX_DECLARE[
616   enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
619 %define parse.assert
620 %define parse.trace
621 %glr-parser
622 %expect 0
623 %expect-rr 1
624 ]$1[
626 %union { int value; }
627 %type <value> start
629 %destructor {
630   if ($$ != MAGIC_VALUE)
631     {
632       fprintf (stderr, "Bad destructor call.\n");
633       exit (EXIT_FAILURE);
634     }
635 } start
639 start:
640    'a' { $$ = MAGIC_VALUE; }
641    | 'a' { $$ = MAGIC_VALUE; }
642    ;
645 ]AT_YYERROR_DEFINE[
646 ]AT_YYLEX_DEFINE(["a"])[
647 ]AT_MAIN_DEFINE[
650 AT_FULL_COMPILE([glr-regr5],,,, [-rall])
652 AT_PARSER_CHECK([[glr-regr5]], 1, [],
653 [Ambiguity detected.
654 Option 1,
655   start -> <Rule 1, tokens 1 .. 1>
656     'a' <tokens 1 .. 1>
658 Option 2,
659   start -> <Rule 2, tokens 1 .. 1>
660     'a' <tokens 1 .. 1>
662 syntax is ambiguous
665 AT_BISON_OPTION_POPDEFS
666 AT_CLEANUP
669 AT_TEST([%skeleton "glr.c"])
670 AT_TEST([%skeleton "glr.cc"])
671 AT_TEST([%skeleton "glr2.cc"])
673 m4_popdef([AT_TEST])
677 ## --------------------------------------------------------------- ##
678 ## User destructor after an error during a split parse.  See       ##
679 ## <https://lists.gnu.org/r/bison-patches/2005-08/msg00029.html>.  ##
680 ## --------------------------------------------------------------- ##
682 m4_pushdef([AT_TEST],
683 [AT_SETUP([User destructor after an error during a split parse: $1])
685 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
686 AT_DATA_GRAMMAR([glr-regr6.y],
688 %code {
689   ]AT_YYERROR_DECLARE[
690   ]AT_YYLEX_DECLARE[
693 %define parse.assert
694 %define parse.trace
695 %glr-parser
696 %expect-rr 1
697 ]$1[
699 %union { int value; }
700 %type <value> 'a'
702 %destructor {
703   printf ("Destructor called.\n");
704 } 'a'
708 start: 'a' | 'a' ;
711 ]AT_YYERROR_DEFINE[
712 ]AT_YYLEX_DEFINE(["a"])[
713 ]AT_MAIN_DEFINE[
716 AT_FULL_COMPILE([glr-regr6],,,, [-rall])
718 AT_PARSER_CHECK([[glr-regr6]], 1,
719 [Destructor called.
721 [Ambiguity detected.
722 Option 1,
723   start -> <Rule 1, tokens 1 .. 1>
724     'a' <tokens 1 .. 1>
726 Option 2,
727   start -> <Rule 2, tokens 1 .. 1>
728     'a' <tokens 1 .. 1>
730 syntax is ambiguous
733 AT_BISON_OPTION_POPDEFS
734 AT_CLEANUP
737 AT_TEST([%skeleton "glr.c"])
738 AT_TEST([%skeleton "glr.cc"])
739 AT_TEST([%skeleton "glr2.cc"])
741 m4_popdef([AT_TEST])
745 ## --------------------------------------------------------------- ##
746 ## Duplicated user destructor for lookahead.  See                  ##
747 ## <https://lists.gnu.org/r/bison-patches/2005-08/msg00035.html>.  ##
748 ## --------------------------------------------------------------- ##
750 m4_pushdef([AT_TEST],
751 [AT_SETUP([Duplicated user destructor for lookahead: $1])
753 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
755 AT_DATA_GRAMMAR([glr-regr7.y],
757 %code requires {
758   typedef struct count_node {
759     int count;
760     struct count_node *prev;
761   } count_node;
764 %code {
765   ]AT_YYERROR_DECLARE[
766   ]AT_YYLEX_DECLARE[
767   #define YYSTACKEXPANDABLE 0
768   static count_node *tail;
771 %define parse.assert
772 %define parse.trace
773 %glr-parser
774 %expect-rr 2
775 ]$1[
777 %union { count_node *node; }
778 %type <node> 'a'
780 %destructor {
781   if ($$->count++)
782     fprintf (stderr, "Destructor called on same value twice.\n");
783 } 'a'
787 start:
788     stack1 start
789   | stack2 start
790   | %empty
791   ;
792 stack1: 'a' ;
793 stack2: 'a' ;
797 ]AT_YYLEX_PROTOTYPE[
799   ]AT_USE_LEX_ARGS[
800   ]AT_VAL[.node = YY_CAST (count_node*, malloc (sizeof *]AT_VAL[.node));
801   if (!]AT_VAL[.node)
802     {
803       fprintf (stderr, "Test inconclusive.\n");
804       exit (EXIT_FAILURE);
805     }
806   ]AT_VAL[.node->count = 0;
807   ]AT_VAL[.node->prev = tail;
808   tail = ]AT_VAL[.node;
809   return 'a';
812 ]AT_YYERROR_DEFINE[
813 ]AT_YYPARSE_DEFINE[
816 main (void)
818   int status;
819   if (getenv ("YYDEBUG"))
820     yydebug = 1;
821   status = yyparse ();
822   while (tail)
823     {
824       count_node *prev = tail->prev;
825       free (tail);
826       tail = prev;
827     }
828   return status;
832 AT_FULL_COMPILE([glr-regr7],,,, [-rall])
834 AT_PARSER_CHECK([[glr-regr7]], 2, [],
835 [memory exhausted
838 AT_BISON_OPTION_POPDEFS
839 AT_CLEANUP
842 AT_TEST([%skeleton "glr.c"])
843 AT_TEST([%skeleton "glr.cc"])
844 AT_TEST([%skeleton "glr2.cc"])
846 m4_popdef([AT_TEST])
850 ## ------------------------------------------------------------------------- ##
851 ## Incorrect default location for empty right-hand sides.  Adapted from bug  ##
852 ## report by Claudia Hermann.                                                ##
853 ## See https://lists.gnu.org/r/bug-bison/2005-10/msg00069.html and           ##
854 ## https://lists.gnu.org/r/bug-bison/2005-10/msg00072.html                   ##
855 ## ------------------------------------------------------------------------- ##
857 m4_pushdef([AT_TEST],
858 [AT_SETUP([Incorrectly initialized location for empty right-hand side in GLR: $1])
860 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations $1])
862 AT_DATA_GRAMMAR([glr-regr8.y],
864 %code {
865   ]AT_YYERROR_DECLARE[
866   ]AT_YYLEX_DECLARE[
869 %define parse.assert
870 %define parse.trace
871 %glr-parser
872 %expect-rr 1
873 ]$1[
875 %token T_CONSTANT
876 %token T_PORT
877 %token T_SIGNAL
882 PortClause      : T_PORT InterfaceDeclaration T_PORT
883                 { printf("%d/%d - %d/%d - %d/%d\n",
884                          @1.]AT_FIRST_COLUMN[, @1.]AT_LAST_COLUMN[,
885                          @2.]AT_FIRST_COLUMN[, @2.]AT_LAST_COLUMN[,
886                          @3.]AT_FIRST_COLUMN[, @3.]AT_LAST_COLUMN[); }
887         ;
889 InterfaceDeclaration    : OptConstantWord       %dprec 1
890         | OptSignalWord %dprec 2
891         ;
893 OptConstantWord : %empty
894         | T_CONSTANT
895         ;
897 OptSignalWord   : %empty
898                 { printf("empty: %d/%d\n", @$.]AT_FIRST_COLUMN[, @$.]AT_LAST_COLUMN[); }
899         | T_SIGNAL
900         ;
904 ]AT_YYERROR_DEFINE[
905 static int lexIndex;
907 ]AT_YYLEX_PROTOTYPE[
909   ]AT_USE_LEX_ARGS[
910   lexIndex += 1;
911   switch (lexIndex)
912     {
913     default:
914       abort ();
915     case 1:
916       ]AT_LOC_FIRST_COLUMN[ = 1;
917       ]AT_LOC_LAST_COLUMN[ = 9;
918       return ]AT_TOKEN([T_PORT])[;
919     case 2:
920       ]AT_LOC_FIRST_COLUMN[ = 13;
921       ]AT_LOC_LAST_COLUMN[ = 17;
922       return ]AT_TOKEN([T])[_PORT;
923     case 3:
924       return 0;
925     }
928 ]AT_MAIN_DEFINE[
931 AT_FULL_COMPILE([glr-regr8],,,, [-rall])
933 AT_PARSER_CHECK([[glr-regr8]], 0,
934 [empty: 9/9
935 1/9 - 9/9 - 13/17
939 AT_BISON_OPTION_POPDEFS
940 AT_CLEANUP
943 AT_TEST([%skeleton "glr.c"])
944 AT_TEST([%skeleton "glr.cc"])
945 AT_TEST([%skeleton "glr2.cc"])
947 m4_popdef([AT_TEST])
951 ## --------------------------------------------------------------- ##
952 ## No users destructors if stack 0 deleted.  See                   ##
953 ## <https://lists.gnu.org/r/bison-patches/2005-09/msg00109.html>.  ##
954 ## --------------------------------------------------------------- ##
956 m4_pushdef([AT_TEST],
957 [AT_SETUP([No users destructors if stack 0 deleted: $1])
959 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
960 AT_DATA_GRAMMAR([glr-regr9.y],
962 %code {
963   ]AT_YYERROR_DECLARE[
964   ]AT_YYLEX_DECLARE[
965 # define YYSTACKEXPANDABLE 0
966   static int tokens = 0;
967   static int destructors = 0;
968 # define USE(Var)
971 %define parse.assert
972 %define parse.trace
973 %glr-parser
974 %expect-rr 2
975 ]$1[
977 %union { int dummy; }
978 %type <dummy> 'a'
980 %destructor {
981   destructors += 1;
982 } 'a'
986 start:
987     ambig0 'a'   { destructors += 2; USE ($][2); }
988   | ambig1 start { destructors += 1; }
989   | ambig2 start { destructors += 1; }
990   ;
992 ambig0: 'a' ;
993 ambig1: 'a' ;
994 ambig2: 'a' ;
998 ]AT_YYLEX_PROTOTYPE[
1000   ]AT_USE_LEX_ARGS[
1001   tokens += 1;
1002   return 'a';
1005 ]AT_YYERROR_DEFINE[
1006 ]AT_YYPARSE_DEFINE[
1009 main (void)
1011   int status;
1012   if (getenv ("YYDEBUG"))
1013     yydebug = 1;
1014   status = yyparse ();
1015   if (tokens != destructors)
1016     {
1017       fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
1018       return 10;
1019     }
1020   return status;
1024 AT_FULL_COMPILE([glr-regr9],,,, [-rall])
1026 # Exit 2: memory exhausted.
1027 AT_PARSER_CHECK([[glr-regr9]], 2, [],
1028 [memory exhausted
1031 AT_BISON_OPTION_POPDEFS
1032 AT_CLEANUP
1035 AT_TEST([%skeleton "glr.c"])
1036 AT_TEST([%skeleton "glr.cc"])
1037 AT_TEST([%skeleton "glr2.cc"])
1039 m4_popdef([AT_TEST])
1043 ## ------------------------------------------------------ ##
1044 ## Corrupted semantic options if user action cuts parse.  ##
1045 ## ------------------------------------------------------ ##
1047 m4_pushdef([AT_TEST],
1048 [AT_SETUP([Corrupted semantic options if user action cuts parse: $1])
1050 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
1051 AT_DATA_GRAMMAR([glr-regr10.y],
1053 %code {
1054   ]AT_YYERROR_DECLARE[
1055   ]AT_YYLEX_DECLARE[
1056   #define GARBAGE_SIZE 50
1057   static char garbage[GARBAGE_SIZE];
1060 %define parse.assert
1061 %define parse.trace
1062 %glr-parser
1063 %expect-rr 1
1064 ]$1[
1066 %union { char *ptr; }
1067 %type <ptr> start
1071 start:
1072     %dprec 2 { $$ = garbage; YYACCEPT; }
1073   | %dprec 1 { $$ = garbage; YYACCEPT; }
1074   ;
1077 ]AT_YYERROR_DEFINE[
1078 ]AT_YYPARSE_DEFINE[
1079 ]AT_YYLEX_DEFINE[
1082 main (void)
1084   int i;
1085   for (i = 0; i < GARBAGE_SIZE; i+=1)
1086     garbage[i] = 108;
1087   if (getenv ("YYDEBUG"))
1088     yydebug = 1;
1089   return yyparse ();
1093 AT_FULL_COMPILE([glr-regr10],,,, [-rall])
1095 AT_PARSER_CHECK([[glr-regr10]], 0, [], [])
1097 AT_BISON_OPTION_POPDEFS
1098 AT_CLEANUP
1101 AT_TEST([%skeleton "glr.c"])
1102 AT_TEST([%skeleton "glr.cc"])
1103 AT_TEST([%skeleton "glr2.cc"])
1105 m4_popdef([AT_TEST])
1109 ## --------------------------------------------------- ##
1110 ## Undesirable destructors if user action cuts parse.  ##
1111 ## --------------------------------------------------- ##
1113 m4_pushdef([AT_TEST],
1114 [AT_SETUP([Undesirable destructors if user action cuts parse: $1])
1116 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
1117 AT_DATA_GRAMMAR([glr-regr11.y],
1119 %code {
1120   ]AT_YYERROR_DECLARE[
1121   ]AT_YYLEX_DECLARE[
1122   static int destructors = 0;
1123 # define USE(val)
1126 %define parse.assert
1127 %define parse.trace
1128 %glr-parser
1129 %expect-rr 1
1130 ]$1[
1132 %union { int dummy; }
1133 %type <int> 'a'
1134 %destructor { destructors += 1; } 'a'
1138 start:
1139     'a' %dprec 2 { USE ($][1); destructors += 1; YYACCEPT; }
1140   | 'a' %dprec 1 { USE ($][1); destructors += 1; YYACCEPT; }
1141   ;
1145 ]AT_YYERROR_DEFINE[
1146 ]AT_YYPARSE_DEFINE[
1147 ]AT_YYLEX_DEFINE(["a"])[
1150 main (void)
1152   int status;
1153   if (getenv ("YYDEBUG"))
1154     yydebug = 1;
1155   status = yyparse ();
1156   if (destructors != 1)
1157     {
1158       fprintf (stderr, "Destructor calls: %d\n", destructors);
1159       return 1;
1160     }
1161   return status;
1165 AT_FULL_COMPILE([glr-regr11],,,, [-rall])
1167 AT_PARSER_CHECK([[glr-regr11]], 0, [], [])
1169 AT_BISON_OPTION_POPDEFS
1170 AT_CLEANUP
1173 AT_TEST([%skeleton "glr.c"])
1174 AT_TEST([%skeleton "glr.cc"])
1175 AT_TEST([%skeleton "glr2.cc"])
1177 m4_popdef([AT_TEST])
1181 ## -------------------------------------------------- ##
1182 ## Leaked semantic values if user action cuts parse.  ##
1183 ## -------------------------------------------------- ##
1185 m4_pushdef([AT_TEST],
1186 [AT_SETUP([Leaked semantic values if user action cuts parse: $1])
1187 AT_KEYWORDS([%merge])
1189 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
1190 AT_DATA_GRAMMAR([glr-regr12.y],
1192 %define parse.assert
1193 %define parse.trace
1194 %glr-parser
1195 %expect 1
1196 %expect-rr 1
1197 ]$1[
1199 %union { int dummy; }
1200 %token PARENT_RHS_AFTER
1201 %type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
1202 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1203 %destructor { merged_value = 0; } merged
1204 %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
1206 %code {
1207 # include <assert.h>
1208   static int merge (]AT_YYSTYPE[, ]AT_YYSTYPE[);
1209   ]AT_YYERROR_DECLARE[
1210   ]AT_YYLEX_DECLARE[
1211   static int parent_rhs_before_value = 0;
1212   static int merged_value = 0;
1213   static int parent_rhs_after_value = 0;
1214 # define USE(val)
1219 start:
1220   alt1 %dprec 1
1221   | alt2 %dprec 2
1222   ;
1224 alt1:
1225   PARENT_RHS_AFTER {
1226     USE ($][1);
1227     parent_rhs_after_value = 0;
1228   }
1229   ;
1231 alt2:
1232   parent_rhs_before merged PARENT_RHS_AFTER {
1233     USE (($][1, $][2, $][3));
1234     parent_rhs_before_value = 0;
1235     merged_value = 0;
1236     parent_rhs_after_value = 0;
1237   }
1238   ;
1240 parent_rhs_before:
1241   {
1242     USE ($$);
1243     parent_rhs_before_value = 1;
1244   }
1245   ;
1247 merged:
1248   %merge<merge> {
1249     USE ($$);
1250     merged_value = 1;
1251   }
1252   | cut %merge<merge> {
1253     USE ($$);
1254     merged_value = 1;
1255   }
1256   ;
1258 cut: { YYACCEPT; } ;
1262 static int
1263 merge (]AT_YYSTYPE[ s1, ]AT_YYSTYPE[ s2)
1265   /* Not invoked. */
1266   return s1.dummy + s2.dummy;
1269 ]AT_YYERROR_DEFINE[
1270 ]AT_YYPARSE_DEFINE[
1271 ]AT_YYLEX_DEFINE([{ ]AT_TOKEN([PARENT_RHS_AFTER])[, 0 }],
1272  [if (res == ]AT_TOKEN([PARENT_RHS_AFTER])[)
1273     parent_rhs_after_value = 1;])[
1276 main (void)
1278   int status;
1279   if (getenv ("YYDEBUG"))
1280     yydebug = 1;
1281   status = yyparse ();
1282   if (parent_rhs_before_value)
1283     {
1284       fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1285       status = 1;
1286     }
1287   if (merged_value)
1288     {
1289       fprintf (stderr, "'merged' destructor not called.\n");
1290       status = 1;
1291     }
1292   if (parent_rhs_after_value)
1293     {
1294       fprintf (stderr, "'PARENT_RHS_AFTER' destructor not called.\n");
1295       status = 1;
1296     }
1297   return status;
1301 AT_FULL_COMPILE([glr-regr12],,,, [-rall])
1303 AT_PARSER_CHECK([[glr-regr12]], 0, [], [])
1305 AT_BISON_OPTION_POPDEFS
1306 AT_CLEANUP
1309 AT_TEST([%skeleton "glr.c"])
1310 AT_TEST([%skeleton "glr.cc"])
1311 AT_TEST([%skeleton "glr2.cc"])
1313 m4_popdef([AT_TEST])
1317 ## --------------------------------------------------------------- ##
1318 ## Incorrect lookahead during deterministic GLR.  See              ##
1319 ## <https://lists.gnu.org/r/help-bison/2005-07/msg00017.html> and  ##
1320 ## <https://lists.gnu.org/r/bison-patches/2006-01/msg00060.html>.  ##
1321 ## --------------------------------------------------------------- ##
1323 m4_pushdef([AT_TEST],
1324 [AT_SETUP([Incorrect lookahead during deterministic GLR: $1])
1326 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations $1])
1327 AT_DATA_GRAMMAR([glr-regr13.y],
1329 /* Tests:
1330      - Defaulted state with initial yychar: yychar == YYEMPTY.
1331      - Nondefaulted state: yychar != YYEMPTY.
1332      - Defaulted state after lookahead: yychar != YYEMPTY.
1333      - Defaulted state after shift: yychar == YYEMPTY.
1334      - User action changing the lookahead.  */
1336 %code {
1337   #include <assert.h>
1338   ]AT_YYERROR_DECLARE[
1339   ]AT_YYLEX_DECLARE[
1340   ]AT_PRINT_LOOKAHEAD_DECLARE[
1341   #define USE(value)
1344 %define parse.assert
1345 %define parse.trace
1346 %locations
1347 %glr-parser
1348 ]$1[
1350 %union { char value; }
1351 %type <value> 'a' 'b'
1355 start:
1356   defstate_init defstate_shift 'b' change_lookahead 'a'
1357     {
1358       USE ($][3);
1359       PRINT_LOOKAHEAD ("start <- defstate_init defstate_shift 'b'");
1360     }
1363 defstate_init:
1364   %empty
1365     {
1366       PRINT_LOOKAHEAD ("defstate_init <- empty string");
1367     }
1370 defstate_shift:
1371   nondefstate defstate_look 'a'
1372     {
1373       USE ($][3);
1374       PRINT_LOOKAHEAD ("defstate_shift <- nondefstate defstate_look 'a'");
1375     }
1378 defstate_look:
1379   %empty
1380     {
1381       PRINT_LOOKAHEAD ("defstate_look <- empty string");
1382     }
1385 nondefstate:
1386   %empty
1387     {
1388       PRINT_LOOKAHEAD ("nondefstate <- empty string");
1389     }
1390 | 'b'
1391     {
1392       USE ($][1);
1393       PRINT_LOOKAHEAD ("nondefstate <- 'b'");
1394     }
1397 change_lookahead:
1398   %empty
1399     {
1400       ]AT_GLR2_CC_IF([[yytoken = yy::parser::yytranslate_ ('a')]], [[yychar = 'a']])[;
1401     }
1406 ]AT_YYERROR_DEFINE[
1407 ]AT_YYPARSE_DEFINE[
1408 ]AT_PRINT_LOOKAHEAD_DEFINE[
1409 ]AT_YYLEX_DEFINE(["ab"],
1410                  []AT_VAL[.value = YY_CAST (char, res + 'A' - 'a')])[
1413 main (void)
1415 ]AT_CXX_IF([], [[
1416   yychar = '#'; /* Not a token in the grammar.  */
1417   yylval.value = '!';
1418 ]])[
1419   if (getenv ("YYDEBUG"))
1420     yydebug = 1;
1421   return yyparse ();
1425 AT_FULL_COMPILE([glr-regr13],,,, [-rall])
1427 AT_PARSER_CHECK([[glr-regr13]], 0,
1428 [defstate_init <- empty string:
1429   yychar=YYEMPTY
1430 nondefstate <- empty string:
1431   yychar='a', yylval='A', yylloc=(1,1),(1,1)
1432 defstate_look <- empty string:
1433   yychar='a', yylval='A', yylloc=(1,1),(1,1)
1434 defstate_shift <- nondefstate defstate_look 'a':
1435   yychar=YYEMPTY
1436 start <- defstate_init defstate_shift 'b':
1437   yychar=YYEMPTY
1438 ], [])
1440 AT_BISON_OPTION_POPDEFS
1441 AT_CLEANUP
1444 AT_TEST([%skeleton "glr.c"])
1445 AT_TEST([%skeleton "glr.cc"])
1446 AT_TEST([%skeleton "glr2.cc"])
1448 m4_popdef([AT_TEST])
1452 ## ------------------------------------------------- ##
1453 ## Incorrect lookahead during nondeterministic GLR.  ##
1454 ## ------------------------------------------------- ##
1456 m4_pushdef([AT_TEST],
1457 [AT_SETUP([Incorrect lookahead during nondeterministic GLR: $1])
1458 AT_KEYWORDS([%merge])
1460 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations $1])
1462 AT_DATA_GRAMMAR([glr-regr14.y],
1464 /* Tests:
1465      - Conflicting actions (split-off parse, which copies lookahead need,
1466        which is necessarily yytrue) and nonconflicting actions (non-split-off
1467        parse) for nondefaulted state: yychar != YYEMPTY.
1468      - Merged deferred actions (lookahead need and RHS from different stack
1469        than the target state) and nonmerged deferred actions (same stack).
1470      - Defaulted state after lookahead: yychar != YYEMPTY.
1471      - Defaulted state after shift: yychar == YYEMPTY.
1472      - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has
1473        seen the lookahead but current stack has not).
1474      - Exceeding stack capacity (stack explosion), and thus reallocating
1475        lookahead need array.
1476    Note that it does not seem possible to see the initial yychar value during
1477    nondeterministic operation since:
1478      - In order to preserve the initial yychar, only defaulted states may be
1479        entered.
1480      - If only defaulted states are entered, there are no conflicts, so
1481        nondeterministic operation does not start.  */
1483 %define parse.assert
1484 %define parse.trace
1485 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1486 %glr-parser
1487 %expect 0
1488 %expect-rr 5
1489 ]$1[
1490 %locations
1492 %union { char value; }
1494 %code {
1495   #include <assert.h>
1496   ]AT_YYERROR_DECLARE[
1497   ]AT_YYLEX_DECLARE[
1498   ]AT_PRINT_LOOKAHEAD_DECLARE[
1499   static char merge (]AT_YYSTYPE[, ]AT_YYSTYPE[);
1500   #define USE(value)
1505 start:
1506   merge 'c' stack_explosion
1507     {
1508       USE ($][2); USE ($][3);
1509       PRINT_LOOKAHEAD ("start <- merge 'c' stack_explosion");
1510     }
1513 /* When merging the 2 deferred actions, the lookahead needs are different.  */
1514 merge:
1515   nonconflict1 'a' 'b' nonconflict2 %dprec 1
1516     {
1517       USE ($][2); USE ($][3);
1518       PRINT_LOOKAHEAD ("merge <- nonconflict1 'a' 'b' nonconflict2");
1519     }
1520 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2
1521     {
1522       USE ($][3); USE ($][5);
1523       PRINT_LOOKAHEAD ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1524                        " defstate_shift");
1525     }
1528 nonconflict1:
1529   %empty
1530     {
1531       PRINT_LOOKAHEAD ("nonconflict1 <- empty string");
1532     }
1535 nonconflict2:
1536   %empty
1537     {
1538       PRINT_LOOKAHEAD ("nonconflict2 <- empty string");
1539     }
1540 | 'a'
1541     {
1542       USE ($][1);
1543       PRINT_LOOKAHEAD ("nonconflict2 <- 'a'");
1544     }
1547 conflict:
1548   %empty
1549   {
1550     PRINT_LOOKAHEAD ("conflict <- empty string");
1551   }
1554 defstate_look:
1555   %empty
1556   {
1557     PRINT_LOOKAHEAD ("defstate_look <- empty string");
1558   }
1561 /* yychar != YYEMPTY but lookahead need is yyfalse.  */
1562 defstate_shift:
1563   %empty
1564   {
1565     PRINT_LOOKAHEAD ("defstate_shift <- empty string");
1566   }
1569 stack_explosion:
1570   %empty { $$ = '\0'; }
1571 | alt1 stack_explosion %merge<merge> { $$ = $][2; }
1572 | alt2 stack_explosion %merge<merge> { $$ = $][2; }
1573 | alt3 stack_explosion %merge<merge> { $$ = $][2; }
1576 alt1:
1577   'd' no_look
1578     {
1579       USE ($][1);
1580       if (]AT_GLR2_CC_IF(
1581         [[yytoken != yy::parser::yytranslate_ ('d') && yytoken != symbol_kind::S_YYEOF]],
1582         [[yychar != 'd' && yychar != ]AT_GLR2_CC_IF([token::])[YYEOF]])[)
1583         PRINT_LOOKAHEAD ("Incorrect lookahead during stack explosion.");
1584     }
1587 alt2:
1588   'd' no_look
1589     {
1590       USE ($][1);
1591       if (]AT_GLR2_CC_IF(
1592         [[yytoken != yy::parser::yytranslate_ ('d') && yytoken != symbol_kind::S_YYEOF]],
1593         [[yychar != 'd' && yychar != ]AT_GLR2_CC_IF([token::])[YYEOF]])[)
1594         PRINT_LOOKAHEAD ("Incorrect lookahead during stack explosion.");
1595     }
1598 alt3:
1599   'd' no_look
1600     {
1601       USE ($][1);
1602         if (]AT_GLR2_CC_IF(
1603           [[yytoken != yy::parser::yytranslate_ ('d') && yytoken != symbol_kind::S_YYEOF]],
1604           [[yychar != 'd' && yychar != ]AT_GLR2_CC_IF([token::])[YYEOF]])[)
1605         PRINT_LOOKAHEAD ("Incorrect lookahead during stack explosion.");
1606     }
1609 no_look:
1610   %empty
1611     {
1612       if (]AT_GLR2_CC_IF(
1613         [[yytoken != symbol_kind::S_YYEMPTY]],
1614         [[yychar != ]AT_GLR2_CC_IF([token::])[YYEMPTY]])[)
1615         PRINT_LOOKAHEAD ("Found lookahead where shouldn't during stack explosion.");
1616     }
1621 ]AT_YYERROR_DEFINE[
1622 ]AT_YYPARSE_DEFINE[
1623 ]AT_PRINT_LOOKAHEAD_DEFINE[
1625 ]AT_YYLEX_PROTOTYPE[
1627   ]AT_USE_LEX_ARGS[
1628   static char const input[] = "abcdddd";
1629   static int toknum = 0;
1630   assert (toknum < YY_CAST (int, sizeof input));
1631   ]AT_LOC_FIRST_LINE[ = ]AT_LOC_LAST_LINE[ = 1;
1632   ]AT_LOC_FIRST_COLUMN[ = ]AT_LOC_LAST_COLUMN[ = toknum + 1;
1633   ]AT_VAL[.value = YY_CAST (char, input[toknum] + 'A' - 'a');
1634   return input[toknum++];
1637 static char
1638 merge (]AT_YYSTYPE[ s1, ]AT_YYSTYPE[ s2)
1640   return YY_CAST (char, s1.value + s2.value);
1644 main (void)
1646 ]AT_CXX_IF([], [[
1647   yychar = '#'; /* Not a token in the grammar.  */
1648   yylval.value = '!';
1649 ]])[
1650   if (getenv ("YYDEBUG"))
1651     yydebug = 1;
1652   return yyparse ();
1656 AT_FULL_COMPILE([glr-regr14],,,, [-rall])
1658 AT_PARSER_CHECK([[glr-regr14]], 0,
1659 [conflict <- empty string:
1660   yychar='a', yylval='A', yylloc=(1,1),(1,1)
1661 defstate_look <- empty string:
1662   yychar='a', yylval='A', yylloc=(1,1),(1,1)
1663 nonconflict2 <- empty string:
1664   yychar='b', yylval='B', yylloc=(1,2),(1,2)
1665 defstate_shift <- empty string:
1666   yychar=YYEMPTY
1667 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1668   yychar=YYEMPTY
1669 start <- merge 'c' stack_explosion:
1670   yychar=YYEOF
1671 ], [])
1673 AT_BISON_OPTION_POPDEFS
1674 AT_CLEANUP
1677 AT_TEST([%skeleton "glr.c"])
1678 AT_TEST([%skeleton "glr.cc"])
1679 AT_TEST([%skeleton "glr2.cc"])
1681 m4_popdef([AT_TEST])
1685 ## ------------------------------------------------- ##
1686 ## Leaked semantic values when reporting ambiguity.  ##
1687 ## ------------------------------------------------- ##
1689 m4_pushdef([AT_TEST],
1690 [AT_SETUP([Leaked semantic values when reporting ambiguity: $1])
1692 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
1694 AT_DATA_GRAMMAR([glr-regr15.y],
1696 %define parse.assert
1697 %define parse.trace
1698 %glr-parser
1699 %expect 0
1700 %expect-rr 2
1701 ]$1[
1703 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1705 %code {
1706   ]AT_YYERROR_DECLARE[
1707   ]AT_YYLEX_DECLARE[
1708   static int parent_rhs_before_value = 0;
1709 # define USE(val)
1714 start:
1715   alt1 %dprec 1
1716   | alt2 %dprec 2
1717   ;
1719 /* This stack must be merged into the other stacks *last* (added at the
1720    beginning of the semantic options list) so that yyparse will choose to clean
1721    it up rather than the tree for which some semantic actions have been
1722    performed.  Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
1723    those other trees are not cleaned up.  */
1724 alt1: ;
1726 alt2:
1727   parent_rhs_before ambiguity {
1728     USE ($][1);
1729     parent_rhs_before_value = 0;
1730   }
1731   ;
1733 parent_rhs_before:
1734   {
1735     USE ($$);
1736     parent_rhs_before_value = 1;
1737   }
1738   ;
1740 ambiguity: ambiguity1 | ambiguity2 ;
1741 ambiguity1: ;
1742 ambiguity2: ;
1745 ]AT_YYERROR_DEFINE[
1746 ]AT_YYPARSE_DEFINE[
1747 ]AT_YYLEX_DEFINE[
1750 main (void)
1752   int status;
1753   if (getenv ("YYDEBUG"))
1754     yydebug = 1;
1755   status = yyparse () != 1;
1756   if (parent_rhs_before_value)
1757     {
1758       fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1759       status = 1;
1760     }
1761   return status;
1765 AT_FULL_COMPILE([glr-regr15],,,, [-rall])
1767 AT_PARSER_CHECK([[glr-regr15]], 0, [],
1768 [Ambiguity detected.
1769 Option 1,
1770   ambiguity -> <Rule 6, empty>
1771     ambiguity1 -> <Rule 8, empty>
1773 Option 2,
1774   ambiguity -> <Rule 7, empty>
1775     ambiguity2 -> <Rule 9, empty>
1777 syntax is ambiguous
1780 AT_BISON_OPTION_POPDEFS
1781 AT_CLEANUP
1784 AT_TEST([%skeleton "glr.c"])
1785 AT_TEST([%skeleton "glr.cc"])
1786 AT_TEST([%skeleton "glr2.cc"])
1788 m4_popdef([AT_TEST])
1792 ## ------------------------------------------------------------ ##
1793 ## Leaked lookahead after nondeterministic parse syntax error.  ##
1794 ## ------------------------------------------------------------ ##
1796 m4_pushdef([AT_TEST],
1797 [AT_SETUP([Leaked lookahead after nondeterministic parse syntax error: $1])
1799 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
1800 AT_DATA_GRAMMAR([glr-regr16.y],
1802 %define parse.assert
1803 %define parse.trace
1804 %glr-parser
1805 %expect 0
1806 %expect-rr 1
1807 ]$1[
1809 %destructor { lookahead_value = 0; } 'b'
1811 %code {
1812 # include <assert.h>
1813   ]AT_YYERROR_DECLARE[
1814   ]AT_YYLEX_DECLARE[
1815   static int lookahead_value = 0;
1816 # define USE(val)
1821 start: alt1 'a' | alt2 'a' ;
1822 alt1: ;
1823 alt2: ;
1827 ]AT_YYERROR_DEFINE[
1828 ]AT_YYPARSE_DEFINE[
1829 ]AT_YYLEX_DEFINE(["ab"],
1830   [if (res == 'b')
1831     lookahead_value = 1])[
1834 main (void)
1836   int status;
1837   if (getenv ("YYDEBUG"))
1838     yydebug = 1;
1839   status = yyparse () != 1;
1840   if (lookahead_value)
1841     {
1842       fprintf (stderr, "Lookahead destructor not called.\n");
1843       status = 1;
1844     }
1845   return status;
1849 AT_FULL_COMPILE([glr-regr16],,,, [-rall])
1851 AT_PARSER_CHECK([[glr-regr16]], 0, [],
1852 [syntax error
1855 AT_BISON_OPTION_POPDEFS
1856 AT_CLEANUP
1859 AT_TEST([%skeleton "glr.c"])
1860 AT_TEST([%skeleton "glr.cc"])
1861 AT_TEST([%skeleton "glr2.cc"])
1863 m4_popdef([AT_TEST])
1867 ## ------------------------------------------------- ##
1868 ## Uninitialized location when reporting ambiguity.  ##
1869 ## ------------------------------------------------- ##
1871 m4_pushdef([AT_TEST],
1872 [AT_SETUP([Uninitialized location when reporting ambiguity: $1])
1874 AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations $1])
1876 AT_DATA_GRAMMAR([glr-regr17.y],
1878 %define parse.assert
1879 %define parse.trace
1880 %glr-parser
1881 %expect 0
1882 %expect-rr 3
1883 ]$1[
1884 %locations
1885 %define parse.error verbose
1887 %union { int dummy; }
1889 %code {
1890   ]AT_YYERROR_DECLARE[
1891   ]AT_YYLEX_DECLARE[
1896 /* Tests the case of an empty RHS that has inherited the location of the
1897    previous nonterminal, which is unresolved.  That location is reported as the
1898    last position of the ambiguity.  */
1899 start: ambig1 empty1 | ambig2 empty2 ;
1901 /* Tests multiple levels of yyresolveLocations recursion.  */
1902 ambig1: sub_ambig1 | sub_ambig2 ;
1903 ambig2: sub_ambig1 | sub_ambig2 ;
1905 /* Tests the case of a non-empty RHS as well as the case of an empty RHS that
1906    has inherited the initial location.  The empty RHS's location is reported as
1907    the first position in the ambiguity.  */
1908 sub_ambig1: empty1 'a' 'b' ;
1909 sub_ambig2: empty2 'a' 'b' ;
1910 empty1: ;
1911 empty2: ;
1914 # include <assert.h>
1916 ]AT_YYERROR_DEFINE[
1918 ]AT_YYLEX_PROTOTYPE[
1920   static char const input[] = "ab";
1921   static int toknum = 0;
1922   ]AT_USE_LEX_ARGS[
1923   assert (toknum < YY_CAST (int, sizeof input));
1924   lvalp->dummy = 0;
1925   ]AT_LOC_FIRST_LINE[ = ]AT_LOC_LAST_LINE[ = 2;
1926   ]AT_LOC_FIRST_COLUMN[ = toknum + 1;
1927   ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_COLUMN[ + 1;
1928   return input[toknum++];
1931 ]AT_MAIN_DEFINE[
1934 AT_FULL_COMPILE([glr-regr17],,,, [-rall])
1936 AT_PARSER_CHECK([[glr-regr17]], 1, [],
1937 [Ambiguity detected.
1938 Option 1,
1939   start -> <Rule 1, tokens 1 .. 2>
1940     ambig1 -> <Rule 4, tokens 1 .. 2>
1941       sub_ambig2 -> <Rule 8, tokens 1 .. 2>
1942         empty2 -> <Rule 10, empty>
1943         'a' <tokens 1 .. 1>
1944         'b' <tokens 2 .. 2>
1945     empty1 -> <Rule 9, empty>
1947 Option 2,
1948   start -> <Rule 2, tokens 1 .. 2>
1949     ambig2 -> <Rule 6, tokens 1 .. 2>
1950       sub_ambig2 -> <Rule 8, tokens 1 .. 2>
1951         empty2 -> <Rule 10, empty>
1952         'a' <tokens 1 .. 1>
1953         'b' <tokens 2 .. 2>
1954     empty2 -> <Rule 10, empty>
1956 1.1-2.2: syntax is ambiguous
1959 AT_BISON_OPTION_POPDEFS
1960 AT_CLEANUP
1963 AT_TEST([%skeleton "glr.c" %define api.pure])
1964 AT_TEST([%skeleton "glr.cc"])
1965 AT_TEST([%skeleton "glr2.cc"])
1967 m4_popdef([AT_TEST])
1971 ## ------------------------------------------------------------- ##
1972 ## Missed %merge type warnings when LHS type is declared later.  ##
1973 ## ------------------------------------------------------------- ##
1975 m4_pushdef([AT_TEST],
1976 [AT_SETUP([Missed %merge type warnings when LHS type is declared later: $1])
1977 AT_KEYWORDS([%merge])
1979 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
1980 AT_DATA_GRAMMAR([glr-regr18.y],
1981 [[%define parse.assert
1982 %define parse.trace
1983 %glr-parser
1984 ]$1[
1986 %code {
1987   ]AT_YYERROR_DECLARE[
1988   ]AT_YYLEX_DECLARE[
1991 %union {
1992   int type1;
1993   int type2;
1994   int type3;
1996 ]AT_CXX_IF([[
1997 // In C++ we need one more line for the line numbers to match.
1998 ]])[
2001 sym1: sym2 %merge<merge> { $$ = $][1; } ;
2002 sym2: sym3 %merge<merge> { $$ = $][1; } ;
2003 sym3: %merge<merge> { $$ = 0; } ;
2005 %type <type1> sym1;
2006 %type <type2> sym2;
2007 %type <type3> sym3;
2010 ]AT_YYERROR_DEFINE[
2011 ]AT_YYLEX_DEFINE[
2012 ]AT_MAIN_DEFINE[
2015 AT_BISON_CHECK([[-o glr-regr18.c -rall -fcaret glr-regr18.y]], 1, [],
2016 [[glr-regr18.y:30.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
2017    30 | sym2: sym3 %merge<merge> { $$ = $][1; } ;
2018       |                  ^~~~~~~
2019 glr-regr18.y:29.18-24: note: previous declaration
2020    29 | sym1: sym2 %merge<merge> { $$ = $][1; } ;
2021       |                  ^~~~~~~
2022 glr-regr18.y:31.13-19: error: result type clash on merge function 'merge': <type3> != <type1>
2023    31 | sym3: %merge<merge> { $$ = 0; } ;
2024       |             ^~~~~~~
2025 glr-regr18.y:29.18-24: note: previous declaration
2026    29 | sym1: sym2 %merge<merge> { $$ = $][1; } ;
2027       |                  ^~~~~~~
2030 AT_BISON_OPTION_POPDEFS
2031 AT_CLEANUP
2034 AT_TEST([%skeleton "glr.c"])
2035 AT_TEST([%skeleton "glr.cc"])
2036 AT_TEST([%skeleton "glr2.cc"])
2038 m4_popdef([AT_TEST])
2042 ## ------------------- ##
2043 ## Ambiguity reports.  ##
2044 ## ------------------- ##
2046 m4_pushdef([AT_TEST],
2047 [AT_SETUP([Ambiguity reports: $1])
2049 AT_BISON_OPTION_PUSHDEFS([%glr-parser %debug $1])
2050 AT_DATA_GRAMMAR([input.y],
2051 [[%code {
2052   ]AT_YYERROR_DECLARE[
2053   ]AT_YYLEX_DECLARE[
2056 %define parse.assert
2057 %define parse.trace
2058 %debug
2059 %glr-parser
2060 %expect 0
2061 %expect-rr 1
2062 ]$1[
2063 ]AT_CXX_IF([[
2064 // In C++ we need two more lines for the line numbers in the trace to match.
2065 ]])[
2068 start:
2069   'a' b 'c' d
2070 | 'a' b 'c' d
2072 b: 'b';
2073 d: %empty;
2075 ]AT_YYERROR_DEFINE[
2076 ]AT_YYLEX_DEFINE(["abc"])[
2077 ]AT_MAIN_DEFINE[
2080 AT_FULL_COMPILE([input])
2082 AT_PARSER_CHECK([[input --debug]], 1, [],
2083 [Starting parse
2084 Entering state 0
2085 Reading a token
2086 Next token is token 'a' ()
2087 Shifting token 'a' ()
2088 Entering state 1
2089 Reading a token
2090 Next token is token 'b' ()
2091 Shifting token 'b' ()
2092 Entering state 3
2093 Reducing stack 0 by rule 3 (line 30):
2094    $][1 = token 'b' ()
2095 -> $][$ = nterm b ()
2096 Entering state 4
2097 Reading a token
2098 Next token is token 'c' ()
2099 Shifting token 'c' ()
2100 Entering state 6
2101 Reducing stack 0 by rule 4 (line 31):
2102 -> $][$ = nterm d ()
2103 Entering state 7
2104 Reading a token
2105 Now at end of input.
2106 Stack 0 Entering state 7
2107 Now at end of input.
2108 Splitting off stack 1 from 0.
2109 Reduced stack 1 by rule 2 (line 28); action deferred.  Now in state 2.
2110 Stack 1 Entering state 2
2111 Now at end of input.
2112 Reduced stack 0 by rule 1 (line 27); action deferred.  Now in state 2.
2113 Merging stack 0 into stack 1.
2114 Stack 1 Entering state 2
2115 Now at end of input.
2116 Removing dead stacks.
2117 Rename stack 1 -> 0.
2118 On stack 0, shifting token "end of file" ()
2119 Stack 0 now in state 5
2120 Ambiguity detected.
2121 Option 1,
2122   start -> <Rule 1, tokens 1 .. 3>
2123     'a' <tokens 1 .. 1>
2124     b <tokens 2 .. 2>
2125     'c' <tokens 3 .. 3>
2126     d <empty>
2128 Option 2,
2129   start -> <Rule 2, tokens 1 .. 3>
2130     'a' <tokens 1 .. 1>
2131     b <tokens 2 .. 2>
2132     'c' <tokens 3 .. 3>
2133     d <empty>
2135 syntax is ambiguous
2136 Cleanup: popping token "end of file" ()
2137 Cleanup: popping unresolved nterm start ()
2138 Cleanup: popping nterm d ()
2139 Cleanup: popping token 'c' ()
2140 Cleanup: popping nterm b ()
2141 Cleanup: popping token 'a' ()
2144 AT_BISON_OPTION_POPDEFS
2145 AT_CLEANUP
2148 AT_TEST([%skeleton "glr.c"])
2149 AT_TEST([%skeleton "glr.cc"])
2150 AT_TEST([%skeleton "glr2.cc"])
2152 m4_popdef([AT_TEST])
2156 ## ------------------------------------------------------- ##
2157 ## Predicates.                                             ##
2158 ##                                                         ##
2159 ## https://lists.gnu.org/r/bug-bison/2013-10/msg00004.html ##
2160 ## https://lists.gnu.org/r/bug-bison/2018-05/msg00033.html ##
2161 ## ------------------------------------------------------- ##
2163 m4_pushdef([AT_TEST],
2164 [AT_SETUP([Predicates: $1])
2166 AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
2167 AT_DATA_GRAMMAR([input.y],
2168 [[%define parse.assert
2169 %define parse.trace
2170 %glr-parser
2171 %define parse.error verbose
2172 %expect-rr 1
2173 ]$1[
2175 %code
2177   #include <assert.h>
2178   #include <stdbool.h>
2179   bool new_syntax = false;
2180   const char *input = YY_NULLPTR;
2181   ]AT_YYERROR_DECLARE[
2182   ]AT_YYLEX_DECLARE[
2185 widget:
2186   %? {new_syntax} 'w' id new_args  { printf("new"); }
2187 | %?{!new_syntax} 'w' id old_args  { printf("old"); }
2189 id: 'i';
2190 new_args: 'n';
2191 old_args: 'o';
2193 ]AT_YYERROR_DEFINE[
2194 ]AT_YYPARSE_DEFINE[
2196 ]AT_YYLEX_PROTOTYPE[
2198   ]AT_USE_LEX_ARGS[
2199   return *input++;
2203 main (int argc, const char* argv[])
2205   assert (argc == 2); (void) argc;
2206   // First char decides whether new, or old syntax.
2207   // Then the input.
2208   new_syntax = argv[1][0] == 'N';
2209   input = argv[1] + 1;
2210   if (getenv ("YYDEBUG"))
2211     yydebug = 1;
2212   return yyparse ();
2216 AT_FULL_COMPILE([input])
2217 AT_PARSER_CHECK([[input Nwin]], [0], [new])
2218 AT_PARSER_CHECK([[input Owin]], [1], [], [[syntax error, unexpected 'n', expecting 'o'
2220 AT_PARSER_CHECK([[input Owio]], [0], [old])
2221 AT_PARSER_CHECK([[input Nwio]], [1], [], [[syntax error, unexpected 'o', expecting 'n'
2224 AT_BISON_OPTION_POPDEFS
2225 AT_CLEANUP
2228 AT_TEST([%skeleton "glr.c"])
2229 AT_TEST([%skeleton "glr.cc"])
2230 AT_TEST([%skeleton "glr2.cc"])
2232 m4_popdef([AT_TEST])
2235 m4_popdef([AT_YYPARSE_DEFINE])