1 # Checking GLR Parsing: Regression Tests -*- Autotest -*-
3 # Copyright (C) 2002-2003, 2005-2007, 2009-2015, 2018-2021 Free Software
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <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"
27 # Wrap the C++ parser in a C-like function interface.
28 m4_pushdef([AT_YYPARSE_DEFINE],
33 ]AT_NAMESPACE[::]AT_PARSER_CLASS[ p;]AT_DEBUG_IF([[
34 int debug = !!getenv ("YYDEBUG");
35 p.set_debug_level (debug);]])[
41 # AT_PRINT_LOOKAHEAD_DECLARE
42 # --------------------------
43 m4_define([AT_PRINT_LOOKAHEAD_DECLARE],
46 print_lookahead (yy::parser::symbol_type yylookahead, char const *reduction);
47 #define PRINT_LOOKAHEAD(Msg) \
48 print_lookahead (yyla, Msg)
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)
57 # AT_PRINT_LOOKAHEAD_DEFINE
58 # -------------------------
59 m4_define([AT_PRINT_LOOKAHEAD_DEFINE],
62 print_lookahead (yy::parser::symbol_type yylookahead, char const *reduction)
65 print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
66 char const *reduction)
70 // We use -2 and 0 to avoid this warning:
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 // | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81 int yytoken = yylookahead.kind ();
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'
89 printf ("%s:\n yychar=", reduction);
90 if (yychr == ]AT_TOKEN([YYEMPTY])[)
92 else if (yychr == ]AT_TOKEN([YYEOF])[)
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[);]])[
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}
132 static ]AT_YYSTYPE[ exprMerge (]AT_YYSTYPE[ x0, ]AT_YYSTYPE[ x1);
143 /* -------- productions ------ */
146 StartSymbol: E { $$=0; } %merge <exprMerge>
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)
169 const char *input = YY_NULLPTR;
178 main (int argc, const char* argv[])
180 assert (argc == 2); (void) argc;
182 if (getenv ("YYDEBUG"))
188 AT_FULL_COMPILE([glr-regr1])
189 AT_PARSER_CHECK([[glr-regr1 BPBPB]], 0,
201 AT_BISON_OPTION_POPDEFS
205 AT_TEST([%skeleton "glr.c"])
206 AT_TEST([%skeleton "glr.cc"])
207 AT_TEST([%skeleton "glr2.cc"])
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 *}
247 { printf ("Variable: '%s'\n", $][2); }
250 | 's' var_list 't' 'e'
251 { printf ("Varlist: '%s'\n", $][2); free ($][2); }
252 | 's' var 't' var_printer 'x'
266 char *s = YY_CAST (char *, realloc ($][1, strlen ($][1) + 1 + strlen ($][3) + 1));
275 { printf ("Variable: '%s'\n", $-1); }
285 assert (!feof (stdin));
286 switch (fscanf (input, " %1[a-z,]", buf))
293 if (fscanf (input, "%49s", buf) != 1)
297 assert (strlen (buf) < sizeof buf - 1);
298 char *s = YY_CAST (char *, malloc (strlen (buf) + 1));
310 main (int argc, char **argv)
314 if (argc == 2 && !(input = fopen (argv[1], "r")))
316 if (getenv ("YYDEBUG"))
319 if (argc == 2 && fclose (input))
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],
345 AT_PARSER_CHECK([[glr-regr2a input3.txt]], 0,
346 [[Variable: 'VARIABLE_3'
349 AT_BISON_OPTION_POPDEFS
353 AT_TEST([%skeleton "glr.c"])
354 AT_TEST([%skeleton "glr.cc"])
355 AT_TEST([%skeleton "glr2.cc"])
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 */
378 static int MergeRule (int x0, int x1);
382 #define RULE(x) (1 << (x))
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>
427 MergeRule (int x0, int x1)
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])[ };
443 assert (!feof (stdin));
444 if (fscanf (input, "%2s", inp) == EOF)
448 case 'p': return P[inp[1] - '1'];
449 case 't': return T[inp[1] - '1'];
450 case 'o': return O[inp[1] - '1'];
452 return ]AT_TOKEN([BAD_CHAR])[;
458 main (int argc, char* argv[])
462 if (argc == 2 && !(input = fopen (argv[1], "r")))
464 if (getenv ("YYDEBUG"))
467 if (argc == 2 && fclose (input))
473 AT_FULL_COMPILE([glr-regr3],,,,[-rall])
476 [[p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2
478 AT_PARSER_CHECK([[glr-regr3 input.txt]],
483 AT_BISON_OPTION_POPDEFS
487 AT_TEST([%skeleton "glr.c"])
488 AT_TEST([%skeleton "glr.cc"])
489 AT_TEST([%skeleton "glr2.cc"])
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],
509 %type <]AT_VALUE_UNION_IF([char*], [ptr])[> S A A1 A2 B
516 static char *merge (]AT_YYSTYPE[, ]AT_YYSTYPE[);
517 static char *make_value (char const *, char const *);
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); }
532 A : A1 %merge<merge> { $$ = make_value ("A", $][1); }
533 | A2 %merge<merge> { $$ = make_value ("A", $][1); }
536 A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
537 A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
538 B: 'a' { $$ = make_value ("B", "'a'"); } ;
543 ]AT_YYLEX_DEFINE(["a"])[
549 if (getenv ("YYDEBUG"))
552 while (ptrs_next != ptrs)
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);
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);]])[
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' }
587 AT_BISON_OPTION_POPDEFS
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"])
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],
616 enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
626 %union { int value; }
630 if ($$ != MAGIC_VALUE)
632 fprintf (stderr, "Bad destructor call.\n");
640 'a' { $$ = MAGIC_VALUE; }
641 | 'a' { $$ = MAGIC_VALUE; }
646 ]AT_YYLEX_DEFINE(["a"])[
650 AT_FULL_COMPILE([glr-regr5],,,, [-rall])
652 AT_PARSER_CHECK([[glr-regr5]], 1, [],
655 start -> <Rule 1, tokens 1 .. 1>
659 start -> <Rule 2, tokens 1 .. 1>
665 AT_BISON_OPTION_POPDEFS
669 AT_TEST([%skeleton "glr.c"])
670 AT_TEST([%skeleton "glr.cc"])
671 AT_TEST([%skeleton "glr2.cc"])
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],
699 %union { int value; }
703 printf ("Destructor called.\n");
712 ]AT_YYLEX_DEFINE(["a"])[
716 AT_FULL_COMPILE([glr-regr6],,,, [-rall])
718 AT_PARSER_CHECK([[glr-regr6]], 1,
723 start -> <Rule 1, tokens 1 .. 1>
727 start -> <Rule 2, tokens 1 .. 1>
733 AT_BISON_OPTION_POPDEFS
737 AT_TEST([%skeleton "glr.c"])
738 AT_TEST([%skeleton "glr.cc"])
739 AT_TEST([%skeleton "glr2.cc"])
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],
758 typedef struct count_node {
760 struct count_node *prev;
767 #define YYSTACKEXPANDABLE 0
768 static count_node *tail;
777 %union { count_node *node; }
782 fprintf (stderr, "Destructor called on same value twice.\n");
800 ]AT_VAL[.node = YY_CAST (count_node*, malloc (sizeof *]AT_VAL[.node));
803 fprintf (stderr, "Test inconclusive.\n");
806 ]AT_VAL[.node->count = 0;
807 ]AT_VAL[.node->prev = tail;
808 tail = ]AT_VAL[.node;
819 if (getenv ("YYDEBUG"))
824 count_node *prev = tail->prev;
832 AT_FULL_COMPILE([glr-regr7],,,, [-rall])
834 AT_PARSER_CHECK([[glr-regr7]], 2, [],
838 AT_BISON_OPTION_POPDEFS
842 AT_TEST([%skeleton "glr.c"])
843 AT_TEST([%skeleton "glr.cc"])
844 AT_TEST([%skeleton "glr2.cc"])
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],
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[); }
889 InterfaceDeclaration : OptConstantWord %dprec 1
890 | OptSignalWord %dprec 2
893 OptConstantWord : %empty
897 OptSignalWord : %empty
898 { printf("empty: %d/%d\n", @$.]AT_FIRST_COLUMN[, @$.]AT_LAST_COLUMN[); }
916 ]AT_LOC_FIRST_COLUMN[ = 1;
917 ]AT_LOC_LAST_COLUMN[ = 9;
918 return ]AT_TOKEN([T_PORT])[;
920 ]AT_LOC_FIRST_COLUMN[ = 13;
921 ]AT_LOC_LAST_COLUMN[ = 17;
922 return ]AT_TOKEN([T])[_PORT;
931 AT_FULL_COMPILE([glr-regr8],,,, [-rall])
933 AT_PARSER_CHECK([[glr-regr8]], 0,
939 AT_BISON_OPTION_POPDEFS
943 AT_TEST([%skeleton "glr.c"])
944 AT_TEST([%skeleton "glr.cc"])
945 AT_TEST([%skeleton "glr2.cc"])
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],
965 # define YYSTACKEXPANDABLE 0
966 static int tokens = 0;
967 static int destructors = 0;
977 %union { int dummy; }
987 ambig0 'a' { destructors += 2; USE ($][2); }
988 | ambig1 start { destructors += 1; }
989 | ambig2 start { destructors += 1; }
1012 if (getenv ("YYDEBUG"))
1014 status = yyparse ();
1015 if (tokens != destructors)
1017 fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
1024 AT_FULL_COMPILE([glr-regr9],,,, [-rall])
1026 # Exit 2: memory exhausted.
1027 AT_PARSER_CHECK([[glr-regr9]], 2, [],
1031 AT_BISON_OPTION_POPDEFS
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],
1054 ]AT_YYERROR_DECLARE[
1056 #define GARBAGE_SIZE 50
1057 static char garbage[GARBAGE_SIZE];
1060 %define parse.assert
1066 %union { char *ptr; }
1072 %dprec 2 { $$ = garbage; YYACCEPT; }
1073 | %dprec 1 { $$ = garbage; YYACCEPT; }
1085 for (i = 0; i < GARBAGE_SIZE; i+=1)
1087 if (getenv ("YYDEBUG"))
1093 AT_FULL_COMPILE([glr-regr10],,,, [-rall])
1095 AT_PARSER_CHECK([[glr-regr10]], 0, [], [])
1097 AT_BISON_OPTION_POPDEFS
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],
1120 ]AT_YYERROR_DECLARE[
1122 static int destructors = 0;
1126 %define parse.assert
1132 %union { int dummy; }
1134 %destructor { destructors += 1; } 'a'
1139 'a' %dprec 2 { USE ($][1); destructors += 1; YYACCEPT; }
1140 | 'a' %dprec 1 { USE ($][1); destructors += 1; YYACCEPT; }
1147 ]AT_YYLEX_DEFINE(["a"])[
1153 if (getenv ("YYDEBUG"))
1155 status = yyparse ();
1156 if (destructors != 1)
1158 fprintf (stderr, "Destructor calls: %d\n", destructors);
1165 AT_FULL_COMPILE([glr-regr11],,,, [-rall])
1167 AT_PARSER_CHECK([[glr-regr11]], 0, [], [])
1169 AT_BISON_OPTION_POPDEFS
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
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
1207 # include <assert.h>
1208 static int merge (]AT_YYSTYPE[, ]AT_YYSTYPE[);
1209 ]AT_YYERROR_DECLARE[
1211 static int parent_rhs_before_value = 0;
1212 static int merged_value = 0;
1213 static int parent_rhs_after_value = 0;
1227 parent_rhs_after_value = 0;
1232 parent_rhs_before merged PARENT_RHS_AFTER {
1233 USE (($][1, $][2, $][3));
1234 parent_rhs_before_value = 0;
1236 parent_rhs_after_value = 0;
1243 parent_rhs_before_value = 1;
1252 | cut %merge<merge> {
1258 cut: { YYACCEPT; } ;
1263 merge (]AT_YYSTYPE[ s1, ]AT_YYSTYPE[ s2)
1266 return s1.dummy + s2.dummy;
1271 ]AT_YYLEX_DEFINE([{ ]AT_TOKEN([PARENT_RHS_AFTER])[, 0 }],
1272 [if (res == ]AT_TOKEN([PARENT_RHS_AFTER])[)
1273 parent_rhs_after_value = 1;])[
1279 if (getenv ("YYDEBUG"))
1281 status = yyparse ();
1282 if (parent_rhs_before_value)
1284 fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1289 fprintf (stderr, "'merged' destructor not called.\n");
1292 if (parent_rhs_after_value)
1294 fprintf (stderr, "'PARENT_RHS_AFTER' destructor not called.\n");
1301 AT_FULL_COMPILE([glr-regr12],,,, [-rall])
1303 AT_PARSER_CHECK([[glr-regr12]], 0, [], [])
1305 AT_BISON_OPTION_POPDEFS
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],
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. */
1338 ]AT_YYERROR_DECLARE[
1340 ]AT_PRINT_LOOKAHEAD_DECLARE[
1344 %define parse.assert
1350 %union { char value; }
1351 %type <value> 'a' 'b'
1356 defstate_init defstate_shift 'b' change_lookahead 'a'
1359 PRINT_LOOKAHEAD ("start <- defstate_init defstate_shift 'b'");
1366 PRINT_LOOKAHEAD ("defstate_init <- empty string");
1371 nondefstate defstate_look 'a'
1374 PRINT_LOOKAHEAD ("defstate_shift <- nondefstate defstate_look 'a'");
1381 PRINT_LOOKAHEAD ("defstate_look <- empty string");
1388 PRINT_LOOKAHEAD ("nondefstate <- empty string");
1393 PRINT_LOOKAHEAD ("nondefstate <- 'b'");
1400 ]AT_GLR2_CC_IF([[yytoken = yy::parser::yytranslate_ ('a')]], [[yychar = 'a']])[;
1408 ]AT_PRINT_LOOKAHEAD_DEFINE[
1409 ]AT_YYLEX_DEFINE(["ab"],
1410 []AT_VAL[.value = YY_CAST (char, res + 'A' - 'a')])[
1416 yychar = '#'; /* Not a token in the grammar. */
1419 if (getenv ("YYDEBUG"))
1425 AT_FULL_COMPILE([glr-regr13],,,, [-rall])
1427 AT_PARSER_CHECK([[glr-regr13]], 0,
1428 [defstate_init <- empty string:
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':
1436 start <- defstate_init defstate_shift 'b':
1440 AT_BISON_OPTION_POPDEFS
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],
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
1480 - If only defaulted states are entered, there are no conflicts, so
1481 nondeterministic operation does not start. */
1483 %define parse.assert
1485 %type <value> 'a' 'b' 'c' 'd' stack_explosion
1492 %union { char value; }
1496 ]AT_YYERROR_DECLARE[
1498 ]AT_PRINT_LOOKAHEAD_DECLARE[
1499 static char merge (]AT_YYSTYPE[, ]AT_YYSTYPE[);
1506 merge 'c' stack_explosion
1508 USE ($][2); USE ($][3);
1509 PRINT_LOOKAHEAD ("start <- merge 'c' stack_explosion");
1513 /* When merging the 2 deferred actions, the lookahead needs are different. */
1515 nonconflict1 'a' 'b' nonconflict2 %dprec 1
1517 USE ($][2); USE ($][3);
1518 PRINT_LOOKAHEAD ("merge <- nonconflict1 'a' 'b' nonconflict2");
1520 | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2
1522 USE ($][3); USE ($][5);
1523 PRINT_LOOKAHEAD ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
1531 PRINT_LOOKAHEAD ("nonconflict1 <- empty string");
1538 PRINT_LOOKAHEAD ("nonconflict2 <- empty string");
1543 PRINT_LOOKAHEAD ("nonconflict2 <- 'a'");
1550 PRINT_LOOKAHEAD ("conflict <- empty string");
1557 PRINT_LOOKAHEAD ("defstate_look <- empty string");
1561 /* yychar != YYEMPTY but lookahead need is yyfalse. */
1565 PRINT_LOOKAHEAD ("defstate_shift <- empty string");
1570 %empty { $$ = '\0'; }
1571 | alt1 stack_explosion %merge<merge> { $$ = $][2; }
1572 | alt2 stack_explosion %merge<merge> { $$ = $][2; }
1573 | alt3 stack_explosion %merge<merge> { $$ = $][2; }
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.");
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.");
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.");
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.");
1623 ]AT_PRINT_LOOKAHEAD_DEFINE[
1625 ]AT_YYLEX_PROTOTYPE[
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++];
1638 merge (]AT_YYSTYPE[ s1, ]AT_YYSTYPE[ s2)
1640 return YY_CAST (char, s1.value + s2.value);
1647 yychar = '#'; /* Not a token in the grammar. */
1650 if (getenv ("YYDEBUG"))
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:
1667 merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift:
1669 start <- merge 'c' stack_explosion:
1673 AT_BISON_OPTION_POPDEFS
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
1703 %destructor { parent_rhs_before_value = 0; } parent_rhs_before
1706 ]AT_YYERROR_DECLARE[
1708 static int parent_rhs_before_value = 0;
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. */
1727 parent_rhs_before ambiguity {
1729 parent_rhs_before_value = 0;
1736 parent_rhs_before_value = 1;
1740 ambiguity: ambiguity1 | ambiguity2 ;
1753 if (getenv ("YYDEBUG"))
1755 status = yyparse () != 1;
1756 if (parent_rhs_before_value)
1758 fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
1765 AT_FULL_COMPILE([glr-regr15],,,, [-rall])
1767 AT_PARSER_CHECK([[glr-regr15]], 0, [],
1768 [Ambiguity detected.
1770 ambiguity -> <Rule 6, empty>
1771 ambiguity1 -> <Rule 8, empty>
1774 ambiguity -> <Rule 7, empty>
1775 ambiguity2 -> <Rule 9, empty>
1780 AT_BISON_OPTION_POPDEFS
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
1809 %destructor { lookahead_value = 0; } 'b'
1812 # include <assert.h>
1813 ]AT_YYERROR_DECLARE[
1815 static int lookahead_value = 0;
1821 start: alt1 'a' | alt2 'a' ;
1829 ]AT_YYLEX_DEFINE(["ab"],
1831 lookahead_value = 1])[
1837 if (getenv ("YYDEBUG"))
1839 status = yyparse () != 1;
1840 if (lookahead_value)
1842 fprintf (stderr, "Lookahead destructor not called.\n");
1849 AT_FULL_COMPILE([glr-regr16],,,, [-rall])
1851 AT_PARSER_CHECK([[glr-regr16]], 0, [],
1855 AT_BISON_OPTION_POPDEFS
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
1885 %define parse.error verbose
1887 %union { int dummy; }
1890 ]AT_YYERROR_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' ;
1914 # include <assert.h>
1918 ]AT_YYLEX_PROTOTYPE[
1920 static char const input[] = "ab";
1921 static int toknum = 0;
1923 assert (toknum < YY_CAST (int, sizeof input));
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++];
1934 AT_FULL_COMPILE([glr-regr17],,,, [-rall])
1936 AT_PARSER_CHECK([[glr-regr17]], 1, [],
1937 [Ambiguity detected.
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>
1945 empty1 -> <Rule 9, empty>
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>
1954 empty2 -> <Rule 10, empty>
1956 1.1-2.2: syntax is ambiguous
1959 AT_BISON_OPTION_POPDEFS
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
1987 ]AT_YYERROR_DECLARE[
1997 // In C++ we need one more line for the line numbers to match.
2001 sym1: sym2 %merge<merge> { $$ = $][1; } ;
2002 sym2: sym3 %merge<merge> { $$ = $][1; } ;
2003 sym3: %merge<merge> { $$ = 0; } ;
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; } ;
2019 glr-regr18.y:29.18-24: note: previous declaration
2020 29 | sym1: sym2 %merge<merge> { $$ = $][1; } ;
2022 glr-regr18.y:31.13-19: error: result type clash on merge function 'merge': <type3> != <type1>
2023 31 | sym3: %merge<merge> { $$ = 0; } ;
2025 glr-regr18.y:29.18-24: note: previous declaration
2026 29 | sym1: sym2 %merge<merge> { $$ = $][1; } ;
2030 AT_BISON_OPTION_POPDEFS
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],
2052 ]AT_YYERROR_DECLARE[
2056 %define parse.assert
2064 // In C++ we need two more lines for the line numbers in the trace to match.
2076 ]AT_YYLEX_DEFINE(["abc"])[
2080 AT_FULL_COMPILE([input])
2082 AT_PARSER_CHECK([[input --debug]], 1, [],
2086 Next token is token 'a' ()
2087 Shifting token 'a' ()
2090 Next token is token 'b' ()
2091 Shifting token 'b' ()
2093 Reducing stack 0 by rule 3 (line 30):
2095 -> $][$ = nterm b ()
2098 Next token is token 'c' ()
2099 Shifting token 'c' ()
2101 Reducing stack 0 by rule 4 (line 31):
2102 -> $][$ = nterm d ()
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
2122 start -> <Rule 1, tokens 1 .. 3>
2129 start -> <Rule 2, tokens 1 .. 3>
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
2148 AT_TEST([%skeleton "glr.c"])
2149 AT_TEST([%skeleton "glr.cc"])
2150 AT_TEST([%skeleton "glr2.cc"])
2152 m4_popdef([AT_TEST])
2156 ## ------------------------------------------------------- ##
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
2171 %define parse.error verbose
2178 #include <stdbool.h>
2179 bool new_syntax = false;
2180 const char *input = YY_NULLPTR;
2181 ]AT_YYERROR_DECLARE[
2186 %? {new_syntax} 'w' id new_args { printf("new"); }
2187 | %?{!new_syntax} 'w' id old_args { printf("old"); }
2196 ]AT_YYLEX_PROTOTYPE[
2203 main (int argc, const char* argv[])
2205 assert (argc == 2); (void) argc;
2206 // First char decides whether new, or old syntax.
2208 new_syntax = argv[1][0] == 'N';
2209 input = argv[1] + 1;
2210 if (getenv ("YYDEBUG"))
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
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])