scanner: don't crash on strings containing a NUL byte
[bison.git] / tests / actions.at
blobd90851de5f028d99d44c6aa60d5aac92b938c2fc
1 # Executing Actions.                               -*- Autotest -*-
3 # Copyright (C) 2001-2015, 2018-2020 Free Software Foundation, Inc.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 AT_BANNER([[User Actions.]])
20 ## ----------------- ##
21 ## Midrule actions.  ##
22 ## ----------------- ##
24 AT_SETUP([Midrule actions])
26 # Bison once forgot the midrule actions.  It was because the action
27 # was attached to the host rule (the one with the midrule action),
28 # instead of being attached to the empty rule dedicated to this
29 # action.
31 AT_BISON_OPTION_PUSHDEFS
32 AT_DATA_GRAMMAR([[input.y]],
33 [[%define parse.error verbose
34 %debug
35 %code {
36 ]AT_YYERROR_DECLARE[
37 ]AT_YYLEX_DECLARE[
40 exp:     { putchar ('0'); }
41      '1' { putchar ('1'); }
42      '2' { putchar ('2'); }
43      '3' { putchar ('3'); }
44      '4' { putchar ('4'); }
45      '5' { putchar ('5'); }
46      '6' { putchar ('6'); }
47      '7' { putchar ('7'); }
48      '8' { putchar ('8'); }
49      '9' { putchar ('9'); }
50          { putchar ('\n'); }
51    ;
53 ]AT_YYERROR_DEFINE[
54 ]AT_YYLEX_DEFINE(["123456789"])[
55 ]AT_MAIN_DEFINE[
56 ]])
57 AT_BISON_OPTION_POPDEFS
59 AT_BISON_CHECK([-d -v -o input.c input.y])
60 AT_COMPILE([input])
61 AT_PARSER_CHECK([input], 0,
62 [[0123456789
63 ]])
65 AT_CLEANUP
68 ## ----------------------- ##
69 ## Typed midrule actions.  ##
70 ## ----------------------- ##
72 AT_SETUP([Typed midrule actions])
74 AT_BISON_OPTION_PUSHDEFS
75 AT_DATA_GRAMMAR([[input.y]],
76 [[%define parse.error verbose
77 %debug
78 %code {
79 ]AT_YYERROR_DECLARE[
80 ]AT_YYLEX_DECLARE[
82 %union {
83   int ival;
85 %type <ival> exp
87 exp:     <ival>{ $$ = 0; }
88      '1' <ival>{ $$ = 1; }
89      '2' <ival>{ $$ = 2; }
90      '3' <ival>{ $$ = 3; }
91      '4' <ival>{ $$ = 4; }
92      '5' <ival>{ $$ = 5; }
93      '6' <ival>{ $$ = 6; }
94      '7' <ival>{ $$ = 7; }
95      '8' <ival>{ $$ = 8; }
96      '9' <ival>{ $$ = 9; }  <ival>{ $$ = 10; }  <ival>{ $$ = 11; }
97   {
98     $$ = $1 + $3 + $5 + $7 + $9 + $11 + $13 + $15 + $17 + $19 + $20 + $21;
99     printf ("%d\n", $$);
100   }
103 ]AT_YYERROR_DEFINE[
104 ]AT_YYLEX_DEFINE(["123456789"])[
105 ]AT_MAIN_DEFINE[
107 AT_BISON_OPTION_POPDEFS
109 AT_BISON_CHECK([-d -v -o input.c input.y])
110 AT_COMPILE([input])
111 AT_PARSER_CHECK([input], 0,
112 [[66
115 AT_CLEANUP
118 ## ----------------------- ##
119 ## Implicitly empty rule.  ##
120 ## ----------------------- ##
122 AT_SETUP([Implicitly empty rule])
124 AT_BISON_OPTION_PUSHDEFS
125 AT_DATA_GRAMMAR([[1.y]],
126 [[%%
127 exp: a b;
128 a: /* empty. */ {};
129 // A midrule action does not count as an empty rule.
130 b: {} {};
133 AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [],
134 [[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
135    11 | a: /* empty. */ {};
136       |                 ^~
137       |                 %empty
138 1.y: warning: fix-its can be applied.  Rerun with option '--update'. [-Wother]
141 AT_DATA_GRAMMAR([[2.y]],
142 [[%%
143 exp: a b c;
144 a: /* empty. */ {};
145 b: %empty       {};
146 c: /* empty. */ {};
149 AT_BISON_CHECK([-fcaret 2.y], [0], [],
150 [[2.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
151    11 | a: /* empty. */ {};
152       |                 ^~
153       |                 %empty
154 2.y:13.17-18: warning: empty rule without %empty [-Wempty-rule]
155    13 | c: /* empty. */ {};
156       |                 ^~
157       |                 %empty
158 2.y: warning: fix-its can be applied.  Rerun with option '--update'. [-Wother]
161 AT_BISON_CHECK([-fcaret -Wno-empty-rule 2.y], [0])
163 AT_BISON_OPTION_POPDEFS
164 AT_CLEANUP
168 ## ------------------------ ##
169 ## Invalid uses of %empty.  ##
170 ## ------------------------ ##
172 AT_SETUP([Invalid uses of %empty])
174 AT_BISON_OPTION_PUSHDEFS
175 AT_DATA_GRAMMAR([[one.y]],
176 [[%%
177 exp:
178   %empty {} %empty
182 AT_BISON_CHECK([-fcaret one.y], [1], [],
183 [[one.y:11.13-18: error: only one %empty allowed per rule
184    11 |   %empty {} %empty
185       |             ^~~~~~
186 one.y:11.3-8: note: previous declaration
187    11 |   %empty {} %empty
188       |   ^~~~~~
189 one.y: warning: fix-its can be applied.  Rerun with option '--update'. [-Wother]
192 AT_BISON_CHECK([-fcaret -u one.y], [1], [],
193 [[one.y:11.13-18: error: only one %empty allowed per rule
194    11 |   %empty {} %empty
195       |             ^~~~~~
196 one.y:11.3-8: note: previous declaration
197    11 |   %empty {} %empty
198       |   ^~~~~~
199 bison: file 'one.y' was updated (backup: 'one.y~')
202 AT_CHECK([sed -e '1,8d' one.y], [],
203 [[%%
204 exp:
205   %empty {} @&t@
210 AT_DATA_GRAMMAR([[two.y]],
211 [[%%
212 exp:
213   'a' %empty    {}
214 | %empty 'a'    {}
215 | %empty {}     {}
219 AT_BISON_CHECK([-fcaret two.y], [1], [],
220 [[two.y:11.7-12: error: %empty on non-empty rule
221    11 |   'a' %empty    {}
222       |       ^~~~~~
223 two.y:12.3-8: error: %empty on non-empty rule
224    12 | | %empty 'a'    {}
225       |   ^~~~~~
226 two.y:13.3-8: error: %empty on non-empty rule
227    13 | | %empty {}     {}
228       |   ^~~~~~
229 two.y: warning: fix-its can be applied.  Rerun with option '--update'. [-Wother]
232 AT_BISON_OPTION_POPDEFS
233 AT_CLEANUP
236 ## ---------------------- ##
237 ## Valid uses of %empty.  ##
238 ## ---------------------- ##
240 AT_SETUP([Valid uses of %empty])
242 AT_BISON_OPTION_PUSHDEFS
243 AT_DATA_GRAMMAR([[input.y]],
245 %debug
246 %code
248 ]AT_YYERROR_DECLARE[
249 ]AT_YYLEX_DECLARE[
252 exp: %empty {}
254 ]AT_YYERROR_DEFINE[
255 ]AT_YYLEX_DEFINE[
256 ]AT_MAIN_DEFINE[
259 AT_FULL_COMPILE([input])
260 AT_PARSER_CHECK([input])
261 AT_BISON_OPTION_POPDEFS
262 AT_CLEANUP
266 ## -------------------- ##
267 ## Add missing %empty.  ##
268 ## -------------------- ##
270 AT_SETUP([Add missing %empty])
272 AT_DATA([input.y],
273 [[%%
274 exp: a b c d e
275 a: {}
285 AT_BISON_CHECK([--update -Wall input.y], [], [], [ignore])
286 AT_CHECK([cat input.y], [],
287 [[%%
288 exp: a b c d e
289 a:  %empty {}
290 b: %empty {
292 c: %empty @&t@
294 : %empty @&t@
295 e: %empty @&t@
299 # No warnings.
300 AT_BISON_CHECK([-Wall input.y])
302 AT_CLEANUP
305 ## ------------------ ##
306 ## Initial location.  ##
307 ## ------------------ ##
309 # AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
310 # -----------------------------------------------------------------------
311 # Check that the initial location is correct.
312 m4_pushdef([AT_TEST],
313 [AT_SETUP([Initial location: $1 $2])
315 AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2])
316 AT_DATA_GRAMMAR([[input.y]],
317 [[%locations
318 %debug
319 %skeleton "$1"
320 ]$2[
321 ]$3[
322 %code
324 # include <stdio.h>
325 # include <stdlib.h> /* getenv */
326 ]AT_YYERROR_DECLARE[
327 ]AT_YYLEX_DECLARE[
330 exp: { ]AT_CXX_IF([[std::cerr << @$ << '\n']],
331                   [[LOCATION_PRINT(stderr, @$); fputc ('\n', stderr)]])[; }
333 ]AT_YYERROR_DEFINE[
335 ]AT_YYLEX_PROTOTYPE[
336 {]AT_PURE_IF([
337   YYUSE(lvalp);
338   YYUSE(llocp);], [AT_CXX_IF([
339   YYUSE(lvalp);
340   YYUSE(llocp);])])[
341   return 'x';
345 main (void)
346 {]AT_CXX_IF([[
347   yy::parser p;
348   p.set_debug_level (!!getenv ("YYDEBUG"));
349   return p.parse ();]], [[
350   yydebug = !!getenv ("YYDEBUG");
351   return !!yyparse (]AT_PARAM_IF([0])[);]])[
355 AT_FULL_COMPILE([input])
356 AT_PARSER_CHECK([input], 1, [],
357 [m4_default([$4], [1.1])
358 m4_default([$4], [1.1])[: syntax error
360 AT_BISON_OPTION_POPDEFS
361 AT_CLEANUP
364 ## FIXME: test Java, and iterate over skeletons.
365 AT_TEST([yacc.c])
366 AT_TEST([yacc.c], [%define api.pure full])
367 AT_TEST([yacc.c], [%define api.pure %parse-param { int x }])
368 AT_TEST([yacc.c], [%define api.push-pull both])
369 AT_TEST([yacc.c], [%define api.push-pull both %define api.pure full])
370 AT_TEST([glr.c])
371 AT_TEST([glr.c], [%define api.pure])
372 AT_TEST([lalr1.cc])
373 AT_TEST([glr.cc])
375 ## A very different test, based on PostgreSQL's implementation of the
376 ## locations.  See
377 ## http://lists.gnu.org/archive/html/bug-bison/2012-11/msg00023.html
379 ## Weirdly enough, to trigger the warning with GCC 4.7, we must not
380 ## use fprintf, so run the test twice: once to check the warning
381 ## (absence thereof), and another time to check the value.
382 AT_TEST([yacc.c], [%define api.pure full],
383 [[%{
384 # define YYLTYPE int
385 # define LOCATION_PRINT(Stream, Loc)      \
386    (void) (Loc)
387 # define YYLLOC_DEFAULT(Current, Rhs, N)    \
388   (Current) = ((Rhs)[N ? 1 : 0])
391 [@&t@])
393 AT_TEST([yacc.c], [%define api.pure full],
394 [[%{
395 # define YYLTYPE int
396 # define LOCATION_PRINT(Stream, Loc)      \
397     fprintf ((Stream), "%d", (Loc))
398 # define YYLLOC_DEFAULT(Current, Rhs, N)    \
399   (Current) = ((Rhs)[N ? 1 : 0])
402 [0])
405 m4_popdef([AT_TEST])
409 ## ---------------- ##
410 ## Location Print.  ##
411 ## ---------------- ##
413 # AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES])
414 # -----------------------------------------------------
415 # Check that the initial location is correct.
416 m4_pushdef([AT_TEST],
417 [AT_SETUP([Location print: $1 $2])
419 AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2])
420 AT_DATA_GRAMMAR([[input.y]],
421 [[%locations
422 %debug
423 %skeleton "$1"
424 ]$2[
425 ]$3[
426 %code
428 #include <stdio.h> /* putchar. */
429 ]AT_YYERROR_DECLARE[
430 ]AT_YYLEX_DECLARE[
433 exp: %empty;
435 ]AT_YYERROR_DEFINE[
436 ]AT_YYLEX_DEFINE[
439 main (void)
441   ]AT_YYLTYPE[ loc;
442 ]AT_GLR_CC_IF([loc.initialize();])[
443 #define TEST(L1, C1, L2, C2)          \
444   loc.]AT_FIRST_LINE[ = L1;           \
445   loc.]AT_FIRST_COLUMN[ = C1;         \
446   loc.]AT_LAST_LINE[ = L2;            \
447   loc.]AT_LAST_COLUMN[ = C2;          \
448   ]AT_CXX_IF([std::cout << loc],
449                  [LOCATION_PRINT(stdout, loc)])[;\
450   putchar ('\n');
452   TEST(1, 1, 1, 1);
453   TEST(2, 1, 2, 10);
454   TEST(3, 1, 4, 1);
455   TEST(5, 1, 6, 10);
457   TEST(7, 2, 0, 2);
458   TEST(8, 0, 8, 0);
459   return 0;
463 AT_FULL_COMPILE([input])
464 AT_PARSER_CHECK([input], 0,
465 [[1.1
466 2.1-9
467 3.1-4.0
468 5.1-6.9
472 AT_BISON_OPTION_POPDEFS
473 AT_CLEANUP
476 ## FIXME: test Java and D.
477 m4_map_args([AT_TEST], [yacc.c], [glr.c], [lalr1.cc], [glr.cc])
479 m4_popdef([AT_TEST])
483 ## ---------------- ##
484 ## Exotic Dollars.  ##
485 ## ---------------- ##
487 AT_SETUP([Exotic Dollars])
489 AT_BISON_OPTION_PUSHDEFS
490 AT_DATA_GRAMMAR([[input.y]],
491 [[%define parse.error verbose
492 %debug
493 %code {
494 ]AT_YYERROR_DECLARE[
495 ]AT_YYLEX_DECLARE[
496 # define USE(Var)
499 %union
501   int val;
504 %type <val> a_1 a_2 a_5
505             sum_of_the_five_previous_values
508 exp: a_1 a_2 { $<val>$ = 3; } { $<val>$ = $<val>3 + 1; } a_5
509      sum_of_the_five_previous_values
510     {
511        USE (($1, $2, $<foo>3, $<foo>4, $5));
512        printf ("%d\n", $6);
513     }
515 a_1: { $$ = 1; };
516 a_2: { $$ = 2; };
517 a_5: { $$ = 5; };
519 sum_of_the_five_previous_values:
520     {
521        $$ = $<val>0 + $<val>-1 + $<val>-2 + $<val>-3 + $<val>-4;
522     }
526 ]AT_YYERROR_DEFINE[
527 ]AT_YYLEX_DEFINE[
528 ]AT_MAIN_DEFINE[
531 AT_BISON_CHECK([-d -v -o input.c input.y], 0)
532 AT_COMPILE([input])
533 AT_PARSER_CHECK([input], 0,
534 [[15
537 # Make sure that fields after $n or $-n are parsed correctly.  At one
538 # point while implementing dashes in symbol names, we were dropping
539 # fields after $-n.
540 AT_DATA_GRAMMAR([[input.y]],
543 ]AT_YYERROR_DECLARE[
544 ]AT_YYLEX_DECLARE[
545   typedef struct { int val; } stype;
546 # define YYSTYPE stype
550 start: one two { $$.val = $1.val + $2.val; } sum ;
551 one: { $$.val = 1; } ;
552 two: { $$.val = 2; } ;
553 sum: { printf ("%d\n", $0.val + $-1.val + $-2.val); } ;
556 ]AT_YYERROR_DEFINE[
557 ]AT_YYLEX_DEFINE[
558 ]AT_MAIN_DEFINE[
561 AT_FULL_COMPILE([input])
562 AT_PARSER_CHECK([[input]], [[0]],
566 AT_BISON_OPTION_POPDEFS
567 AT_CLEANUP
571 ## -------------------------- ##
572 ## Printers and Destructors.  ##
573 ## -------------------------- ##
575 # _AT_CHECK_PRINTER_AND_DESTRUCTOR($1, $2, $3, $4,
576 #                                  BISON-DIRECTIVE, UNION-FLAG)
577 # -------------------------------------------------------------
578 m4_define([_AT_CHECK_PRINTER_AND_DESTRUCTOR],
579 [# Make sure complex $n work.
580 m4_if([$1$2$3$4], $[1]$[2]$[3]$[4], [],
581        [m4_fatal([$0: Invalid arguments: $@])])dnl
583 # Be sure to pass all the %directives to this macro to have correct
584 # helping macros.  So don't put any directly in the Bison file.
585 AT_BISON_OPTION_PUSHDEFS([$5])
586 AT_DATA_GRAMMAR([[input.y]],
587 [[%code requires {
588 #include <stdio.h>
589 #include <stdlib.h>
590 #include <string.h>
591 #include <assert.h>
593 #define YYINITDEPTH 10
594 #define YYMAXDEPTH 10
595 #define RANGE(Location) ]AT_CXX_IF([(Location).begin.line, (Location).end.line],
596       [(Location).first_line, (Location).last_line])[
598 #define USE(SYM)
600 /* Display the symbol type Symbol.  */
601 #define V(Symbol, Value, Location, Sep) \
602    fprintf (stderr, #Symbol " (%d@%d-%d)%s", Value, RANGE(Location), Sep)
606 ]m4_ifval([$6], [%union
608   int ival;
610 m4_ifval([$6], [[%code provides {]], [[%code {]])
611 AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
612 ]AT_YYLEX_DECLARE[
613 ]AT_LALR1_CC_IF([], [AT_YYERROR_DECLARE])
616 ]m4_ifval([$6],
617 [%type <ival> '(' 'x' 'y' ')' ';' thing line input
618               '!' raise check-spontaneous-errors END])[
620 /* FIXME: This %printer isn't actually tested.  */
621 %printer
622   {
623     ]AT_CXX_IF([yyo << $$;],
624                [fprintf (yyo, "%d", $$)])[;
625   }
626   '(' 'x' 'y' ')' ';' thing line input '!' raise check-spontaneous-errors END
628 %destructor
629   { fprintf (stderr, "Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); }
630   input
632 %destructor
633   { fprintf (stderr, "Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); }
634   line
636 %destructor
637   { fprintf (stderr, "Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); }
638   thing
640 %destructor
641   { fprintf (stderr, "Freeing nterm raise (%d@%d-%d)\n", $$, RANGE (@$)); }
642   raise
644 %destructor
645   { fprintf (stderr, "Freeing nterm check-spontaneous-errors (%d@%d-%d)\n", $$, RANGE (@$)); }
646   check-spontaneous-errors
648 %destructor
649   { fprintf (stderr, "Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); }
650   'x'
652 %destructor
653   { fprintf (stderr, "Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); }
654   'y'
656 %token END 0
657 %destructor
658   { fprintf (stderr, "Freeing token END (%d@%d-%d)\n", $$, RANGE (@$)); }
659   END
663    This grammar is made to exercise error recovery.
664    "Lines" starting with '(' support error recovery, with
665    ')' as synchronizing token.  Lines starting with 'x' can never
666    be recovered from if in error.
669 input:
670   %empty
671     {
672       $$ = 0;
673       V(input, $$, @$, ": /* Nothing */\n");
674     }
675 | line input /* Right recursive to load the stack so that popping at
676                 END can be exercised.  */
677     {
678       $$ = 2;
679       V(input, $$, @$, ": ");
680       V(line,  $1, @1, " ");
681       V(input, $2, @2, "\n");
682     }
683 | '!' check-spontaneous-errors
684   {
685     $$ = $2;
686   }
689 check-spontaneous-errors:
690   raise         { abort(); USE(($$, $1)); }
691 | '(' raise ')' { abort(); USE(($$, $2)); }
692 | error
693   {
694     $$ = 5;
695     V(check-spontaneous-errors, $$, @$, ": ");
696     fprintf (stderr, "error (@%d-%d)\n", RANGE(@1));
697   }
700 raise:
701   %empty
702   {
703     $$ = 4;
704     V(raise, $$, @$, ": %empty\n");
705     YYERROR;
706   }
707 | '!' '!'
708   {
709     $$ = 5;
710     V(raise, $$, @$, ": ");
711     V(!, $1, @2, " ");
712     V(!, $2, @2, "\n");
713     YYERROR;
714   }
717 line:
718   thing thing thing ';'
719     {
720       $$ = $1;
721       V(line,  $$, @$, ": ");
722       V(thing, $1, @1, " ");
723       V(thing, $2, @2, " ");
724       V(thing, $3, @3, " ");
725       V(;,     $4, @4, "\n");
726     }
727 | '(' thing thing ')'
728     {
729       $$ = $1;
730       V(line,  $$, @$, ": ");
731       V('(',   $1, @1, " ");
732       V(thing, $2, @2, " ");
733       V(thing, $3, @3, " ");
734       V(')',   $4, @4, "\n");
735     }
736 | '(' thing ')'
737     {
738       $$ = $1;
739       V(line,  $$, @$, ": ");
740       V('(',   $1, @1, " ");
741       V(thing, $2, @2, " ");
742       V(')',   $3, @3, "\n");
743     }
744 | '(' error ')'
745     {
746       $$ = -1;
747       V(line,  $$, @$, ": ");
748       V('(',   $1, @1, " ");
749       fprintf (stderr, "error (@%d-%d) ", RANGE(@2));
750       V(')',   $3, @3, "\n");
751     }
754 thing:
755   'x'
756     {
757       $$ = $1;
758       V(thing, $$, @$, ": ");
759       V('x',   $1, @1, "\n");
760     }
763 /* Alias to ARGV[1]. */
764 const char *source = YY_NULLPTR;
766 ]AT_YYERROR_DEFINE[
768 static
769 ]AT_YYLEX_PROTOTYPE[
771   static int counter = 0;
773   int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
774   assert (c <= YY_CAST (int, strlen (source)));
775   /* As in BASIC, line numbers go from 10 to 10.  */
776   ]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = (10 * c);
777   ]AT_LOC_LAST_LINE[ = ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_LINE[ + 9;
778   if (source[c])
779     fprintf (stderr, "sending: '%c'", source[c]);
780   else
781     fprintf (stderr, "sending: END");
782   fprintf (stderr, " (%d@%d-%d)\n", c, RANGE (]AT_LOC[));
783   return source[c];
785 ]AT_LALR1_CC_IF([static bool yydebug;])[
786 ]AT_CXX_IF([int
787 yyparse ()
789   yy::parser parser;
790   parser.set_debug_level (yydebug);
791   return parser.parse ();
796 main (int argc, const char *argv[])
798   int status;
799   yydebug = !!getenv ("YYDEBUG");
800   assert (argc == 2); (void) argc;
801   source = argv[1];
802   status = yyparse ();
803   switch (status)
804     {
805       case 0: fprintf (stderr, "Successful parse.\n"); break;
806       case 1: fprintf (stderr, "Parsing FAILED.\n"); break;
807       default: fprintf (stderr, "Parsing FAILED (status %d).\n", status); break;
808     }
809   return status;
813 AT_FULL_COMPILE([input])
816 # Check the location of "empty"
817 # -----------------------------
818 # I.e., epsilon-reductions, as in "(x)" which ends by reducing
819 # an empty "line" nterm.
820 # FIXME: This location is not satisfying.  Depend on the lookahead?
821 AT_PARSER_CHECK([input '(x)'], 0, [],
822 [[sending: '(' (0@0-9)
823 sending: 'x' (1@10-19)
824 thing (1@10-19): 'x' (1@10-19)
825 sending: ')' (2@20-29)
826 line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
827 sending: END (3@30-39)
828 input (0@29-29): /* Nothing */
829 input (2@0-29): line (0@0-29) input (0@29-29)
830 Freeing token END (3@30-39)
831 Freeing nterm input (2@0-29)
832 Successful parse.
835 # Check the location of empty reductions raising an error
836 # -------------------------------------------------------
837 # Here, the error is after token "!@0-9", so the error is raised from
838 # @9-9, and the error recovery detects that it starts from @9-9 and
839 # ends where starts the next token: END@10-19.
841 # So error recovery reports error@9-19.
842 AT_PARSER_CHECK([input '!'], 0, [],
843 [[sending: '!' (0@0-9)
844 sending: END (1@10-19)
845 raise (4@9-9): %empty
846 check-spontaneous-errors (5@9-19): error (@9-19)
847 Freeing token END (1@10-19)
848 Freeing nterm input (5@0-19)
849 Successful parse.
852 # Check the location of not empty reductions raising an error
853 # -----------------------------------------------------------
854 # This time the error is raised from a rule with 2 rhs symbols: @10-29.
855 # It is recovered @10-29.
856 AT_PARSER_CHECK([[input '!!!']], 0, [],
857 [[sending: '!' (0@0-9)
858 sending: '!' (1@10-19)
859 sending: '!' (2@20-29)
860 raise (5@10-29): ! (1@20-29) ! (2@20-29)
861 check-spontaneous-errors (5@10-29): error (@10-29)
862 sending: END (3@30-39)
863 Freeing token END (3@30-39)
864 Freeing nterm input (5@0-29)
865 Successful parse.
868 # Check locations in error recovery
869 # ---------------------------------
870 # '(y)' is an error, but can be recovered from.  But what's the location
871 # of the error itself ('y'), and of the resulting reduction ('(error)').
872 AT_PARSER_CHECK([input '(y)'], 0, [],
873 [[sending: '(' (0@0-9)
874 sending: 'y' (1@10-19)
875 10.10-19.18: syntax error, unexpected 'y', expecting 'x'
876 Freeing token 'y' (1@10-19)
877 sending: ')' (2@20-29)
878 line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29)
879 sending: END (3@30-39)
880 input (0@29-29): /* Nothing */
881 input (2@0-29): line (-1@0-29) input (0@29-29)
882 Freeing token END (3@30-39)
883 Freeing nterm input (2@0-29)
884 Successful parse.
888 # Syntax errors caught by the parser
889 # ----------------------------------
890 # Exercise the discarding of stack top and input until 'error'
891 # can be reduced.
893 #     '(', 'x', 'x', 'x', 'x', 'x', ')',
895 # Load the stack and provoke an error that cannot be caught by the
896 # grammar, to check that the stack is cleared.  And make sure the
897 # lookahead is freed.
899 #     '(', 'x', ')',
900 #     '(', 'x', ')',
901 #     'y'
902 AT_PARSER_CHECK([input '(xxxxx)(x)(x)y'], 1, [],
903 [[sending: '(' (0@0-9)
904 sending: 'x' (1@10-19)
905 thing (1@10-19): 'x' (1@10-19)
906 sending: 'x' (2@20-29)
907 thing (2@20-29): 'x' (2@20-29)
908 sending: 'x' (3@30-39)
909 30.30-39.38: syntax error, unexpected 'x', expecting ')'
910 Freeing nterm thing (2@20-29)
911 Freeing nterm thing (1@10-19)
912 Freeing token 'x' (3@30-39)
913 sending: 'x' (4@40-49)
914 Freeing token 'x' (4@40-49)
915 sending: 'x' (5@50-59)
916 Freeing token 'x' (5@50-59)
917 sending: ')' (6@60-69)
918 line (-1@0-69): '(' (0@0-9) error (@10-59) ')' (6@60-69)
919 sending: '(' (7@70-79)
920 sending: 'x' (8@80-89)
921 thing (8@80-89): 'x' (8@80-89)
922 sending: ')' (9@90-99)
923 line (7@70-99): '(' (7@70-79) thing (8@80-89) ')' (9@90-99)
924 sending: '(' (10@100-109)
925 sending: 'x' (11@110-119)
926 thing (11@110-119): 'x' (11@110-119)
927 sending: ')' (12@120-129)
928 line (10@100-129): '(' (10@100-109) thing (11@110-119) ')' (12@120-129)
929 sending: 'y' (13@130-139)
930 input (0@129-129): /* Nothing */
931 input (2@100-129): line (10@100-129) input (0@129-129)
932 input (2@70-129): line (7@70-99) input (2@100-129)
933 input (2@0-129): line (-1@0-69) input (2@70-129)
934 130.130-139.138: syntax error, unexpected 'y', expecting END
935 Freeing nterm input (2@0-129)
936 Freeing token 'y' (13@130-139)
937 Parsing FAILED.
941 # Syntax error caught by the parser where lookahead = END
942 # --------------------------------------------------------
943 # Load the stack and provoke an error that cannot be caught by the
944 # grammar, to check that the stack is cleared.  And make sure the
945 # lookahead is freed.
947 #     '(', 'x', ')',
948 #     '(', 'x', ')',
949 #     'x'
950 AT_PARSER_CHECK([input '(x)(x)x'], 1, [],
951 [[sending: '(' (0@0-9)
952 sending: 'x' (1@10-19)
953 thing (1@10-19): 'x' (1@10-19)
954 sending: ')' (2@20-29)
955 line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
956 sending: '(' (3@30-39)
957 sending: 'x' (4@40-49)
958 thing (4@40-49): 'x' (4@40-49)
959 sending: ')' (5@50-59)
960 line (3@30-59): '(' (3@30-39) thing (4@40-49) ')' (5@50-59)
961 sending: 'x' (6@60-69)
962 thing (6@60-69): 'x' (6@60-69)
963 sending: END (7@70-79)
964 70.70-79.78: syntax error, unexpected END, expecting 'x'
965 Freeing nterm thing (6@60-69)
966 Freeing nterm line (3@30-59)
967 Freeing nterm line (0@0-29)
968 Freeing token END (7@70-79)
969 Parsing FAILED.
973 # Check destruction upon stack overflow
974 # -------------------------------------
975 # Upon stack overflow, all symbols on the stack should be destroyed.
976 # Only check for yacc.c.
977 AT_YACC_IF([
978 AT_PARSER_CHECK([input '(x)(x)(x)(x)(x)(x)(x)'], 2, [],
979 [[sending: '(' (0@0-9)
980 sending: 'x' (1@10-19)
981 thing (1@10-19): 'x' (1@10-19)
982 sending: ')' (2@20-29)
983 line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
984 sending: '(' (3@30-39)
985 sending: 'x' (4@40-49)
986 thing (4@40-49): 'x' (4@40-49)
987 sending: ')' (5@50-59)
988 line (3@30-59): '(' (3@30-39) thing (4@40-49) ')' (5@50-59)
989 sending: '(' (6@60-69)
990 sending: 'x' (7@70-79)
991 thing (7@70-79): 'x' (7@70-79)
992 sending: ')' (8@80-89)
993 line (6@60-89): '(' (6@60-69) thing (7@70-79) ')' (8@80-89)
994 sending: '(' (9@90-99)
995 sending: 'x' (10@100-109)
996 thing (10@100-109): 'x' (10@100-109)
997 sending: ')' (11@110-119)
998 line (9@90-119): '(' (9@90-99) thing (10@100-109) ')' (11@110-119)
999 sending: '(' (12@120-129)
1000 sending: 'x' (13@130-139)
1001 thing (13@130-139): 'x' (13@130-139)
1002 sending: ')' (14@140-149)
1003 line (12@120-149): '(' (12@120-129) thing (13@130-139) ')' (14@140-149)
1004 sending: '(' (15@150-159)
1005 sending: 'x' (16@160-169)
1006 thing (16@160-169): 'x' (16@160-169)
1007 sending: ')' (17@170-179)
1008 line (15@150-179): '(' (15@150-159) thing (16@160-169) ')' (17@170-179)
1009 sending: '(' (18@180-189)
1010 sending: 'x' (19@190-199)
1011 thing (19@190-199): 'x' (19@190-199)
1012 sending: ')' (20@200-209)
1013 200.200-209.208: memory exhausted
1014 Freeing nterm thing (19@190-199)
1015 Freeing nterm line (15@150-179)
1016 Freeing nterm line (12@120-149)
1017 Freeing nterm line (9@90-119)
1018 Freeing nterm line (6@60-89)
1019 Freeing nterm line (3@30-59)
1020 Freeing nterm line (0@0-29)
1021 Parsing FAILED (status 2).
1025 AT_BISON_OPTION_POPDEFS
1026 ])# _AT_CHECK_PRINTER_AND_DESTRUCTOR
1029 # AT_CHECK_PRINTER_AND_DESTRUCTOR([BISON-OPTIONS], [UNION-FLAG], [SKIP_FLAG])
1030 # ---------------------------------------------------------------------------
1031 m4_define([AT_CHECK_PRINTER_AND_DESTRUCTOR],
1032 [AT_SETUP([Printers and Destructors$2]m4_ifval([$1], [[: $1]]))
1035 _AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4],
1036 [%define parse.error verbose
1037 %debug
1038 %verbose
1039 %locations
1040 $1], [$2])
1042 AT_CLEANUP
1046 AT_CHECK_PRINTER_AND_DESTRUCTOR([])
1047 AT_CHECK_PRINTER_AND_DESTRUCTOR([], [ with union])
1049 AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
1050 AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
1052 AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
1053 AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [ with union])
1055 AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "glr.cc"])
1056 AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "glr.cc"], [ with union])
1060 ## ----------------------------------------- ##
1061 ## Default tagless %printer and %destructor. ##
1062 ## ----------------------------------------- ##
1064 # Check that the right %printer and %destructor are called, that they're not
1065 # called for $end, and that $$ and @$ work correctly.
1067 AT_SETUP([Default tagless %printer and %destructor])
1068 AT_BISON_OPTION_PUSHDEFS([%locations %debug])
1069 AT_DATA_GRAMMAR([[input.y]],
1070 [[%define parse.error verbose
1071 %debug
1072 %locations
1074 %code {
1075 ]AT_YYLEX_DECLARE[
1076 ]AT_YYERROR_DECLARE[
1077 # define USE(SYM)
1080 %printer {
1081   #error "<*> printer should not be used."
1082 } <*>
1084 %printer {
1085   fprintf (yyo, "<> printer for '%c' @ %d", $$, @$.first_column);
1086 } <>
1087 %destructor {
1088   printf ("<> destructor for '%c' @ %d.\n", $$, @$.first_column);
1089 } <>
1091 %printer {
1092   fprintf (yyo, "'b'/'c' printer for '%c' @ %d", $$, @$.first_column);
1093 } 'b' 'c'
1094 %destructor {
1095   printf ("'b'/'c' destructor for '%c' @ %d.\n", $$, @$.first_column);
1096 } 'b' 'c'
1098 %destructor {
1099   #error "<*> destructor should not be used."
1100 } <*>
1104 start: 'a' 'b' 'c' 'd' 'e' { $$ = 'S'; USE(($1, $2, $3, $4, $5)); } ;
1107 ]AT_YYERROR_DEFINE[
1108 ]AT_YYLEX_DEFINE(["abcd"], [[yylval = res]])[
1109 ]AT_MAIN_DEFINE[
1112 AT_BISON_CHECK([-o input.c input.y], [], [],
1113 [[input.y:30.3-5: warning: useless %destructor for type <*> [-Wother]
1114 input.y:30.3-5: warning: useless %printer for type <*> [-Wother]
1116 AT_COMPILE([input])
1117 AT_PARSER_CHECK([input --debug], 1,
1118 [[<> destructor for 'd' @ 4.
1119 'b'/'c' destructor for 'c' @ 3.
1120 'b'/'c' destructor for 'b' @ 2.
1121 <> destructor for 'a' @ 1.
1123 [[Starting parse
1124 Entering state 0
1125 Stack now 0
1126 Reading a token
1127 Next token is token 'a' (1.1: <> printer for 'a' @ 1)
1128 Shifting token 'a' (1.1: <> printer for 'a' @ 1)
1129 Entering state 1
1130 Stack now 0 1
1131 Reading a token
1132 Next token is token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
1133 Shifting token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
1134 Entering state 3
1135 Stack now 0 1 3
1136 Reading a token
1137 Next token is token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
1138 Shifting token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
1139 Entering state 5
1140 Stack now 0 1 3 5
1141 Reading a token
1142 Next token is token 'd' (1.4: <> printer for 'd' @ 4)
1143 Shifting token 'd' (1.4: <> printer for 'd' @ 4)
1144 Entering state 6
1145 Stack now 0 1 3 5 6
1146 Reading a token
1147 Now at end of input.
1148 1.5: syntax error, unexpected end of file, expecting 'e'
1149 Error: popping token 'd' (1.4: <> printer for 'd' @ 4)
1150 Stack now 0 1 3 5
1151 Error: popping token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
1152 Stack now 0 1 3
1153 Error: popping token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
1154 Stack now 0 1
1155 Error: popping token 'a' (1.1: <> printer for 'a' @ 1)
1156 Stack now 0
1157 Cleanup: discarding lookahead token "end of file" (1.5: )
1158 Stack now 0
1161 AT_BISON_OPTION_POPDEFS
1162 AT_CLEANUP
1166 ## ------------------------------------------------------ ##
1167 ## Default tagged and per-type %printer and %destructor.  ##
1168 ## ------------------------------------------------------ ##
1170 AT_SETUP([Default tagged and per-type %printer and %destructor])
1171 AT_BISON_OPTION_PUSHDEFS([%debug])
1172 AT_DATA_GRAMMAR([[input.y]],
1173 [[%define parse.error verbose
1174 %debug
1177 ]AT_YYERROR_DECLARE[
1178 ]AT_YYLEX_DECLARE[
1179 # define USE(SYM)
1182 %printer {
1183   #error "<> printer should not be used."
1184 } <>
1186 %union { int field0; int field1; int field2; }
1187 %type <field0> start 'a' 'g'
1188 %type <field1> 'e'
1189 %type <field2> 'f'
1190 %printer {
1191   fprintf (yyo, "<*>/<field2>/e printer");
1192 } <*> 'e' <field2>
1193 %destructor {
1194   printf ("<*>/<field2>/e destructor.\n");
1195 } <*> 'e' <field2>
1197 %type <field1> 'b'
1198 %printer { fprintf (yyo, "<field1> printer"); } <field1>
1199 %destructor { printf ("<field1> destructor.\n"); } <field1>
1201 %type <field0> 'c'
1202 %printer { fprintf (yyo, "'c' printer"); } 'c'
1203 %destructor { printf ("'c' destructor.\n"); } 'c'
1205 %type <field1> 'd'
1206 %printer { fprintf (yyo, "'d' printer"); } 'd'
1207 %destructor { printf ("'d' destructor.\n"); } 'd'
1209 %destructor {
1210   #error "<> destructor should not be used."
1211 } <>
1215 start:
1216   'a' 'b' 'c' 'd' 'e' 'f' 'g'
1217     {
1218       USE(($1, $2, $3, $4, $5, $6, $7));
1219       $$ = 'S';
1220     }
1221   ;
1224 ]AT_YYERROR_DEFINE[
1225 ]AT_YYLEX_DEFINE(["abcdef"])[
1226 ]AT_MAIN_DEFINE[
1229 AT_BISON_CHECK([-o input.c input.y], [], [],
1230 [[input.y:22.3-4: warning: useless %destructor for type <> [-Wother]
1231 input.y:22.3-4: warning: useless %printer for type <> [-Wother]
1233 AT_COMPILE([input])
1234 AT_PARSER_CHECK([input --debug], 1,
1235 [[<*>/<field2>/e destructor.
1236 <*>/<field2>/e destructor.
1237 'd' destructor.
1238 'c' destructor.
1239 <field1> destructor.
1240 <*>/<field2>/e destructor.
1242 [[Starting parse
1243 Entering state 0
1244 Stack now 0
1245 Reading a token
1246 Next token is token 'a' (<*>/<field2>/e printer)
1247 Shifting token 'a' (<*>/<field2>/e printer)
1248 Entering state 1
1249 Stack now 0 1
1250 Reading a token
1251 Next token is token 'b' (<field1> printer)
1252 Shifting token 'b' (<field1> printer)
1253 Entering state 3
1254 Stack now 0 1 3
1255 Reading a token
1256 Next token is token 'c' ('c' printer)
1257 Shifting token 'c' ('c' printer)
1258 Entering state 5
1259 Stack now 0 1 3 5
1260 Reading a token
1261 Next token is token 'd' ('d' printer)
1262 Shifting token 'd' ('d' printer)
1263 Entering state 6
1264 Stack now 0 1 3 5 6
1265 Reading a token
1266 Next token is token 'e' (<*>/<field2>/e printer)
1267 Shifting token 'e' (<*>/<field2>/e printer)
1268 Entering state 7
1269 Stack now 0 1 3 5 6 7
1270 Reading a token
1271 Next token is token 'f' (<*>/<field2>/e printer)
1272 Shifting token 'f' (<*>/<field2>/e printer)
1273 Entering state 8
1274 Stack now 0 1 3 5 6 7 8
1275 Reading a token
1276 Now at end of input.
1277 syntax error, unexpected end of file, expecting 'g'
1278 Error: popping token 'f' (<*>/<field2>/e printer)
1279 Stack now 0 1 3 5 6 7
1280 Error: popping token 'e' (<*>/<field2>/e printer)
1281 Stack now 0 1 3 5 6
1282 Error: popping token 'd' ('d' printer)
1283 Stack now 0 1 3 5
1284 Error: popping token 'c' ('c' printer)
1285 Stack now 0 1 3
1286 Error: popping token 'b' (<field1> printer)
1287 Stack now 0 1
1288 Error: popping token 'a' (<*>/<field2>/e printer)
1289 Stack now 0
1290 Cleanup: discarding lookahead token "end of file" ()
1291 Stack now 0
1294 AT_BISON_OPTION_POPDEFS
1295 AT_CLEANUP
1299 ## ------------------------------------------------------------- ##
1300 ## Default %printer and %destructor for user-defined end token.  ##
1301 ## ------------------------------------------------------------- ##
1303 AT_SETUP([Default %printer and %destructor for user-defined end token])
1305 # Enable declaration of default %printer/%destructor.  Make the parser
1306 # use these for all user-declared grammar symbols for which the user
1307 # does not declare a specific %printer/%destructor.  Thus, the parser
1308 # uses it for token 0 if the user declares it but not if Bison
1309 # generates it as $end.  Discussed starting at
1310 # <http://lists.gnu.org/r/bison-patches/2006-02/msg00064.html>,
1311 # <http://lists.gnu.org/r/bison-patches/2006-06/msg00091.html>, and
1312 # <http://lists.gnu.org/r/bison-patches/2006-07/msg00019.html>.
1314 # AT_TEST(TYPED)
1315 # --------------
1316 m4_pushdef([AT_TEST],
1317 [m4_if($1, 0,
1318   [m4_pushdef([kind], []) m4_pushdef([not_kind], [*])],
1319   [m4_pushdef([kind], [*]) m4_pushdef([not_kind], [])])
1321 AT_BISON_OPTION_PUSHDEFS([%locations %debug])
1322 AT_DATA_GRAMMAR([[input]]$1[[.y]],
1323 [[%define parse.error verbose
1324 %debug
1325 %locations
1327 %code {
1328 ]AT_YYERROR_DECLARE[
1329 ]AT_YYLEX_DECLARE[
1330 # define USE(SYM)
1333 %destructor {
1334   #error "<]]not_kind[[> destructor should not be used."
1335 } <]]not_kind[[>
1337 %token END 0
1338 %printer {
1339   fprintf (yyo, "<]]kind[[> for '%c' @ %d", $$, @$.first_column);
1340 } <]]kind[[>
1341 %destructor {
1342   printf ("<]]kind[[> for '%c' @ %d.\n", $$, @$.first_column);
1343 } <]]kind[[>
1345 %printer {
1346   #error "<]]not_kind[[> printer should not be used."
1347 } <]]not_kind[[>
1349 ]]m4_if($1, 0, [[[
1350 ]]],
1351 [[[%union { char tag; }
1352 %type <tag> start END]]])[[
1356 start: { $$ = 'S'; } ;
1359 #include <stdlib.h> /* abort */
1360 static int
1361 yylex (void)
1363   static int called;
1364   if (called++)
1365     abort ();
1366   yylval]]m4_if($1, 0,, [[[.tag]]])[[ = 'E';
1367   yylloc.first_line = yylloc.last_line = 1;
1368   yylloc.first_column = yylloc.last_column = 1;
1369   return 0;
1371 ]AT_YYERROR_DEFINE[
1372 ]AT_MAIN_DEFINE[
1374 AT_BISON_OPTION_POPDEFS
1376 AT_BISON_CHECK([-o input$1.c input$1.y], [], [],
1377 [m4_if([$1], [0],
1378 [[input0.y:30.3-5: warning: useless %destructor for type <*> [-Wother]
1379 input0.y:30.3-5: warning: useless %printer for type <*> [-Wother]
1381 [[input1.y:30.3-4: warning: useless %destructor for type <> [-Wother]
1382 input1.y:30.3-4: warning: useless %printer for type <> [-Wother]
1383 ]])])
1385 AT_COMPILE([input$1])
1387 AT_PARSER_CHECK([input$1 --debug], 0,
1388 [[<]]kind[[> for 'E' @ 1.
1389 <]]kind[[> for 'S' @ 1.
1391 [[Starting parse
1392 Entering state 0
1393 Stack now 0
1394 Reducing stack by rule 1 (line 49):
1395 -> $$ = nterm start (1.1: <]]kind[[> for 'S' @ 1)
1396 Entering state 1
1397 Stack now 0 1
1398 Reading a token
1399 Now at end of input.
1400 Shifting token END (1.1: <]]kind[[> for 'E' @ 1)
1401 Entering state 2
1402 Stack now 0 1 2
1403 Stack now 0 1 2
1404 Cleanup: popping token END (1.1: <]]kind[[> for 'E' @ 1)
1405 Cleanup: popping nterm start (1.1: <]]kind[[> for 'S' @ 1)
1408 m4_popdef([kind])
1409 m4_popdef([not_kind])
1412 AT_TEST(0)
1413 AT_TEST(1)
1415 m4_popdef([AT_TEST])
1417 AT_CLEANUP
1421 ## ------------------------------------------------------------------ ##
1422 ## Default %printer and %destructor are not for error or $undefined.  ##
1423 ## ------------------------------------------------------------------ ##
1425 AT_SETUP([Default %printer and %destructor are not for error or $undefined])
1427 # If Bison were to apply the default %printer and %destructor to the error
1428 # token or to $undefined:
1429 #   - For the error token:
1430 #     - It would generate warnings for unused $n.
1431 #     - It would invoke the %printer and %destructor on the error token's
1432 #       semantic value, which would be initialized from the lookahead, which
1433 #       would be destroyed separately.
1434 #   - For $undefined, who knows what the semantic value would be.
1435 AT_BISON_OPTION_PUSHDEFS([%debug])
1436 AT_DATA_GRAMMAR([[input.y]],
1437 [[%debug
1440 # include <stdio.h>
1441 # include <stdlib.h>
1442 ]AT_YYERROR_DECLARE[
1443 ]AT_YYLEX_DECLARE[
1444 # define USE(SYM)
1447 %printer {
1448   fprintf (yyo, "'%c'", $$);
1449 } <> <*>
1450 %destructor {
1451   fprintf (stderr, "DESTROY '%c'\n", $$);
1452 } <> <*>
1456 start:
1457   { $$ = 'S'; }
1458   /* In order to reveal the problems that this bug caused during parsing, add
1459    * $2 to USE.  */
1460   | 'a' error 'b' 'c' { USE(($1, $3, $4)); $$ = 'S'; }
1461   ;
1464 ]AT_YYERROR_DEFINE[
1465 ]AT_YYLEX_DEFINE(["abd"], [yylval = res])[
1466 ]AT_MAIN_DEFINE[
1468 AT_BISON_OPTION_POPDEFS
1470 AT_BISON_CHECK([-o input.c input.y], [], [],
1471 [[input.y:23.6-8: warning: useless %destructor for type <*> [-Wother]
1472 input.y:23.6-8: warning: useless %printer for type <*> [-Wother]
1474 AT_COMPILE([input])
1475 AT_PARSER_CHECK([input --debug], [1], [],
1476 [[Starting parse
1477 Entering state 0
1478 Stack now 0
1479 Reading a token
1480 Next token is token 'a' ('a')
1481 Shifting token 'a' ('a')
1482 Entering state 1
1483 Stack now 0 1
1484 Reading a token
1485 Next token is token 'b' ('b')
1486 syntax error
1487 Shifting token error ()
1488 Entering state 3
1489 Stack now 0 1 3
1490 Next token is token 'b' ('b')
1491 Shifting token 'b' ('b')
1492 Entering state 5
1493 Stack now 0 1 3 5
1494 Reading a token
1495 Next token is token "invalid token" ()
1496 Error: popping token 'b' ('b')
1497 DESTROY 'b'
1498 Stack now 0 1 3
1499 Error: popping token error ()
1500 Stack now 0 1
1501 Shifting token error ()
1502 Entering state 3
1503 Stack now 0 1 3
1504 Next token is token "invalid token" ()
1505 Error: discarding token "invalid token" ()
1506 Error: popping token error ()
1507 Stack now 0 1
1508 Shifting token error ()
1509 Entering state 3
1510 Stack now 0 1 3
1511 Reading a token
1512 Now at end of input.
1513 Cleanup: discarding lookahead token "end of file" ()
1514 Stack now 0 1 3
1515 Cleanup: popping token error ()
1516 Cleanup: popping token 'a' ('a')
1517 DESTROY 'a'
1520 AT_CLEANUP
1524 ## ------------------------------------------------------ ##
1525 ## Default %printer and %destructor are not for $accept.  ##
1526 ## ------------------------------------------------------ ##
1528 AT_SETUP([Default %printer and %destructor are not for $accept])
1530 # If YYSTYPE is a union and Bison were to apply the default %printer and
1531 # %destructor to $accept:
1532 #   - The %printer and %destructor code generated for $accept would always be
1533 #     dead code because $accept is currently never shifted onto the stack.
1534 #   - $$ for $accept would always be of type YYSTYPE because it's not possible
1535 #     to declare '%type <field> $accept'.  (Also true for $undefined.)
1536 #   - Thus, the compiler might complain that the user code assumes the wrong
1537 #     type for $$ since the code might assume the type associated with a
1538 #     specific union field, which is especially reasonable in C++ since that
1539 #     type may be a base type.  This test case checks for this problem.  (Also
1540 #     true for $undefined and the error token, so there are three warnings for
1541 #     %printer and three for %destructor.)
1543 AT_BISON_OPTION_PUSHDEFS([%debug])
1544 AT_DATA_GRAMMAR([[input.y]],
1545 [[%debug /* So that %printer is actually compiled.  */
1548 # include <stdio.h>
1549 # include <stdlib.h>
1550 ]AT_YYERROR_DECLARE[
1551 ]AT_YYLEX_DECLARE[
1552 # define USE(SYM)
1555 %printer {
1556   char chr = $$;
1557   fprintf (yyo, "'%c'", chr);
1558 } <> <*>
1559 %destructor {
1560   char chr = $$;
1561   fprintf (stderr, "DESTROY '%c'\n", chr);
1562 } <> <*>
1564 %union { char chr; }
1565 %type <chr> start
1569 start: { USE($$); } ;
1572 ]AT_YYERROR_DEFINE[
1573 ]AT_YYLEX_DEFINE[
1574 ]AT_MAIN_DEFINE[
1576 AT_BISON_OPTION_POPDEFS
1578 AT_BISON_CHECK([-o input.c input.y], [], [],
1579 [[input.y:24.3-4: warning: useless %destructor for type <> [-Wother]
1580 input.y:24.3-4: warning: useless %printer for type <> [-Wother]
1582 AT_COMPILE([input])
1584 AT_CLEANUP
1588 ## ----------------------------------------------------- ##
1589 ## Default %printer and %destructor for midrule values.  ##
1590 ## ----------------------------------------------------- ##
1592 AT_SETUP([Default %printer and %destructor for midrule values])
1594 AT_BISON_OPTION_PUSHDEFS([%debug])
1595 AT_DATA_GRAMMAR([[input.y]],
1596 [[%debug /* So that %printer is actually compiled.  */
1599 ]AT_YYERROR_DECLARE[
1600 ]AT_YYLEX_DECLARE[
1601 # define USE(SYM)
1602 # define YYLTYPE int
1603 # define YYLLOC_DEFAULT(Current, Rhs, N) (void)(Rhs)
1604 # define LOCATION_PRINT(File, Loc)
1607 %printer    { fprintf (yyo, "%d", @$); } <>
1608 %destructor { fprintf (stderr, "DESTROY %d\n", @$); } <>
1609 %printer    { #error "<*> printer should not be used" } <*>
1610 %destructor { #error "<*> destructor should not be used" } <*>
1614 start:
1615   {           @$ = 1; } // Not set or used.
1616   { USE ($$); @$ = 2; } // Both set and used.
1617   { USE ($$); @$ = 3; } // Only set.
1618   {           @$ = 4; } // Only used.
1619   'c'
1620   { USE (($$, $2, $4, $5)); @$ = 0; }
1621   ;
1624 ]AT_YYERROR_DEFINE[
1625 ]AT_YYLEX_DEFINE[
1626 ]AT_MAIN_DEFINE[
1628 AT_BISON_OPTION_POPDEFS
1630 AT_BISON_CHECK([-o input.c input.y], 0,,
1631 [[input.y:24.57-59: warning: useless %destructor for type <*> [-Wother]
1632 input.y:24.57-59: warning: useless %printer for type <*> [-Wother]
1633 input.y:33.3-23: warning: unset value: $$ [-Wother]
1634 input.y:32.3-23: warning: unused value: $3 [-Wother]
1637 AT_BISON_CHECK([-fcaret -o input.c input.y], 0,,
1638 [[input.y:24.57-59: warning: useless %destructor for type <*> [-Wother]
1639    24 | %printer    { #error "<*> printer should not be used" } <*>
1640       |                                                         ^~~
1641 input.y:24.57-59: warning: useless %printer for type <*> [-Wother]
1642    24 | %printer    { #error "<*> printer should not be used" } <*>
1643       |                                                         ^~~
1644 input.y:33.3-23: warning: unset value: $$ [-Wother]
1645    33 |   {           @$ = 4; } // Only used.
1646       |   ^~~~~~~~~~~~~~~~~~~~~
1647 input.y:32.3-23: warning: unused value: $3 [-Wother]
1648    32 |   { USE ($$); @$ = 3; } // Only set.
1649       |   ^~~~~~~~~~~~~~~~~~~~~
1652 AT_COMPILE([input])
1653 AT_PARSER_CHECK([input --debug], 1,,
1654 [[Starting parse
1655 Entering state 0
1656 Stack now 0
1657 Reducing stack by rule 1 (line 30):
1658 -> $$ = nterm $@1 (: )
1659 Entering state 2
1660 Stack now 0 2
1661 Reducing stack by rule 2 (line 31):
1662 -> $$ = nterm @2 (: 2)
1663 Entering state 4
1664 Stack now 0 2 4
1665 Reducing stack by rule 3 (line 32):
1666 -> $$ = nterm @3 (: 3)
1667 Entering state 5
1668 Stack now 0 2 4 5
1669 Reducing stack by rule 4 (line 33):
1670 -> $$ = nterm @4 (: 4)
1671 Entering state 6
1672 Stack now 0 2 4 5 6
1673 Reading a token
1674 Now at end of input.
1675 syntax error
1676 Error: popping nterm @4 (: 4)
1677 DESTROY 4
1678 Stack now 0 2 4 5
1679 Error: popping nterm @3 (: 3)
1680 DESTROY 3
1681 Stack now 0 2 4
1682 Error: popping nterm @2 (: 2)
1683 DESTROY 2
1684 Stack now 0 2
1685 Error: popping nterm $@1 (: )
1686 Stack now 0
1687 Cleanup: discarding lookahead token "end of file" (: )
1688 Stack now 0
1691 AT_CLEANUP
1694 ## ----------------------- ##
1695 ## @$ implies %locations.  ##
1696 ## ----------------------- ##
1698 # Bison once forgot to check for @$ in actions other than semantic actions.
1700 # AT_CHECK_ACTION_LOCATIONS(ACTION-DIRECTIVE)
1701 # -------------------------------------------
1702 m4_define([AT_CHECK_ACTION_LOCATIONS],
1703 [AT_SETUP([[@$ in ]$1[ implies %locations]])
1704 AT_BISON_OPTION_PUSHDEFS([%debug])
1705 AT_DATA_GRAMMAR([[input.y]],
1706 [[%code {
1707   #include <stdio.h>
1708 ]AT_YYERROR_DECLARE[
1709 ]AT_YYLEX_DECLARE[
1712 %debug
1714 ]$1[ {
1715   fprintf (stderr, "%d\n", @$.first_line);
1716 } ]m4_if($1, [%initial-action], [], [[start]])[
1720 start:  ;
1724 static int
1725 yylex (void)
1727   return 0;
1730 ]AT_YYERROR_DEFINE[
1731 ]AT_MAIN_DEFINE[
1734 AT_BISON_CHECK([[-o input.c input.y]])
1735 AT_COMPILE([[input]])
1736 AT_BISON_OPTION_POPDEFS
1737 AT_CLEANUP])
1739 AT_CHECK_ACTION_LOCATIONS([[%initial-action]])
1740 AT_CHECK_ACTION_LOCATIONS([[%destructor]])
1741 AT_CHECK_ACTION_LOCATIONS([[%printer]])
1744 ## ------------------------- ##
1745 ## Qualified $$ in actions.  ##
1746 ## ------------------------- ##
1748 # Check that we can use qualified $$ (v.g., $<type>$) not only in rule
1749 # actions, but also where $$ is valid: %destructor/%printer and
1750 # %initial-action.
1752 # FIXME: Not actually checking %destructor, but it's the same code as
1753 # %printer...
1755 # To do that, use a semantic value that has two fields (sem_type),
1756 # declare symbols to have only one of these types (INT, float), and
1757 # use $<type>$ to get the other one.  Including for symbols that are
1758 # not typed (UNTYPED).
1760 m4_pushdef([AT_TEST],
1761 [AT_SETUP([[Qualified $$ in actions: $1]])
1763 AT_BISON_OPTION_PUSHDEFS([%skeleton "$1" %debug])
1765 AT_DATA_GRAMMAR([[input.y]],
1766 [[%skeleton "$1"
1767 %debug
1768 %code requires
1770   typedef struct sem_type
1771   {
1772     int ival;
1773     float fval;
1774   } sem_type;
1776 # define YYSTYPE sem_type
1778 ]AT_CXX_IF([[
1779 # include <cstdio> // EOF.
1780 # include <iostream>
1781   namespace
1782   {
1783     void
1784     report (std::ostream& yyo, int ival, float fval)
1785     {
1786       yyo << "ival: " << ival << ", fval: " <<  fval;
1787     }
1788   }
1789 ]], [[
1790 # include <stdio.h>
1791   static void
1792   report (FILE* yyo, int ival, float fval)
1793   {
1794     fprintf (yyo, "ival: %d, fval: %1.1f", ival, fval);
1795   }
1796 ]])[
1799 %code
1801   ]AT_YYERROR_DECLARE[
1802   ]AT_YYLEX_DECLARE[
1805 %token UNTYPED
1806 %token <ival> INT
1807 %type <fval> float
1808 %printer { report (yyo, $$,       $<fval>$); } <ival>;
1809 %printer { report (yyo, $<ival>$, $$      ); } <fval>;
1810 %printer { report (yyo, $<ival>$, $<fval>$); } <>;
1812 %initial-action
1814   $<ival>$ = 42;
1815   $<fval>$ = 4.2f;
1819 float: UNTYPED INT
1821   $$       = $<fval>1 + $<fval>2;
1822   $<ival>$ = $<ival>1 + $][2;
1825 ]AT_YYERROR_DEFINE[
1826 ]AT_YYLEX_DEFINE(AT_CXX_IF([[{yy::parser::token::UNTYPED,
1827                                  yy::parser::token::INT,
1828                                   EOF}]],
1829                                [[{UNTYPED, INT, EOF}]]),
1830                  [AT_VAL.ival = toknum * 10;
1831                   AT_VAL.fval = YY_CAST (float, toknum) / 10.0f;])[
1832 ]AT_MAIN_DEFINE[
1835 AT_FULL_COMPILE([[input]])
1836 AT_PARSER_CHECK([input --debug], 0, [], [stderr])
1837 # Don't be too picky on the traces, GLR is not exactly the same.  Keep
1838 # only the lines from the printer.
1839 AT_CHECK([[sed -ne '/ival:/p' stderr]], 0,
1840 [[Next token is token UNTYPED (ival: 10, fval: 0.1)
1841 Shifting token UNTYPED (ival: 10, fval: 0.1)
1842 Next token is token INT (ival: 20, fval: 0.2)
1843 Shifting token INT (ival: 20, fval: 0.2)
1844    $][1 = token UNTYPED (ival: 10, fval: 0.1)
1845    $][2 = token INT (ival: 20, fval: 0.2)
1846 -> $$ = nterm float (ival: 30, fval: 0.3)
1847 Cleanup: popping nterm float (ival: 30, fval: 0.3)
1850 AT_BISON_OPTION_POPDEFS
1852 AT_CLEANUP
1855 m4_map_args([AT_TEST], [yacc.c], [glr.c], [lalr1.cc], [glr.cc])
1856 m4_popdef([AT_TEST])
1858 ## -------------------------------------------------- ##
1859 ## Destroying lookahead assigned by semantic action.  ##
1860 ## -------------------------------------------------- ##
1862 AT_SETUP([[Destroying lookahead assigned by semantic action]])
1864 AT_BISON_OPTION_PUSHDEFS
1865 AT_DATA_GRAMMAR([input.y],
1867 %code {
1868   #include <assert.h>
1869   #include <stdio.h>
1870 ]AT_YYERROR_DECLARE[
1871 ]AT_YYLEX_DECLARE[
1872   #define USE(Var)
1875 %destructor { fprintf (stderr, "'a' destructor\n"); } 'a'
1876 %destructor { fprintf (stderr, "'b' destructor\n"); } 'b'
1880 // In a previous version of Bison, yychar assigned by the semantic
1881 // action below was not translated into yytoken before the lookahead was
1882 // discarded and thus before its destructor (selected according to
1883 // yytoken) was called in order to return from yyparse.  This would
1884 // happen even if YYACCEPT was performed in a later semantic action as
1885 // long as only consistent states with default reductions were visited
1886 // in between.  However, we leave YYACCEPT in the same semantic action
1887 // for this test in order to show that skeletons cannot simply translate
1888 // immediately after every semantic action because a semantic action
1889 // that has set yychar might not always return normally.  Instead,
1890 // skeletons must translate before every use of yytoken.
1891 start: 'a' accept { USE($1); } ;
1892 accept: %empty {
1893   assert (yychar == YYEMPTY);
1894   yychar = 'b';
1895   YYACCEPT;
1896 } ;
1899 ]AT_YYERROR_DEFINE[
1900 ]AT_YYLEX_DEFINE(["a"])[
1901 ]AT_MAIN_DEFINE[
1903 AT_BISON_OPTION_POPDEFS
1904 AT_BISON_CHECK([[-o input.c input.y]])
1905 AT_COMPILE([[input]])
1906 AT_PARSER_CHECK([[input]], [[0]], [],
1907 [['b' destructor
1908 'a' destructor
1911 AT_CLEANUP
1913 ## ---------- ##
1914 ## YYBACKUP.  ##
1915 ## ---------- ##
1917 AT_SETUP([[YYBACKUP]])
1919 AT_BISON_OPTION_PUSHDEFS([%pure-parser %debug])
1921 AT_DATA_GRAMMAR([input.y],
1923 %define parse.error verbose
1924 %debug
1925 %define api.pure
1926 %code {
1927 # include <stdio.h>
1928 # include <stdlib.h>
1929 # include <assert.h>
1931   ]AT_YYERROR_DECLARE[
1932   ]AT_YYLEX_DECLARE[
1935 input:
1936   exp exp {}
1939 exp:
1940   'a'     { printf ("a: %d\n", $1); }
1941 | 'b'     { YYBACKUP('a', 123); }
1942 | 'c' 'd' { YYBACKUP('a', 456); }
1946 ]AT_YYERROR_DEFINE[
1947 ]AT_YYLEX_DEFINE(["bcd"], [*lvalp = (toknum + 1) * 10])[
1948 ]AT_MAIN_DEFINE[
1950 AT_BISON_OPTION_POPDEFS
1952 AT_BISON_CHECK([[-o input.c input.y]])
1953 AT_COMPILE([[input]])
1954 AT_PARSER_CHECK([[input]], [[0]],
1955 [[a: 123
1956 a: 456
1959 AT_CLEANUP