1 e# Executing Actions. -*- Autotest -*-
3 # Copyright (C) 2001-2015 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 ## Mid-rule actions. ##
22 ## ------------------ ##
24 AT_SETUP([Mid-rule actions])
26 # Bison once forgot the mid-rule actions. It was because the action
27 # was attached to the host rule (the one with the mid-rule action),
28 # instead of being attached to the empty rule dedicated to this
31 AT_BISON_OPTION_PUSHDEFS
32 AT_DATA_GRAMMAR([[input.y]],
33 [[%define parse.error verbose
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'); }
54 ]AT_YYLEX_DEFINE(["123456789"])[
57 AT_BISON_OPTION_POPDEFS
59 AT_BISON_CHECK([-d -v -o input.c input.y])
61 AT_PARSER_CHECK([./input], 0,
67 ## ----------------------- ##
68 ## Implicitly empty rule. ##
69 ## ----------------------- ##
71 AT_SETUP([Implicitly empty rule])
73 AT_DATA_GRAMMAR([[1.y]],
77 // A mid-rule action does not count as an empty rule.
81 AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [],
82 [[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
87 AT_DATA_GRAMMAR([[2.y]],
95 AT_BISON_CHECK([-fcaret 2.y], [0], [],
96 [[2.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
99 2.y:13.17-18: warning: empty rule without %empty [-Wempty-rule]
104 AT_BISON_CHECK([-fcaret -Wno-empty-rule 2.y], [0])
108 ## ------------------------ ##
109 ## Invalid uses of %empty. ##
110 ## ------------------------ ##
112 AT_SETUP([Invalid uses of %empty])
114 AT_DATA_GRAMMAR([[one.y]],
121 AT_BISON_CHECK([-fcaret one.y], [1], [],
122 [[one.y:11.13-18: error: only one %empty allowed per rule
125 one.y:11.3-8: previous declaration
130 AT_DATA_GRAMMAR([[two.y]],
139 AT_BISON_CHECK([-fcaret two.y], [1], [],
140 [[two.y:11.7-12: error: %empty on non-empty rule
143 two.y:12.3-8: error: %empty on non-empty rule
146 two.y:13.3-8: error: %empty on non-empty rule
153 ## ---------------------- ##
154 ## Valid uses of %empty. ##
155 ## ---------------------- ##
157 AT_SETUP([Valid uses of %empty])
159 AT_BISON_OPTION_PUSHDEFS
160 AT_DATA_GRAMMAR([[input.y]],
176 AT_FULL_COMPILE([input])
177 AT_PARSER_CHECK([./input])
178 AT_BISON_OPTION_POPDEFS
181 ## ------------------ ##
182 ## Initial location. ##
183 ## ------------------ ##
185 # AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
186 # -----------------------------------------------------------------------
187 # Check that the initial location is correct.
188 m4_pushdef([AT_TEST],
189 [AT_SETUP([Initial location: $1 $2])
191 AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2])
192 AT_DATA_GRAMMAR([[input.y]],
201 # include <stdlib.h> /* getenv */
206 exp: { ]AT_SKEL_CC_IF([[std::cerr << @$ << std::endl]],
207 [[LOCATION_PRINT(stderr, @$); fputc ('\n', stderr)]])[; }
214 YYUSE(llocp);], [AT_SKEL_CC_IF([
224 p.set_debug_level (!!getenv("YYDEBUG"));
225 return p.parse ();]], [[
226 yydebug = !!getenv("YYDEBUG");
227 return !!yyparse (]AT_PARAM_IF([0])[);]])[
231 AT_FULL_COMPILE([input])
232 AT_PARSER_CHECK([./input], 1, [],
233 [m4_default([$4], [1.1])
234 m4_default([$4], [1.1])[: syntax error
236 AT_BISON_OPTION_POPDEFS
240 ## FIXME: test Java, and iterate over skeletons.
242 AT_TEST([yacc.c], [%define api.pure full])
243 AT_TEST([yacc.c], [%define api.pure %parse-param { int x }])
244 AT_TEST([yacc.c], [%define api.push-pull both])
245 AT_TEST([yacc.c], [%define api.push-pull both %define api.pure full])
247 AT_TEST([glr.c], [%define api.pure])
251 ## A very different test, based on PostgreSQL's implementation of the
253 ## http://lists.gnu.org/archive/html/bug-bison/2012-11/msg00023.html
255 ## Weirdly enough, to trigger the warning with GCC 4.7, we must not
256 ## use fprintf, so run the test twice: once to check the warning
257 ## (absence thereof), and another time to check the value.
258 AT_TEST([yacc.c], [%define api.pure full],
261 # define LOCATION_PRINT(Stream, Loc) \
263 # define YYLLOC_DEFAULT(Current, Rhs, N) \
264 (Current) = ((Rhs)[N ? 1 : 0])
269 AT_TEST([yacc.c], [%define api.pure full],
272 # define LOCATION_PRINT(Stream, Loc) \
273 fprintf ((Stream), "%d", (Loc))
274 # define YYLLOC_DEFAULT(Current, Rhs, N) \
275 (Current) = ((Rhs)[N ? 1 : 0])
285 ## ---------------- ##
286 ## Location Print. ##
287 ## ---------------- ##
289 # AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES])
290 # -----------------------------------------------------
291 # Check that the initial location is correct.
292 m4_pushdef([AT_TEST],
293 [AT_SETUP([Location print: $1 $2])
295 AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2])
296 AT_DATA_GRAMMAR([[input.y]],
317 ]AT_GLR_CC_IF([loc.initialize();])[
318 #define TEST(L1, C1, L2, C2) \
319 loc.]AT_FIRST_LINE[ = L1; \
320 loc.]AT_FIRST_COLUMN[ = C1; \
321 loc.]AT_LAST_LINE[ = L2; \
322 loc.]AT_LAST_COLUMN[ = C2; \
323 ]AT_SKEL_CC_IF([std::cout << loc],
324 [LOCATION_PRINT(stdout, loc)])[;\
338 AT_FULL_COMPILE([input])
339 AT_PARSER_CHECK([./input], 0,
347 AT_BISON_OPTION_POPDEFS
351 ## FIXME: test Java, and iterate over skeletons.
361 ## ---------------- ##
362 ## Exotic Dollars. ##
363 ## ---------------- ##
365 AT_SETUP([Exotic Dollars])
367 AT_BISON_OPTION_PUSHDEFS
368 AT_DATA_GRAMMAR([[input.y]],
369 [[%define parse.error verbose
382 %type <val> a_1 a_2 a_5
383 sum_of_the_five_previous_values
386 exp: a_1 a_2 { $<val>$ = 3; } { $<val>$ = $<val>3 + 1; } a_5
387 sum_of_the_five_previous_values
389 USE (($1, $2, $<foo>3, $<foo>4, $5));
397 sum_of_the_five_previous_values:
399 $$ = $<val>0 + $<val>-1 + $<val>-2 + $<val>-3 + $<val>-4;
409 AT_BISON_CHECK([-d -v -o input.c input.y], 0)
411 AT_PARSER_CHECK([./input], 0,
415 # Make sure that fields after $n or $-n are parsed correctly. At one
416 # point while implementing dashes in symbol names, we were dropping
418 AT_DATA_GRAMMAR([[input.y]],
423 typedef struct { int val; } stype;
424 # define YYSTYPE stype
428 start: one two { $$.val = $1.val + $2.val; } sum ;
429 one: { $$.val = 1; } ;
430 two: { $$.val = 2; } ;
431 sum: { printf ("%d\n", $0.val + $-1.val + $-2.val); } ;
439 AT_FULL_COMPILE([input])
440 AT_PARSER_CHECK([[./input]], [[0]],
444 AT_BISON_OPTION_POPDEFS
449 ## -------------------------- ##
450 ## Printers and Destructors. ##
451 ## -------------------------- ##
453 # _AT_CHECK_PRINTER_AND_DESTRUCTOR($1, $2, $3, $4,
454 # BISON-DIRECTIVE, UNION-FLAG)
455 # -------------------------------------------------------------
456 m4_define([_AT_CHECK_PRINTER_AND_DESTRUCTOR],
457 [# Make sure complex $n work.
458 m4_if([$1$2$3$4], $[1]$[2]$[3]$[4], [],
459 [m4_fatal([$0: Invalid arguments: $@])])dnl
461 # Be sure to pass all the %directives to this macro to have correct
462 # helping macros. So don't put any directly in the Bison file.
463 AT_BISON_OPTION_PUSHDEFS([$5])
464 AT_DATA_GRAMMAR([[input.y]],
471 #define YYINITDEPTH 10
472 #define YYMAXDEPTH 10
473 #define RANGE(Location) ]AT_LALR1_CC_IF([(Location).begin.line, (Location).end.line],
474 [(Location).first_line, (Location).last_line])[
476 /* Display the symbol type Symbol. */
477 #define V(Symbol, Value, Location, Sep) \
478 fprintf (stderr, #Symbol " (%d@%d-%d)%s", Value, RANGE(Location), Sep)
482 ]m4_ifval([$6], [%union
486 AT_LALR1_CC_IF([%define global_tokens_and_yystype])
487 m4_ifval([$6], [[%code provides {]], [[%code {]])
488 AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
490 ]AT_LALR1_CC_IF([], [AT_YYERROR_DECLARE])
494 [%type <ival> '(' 'x' 'y' ')' ';' thing line input
495 '!' raise check-spontaneous-errors END])[
497 /* FIXME: This %printer isn't actually tested. */
500 ]AT_LALR1_CC_IF([yyo << $$;],
501 [fprintf (yyo, "%d", $$)])[;
503 '(' 'x' 'y' ')' ';' thing line input '!' raise check-spontaneous-errors END
506 { fprintf (stderr, "Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); }
510 { fprintf (stderr, "Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); }
514 { fprintf (stderr, "Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); }
518 { fprintf (stderr, "Freeing raise thing (%d@%d-%d)\n", $$, RANGE (@$)); }
522 { fprintf (stderr, "Freeing check-spontaneous-errors thing (%d@%d-%d)\n", $$, RANGE (@$)); }
523 check-spontaneous-errors
526 { fprintf (stderr, "Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); }
530 { fprintf (stderr, "Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); }
535 { fprintf (stderr, "Freeing token END (%d@%d-%d)\n", $$, RANGE (@$)); }
540 This grammar is made to exercise error recovery.
541 "Lines" starting with '(' support error recovery, with
542 ')' as synchronizing token. Lines starting with 'x' can never
543 be recovered from if in error.
550 V(input, $$, @$, ": /* Nothing */\n");
552 | line input /* Right recursive to load the stack so that popping at
553 END can be exercised. */
556 V(input, $$, @$, ": ");
557 V(line, $1, @1, " ");
558 V(input, $2, @2, "\n");
560 | '!' check-spontaneous-errors
566 check-spontaneous-errors:
567 raise { abort(); $$ = $1; }
568 | '(' raise ')' { abort(); $$ = $2; }
572 V(check-spontaneous-errors, $$, @$, ": ");
573 fprintf (stderr, "error (@%d-%d)\n", RANGE(@1));
581 V(raise, $$, @$, ": %empty\n");
587 V(raise, $$, @$, ": ");
595 thing thing thing ';'
598 V(line, $$, @$, ": ");
599 V(thing, $1, @1, " ");
600 V(thing, $2, @2, " ");
601 V(thing, $3, @3, " ");
604 | '(' thing thing ')'
607 V(line, $$, @$, ": ");
609 V(thing, $2, @2, " ");
610 V(thing, $3, @3, " ");
611 V(')', $4, @4, "\n");
616 V(line, $$, @$, ": ");
618 V(thing, $2, @2, " ");
619 V(')', $3, @3, "\n");
624 V(line, $$, @$, ": ");
626 fprintf (stderr, "error (@%d-%d) ", RANGE(@2));
627 V(')', $3, @3, "\n");
635 V(thing, $$, @$, ": ");
636 V('x', $1, @1, "\n");
640 /* Alias to ARGV[1]. */
641 const char *source = YY_NULLPTR;
648 static unsigned int counter = 0;
650 unsigned int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
651 /* As in BASIC, line numbers go from 10 to 10. */
652 ]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = 10 * c;
653 ]AT_LOC_LAST_LINE[ = ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_LINE[ + 9;
654 assert (c <= strlen (source));
656 fprintf (stderr, "sending: '%c'", source[c]);
658 fprintf (stderr, "sending: END");
659 fprintf (stderr, " (%d@%d-%d)\n", c, RANGE (]AT_LOC[));
663 [static bool yydebug;
668 parser.set_debug_level (yydebug);
669 return parser.parse ();
674 main (int argc, const char *argv[])
677 yydebug = !!getenv ("YYDEBUG");
678 assert (argc == 2); (void) argc;
683 case 0: fprintf (stderr, "Successful parse.\n"); break;
684 case 1: fprintf (stderr, "Parsing FAILED.\n"); break;
685 default: fprintf (stderr, "Parsing FAILED (status %d).\n", status); break;
691 AT_FULL_COMPILE([input])
694 # Check the location of "empty"
695 # -----------------------------
696 # I.e., epsilon-reductions, as in "(x)" which ends by reducing
697 # an empty "line" nterm.
698 # FIXME: This location is not satisfying. Depend on the lookahead?
699 AT_PARSER_CHECK([./input '(x)'], 0, [],
700 [[sending: '(' (0@0-9)
701 sending: 'x' (1@10-19)
702 thing (1@10-19): 'x' (1@10-19)
703 sending: ')' (2@20-29)
704 line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
705 sending: END (3@30-39)
706 input (0@29-29): /* Nothing */
707 input (2@0-29): line (0@0-29) input (0@29-29)
708 Freeing token END (3@30-39)
709 Freeing nterm input (2@0-29)
713 # Check the location of empty reductions raising an error
714 # -------------------------------------------------------
715 # Here, the error is after token "!@0-9", so the error is raised from
716 # @9-9, and the error recovery detects that it starts from @9-9 and
717 # ends where starts the next token: END@10-19.
719 # So error recovery reports error@9-19.
720 AT_PARSER_CHECK([./input '!'], 0, [],
721 [[sending: '!' (0@0-9)
722 sending: END (1@10-19)
723 raise (4@9-9): %empty
724 check-spontaneous-errors (5@9-19): error (@9-19)
725 Freeing token END (1@10-19)
726 Freeing nterm input (5@0-19)
730 # Check the location of not empty reductions raising an error
731 # -----------------------------------------------------------
732 # This time the error is raised from a rule with 2 rhs symbols: @10-29.
733 # It is recovered @10-29.
734 AT_PARSER_CHECK([[./input '!!!']], 0, [],
735 [[sending: '!' (0@0-9)
736 sending: '!' (1@10-19)
737 sending: '!' (2@20-29)
738 raise (5@10-29): ! (1@20-29) ! (2@20-29)
739 check-spontaneous-errors (5@10-29): error (@10-29)
740 sending: END (3@30-39)
741 Freeing token END (3@30-39)
742 Freeing nterm input (5@0-29)
746 # Check locations in error recovery
747 # ---------------------------------
748 # '(y)' is an error, but can be recovered from. But what's the location
749 # of the error itself ('y'), and of the resulting reduction ('(error)').
750 AT_PARSER_CHECK([./input '(y)'], 0, [],
751 [[sending: '(' (0@0-9)
752 sending: 'y' (1@10-19)
753 10.10-19.18: syntax error, unexpected 'y', expecting 'x'
754 Freeing token 'y' (1@10-19)
755 sending: ')' (2@20-29)
756 line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29)
757 sending: END (3@30-39)
758 input (0@29-29): /* Nothing */
759 input (2@0-29): line (-1@0-29) input (0@29-29)
760 Freeing token END (3@30-39)
761 Freeing nterm input (2@0-29)
766 # Syntax errors caught by the parser
767 # ----------------------------------
768 # Exercise the discarding of stack top and input until 'error'
771 # '(', 'x', 'x', 'x', 'x', 'x', ')',
773 # Load the stack and provoke an error that cannot be caught by the
774 # grammar, to check that the stack is cleared. And make sure the
775 # lookahead is freed.
780 AT_PARSER_CHECK([./input '(xxxxx)(x)(x)y'], 1, [],
781 [[sending: '(' (0@0-9)
782 sending: 'x' (1@10-19)
783 thing (1@10-19): 'x' (1@10-19)
784 sending: 'x' (2@20-29)
785 thing (2@20-29): 'x' (2@20-29)
786 sending: 'x' (3@30-39)
787 30.30-39.38: syntax error, unexpected 'x', expecting ')'
788 Freeing nterm thing (2@20-29)
789 Freeing nterm thing (1@10-19)
790 Freeing token 'x' (3@30-39)
791 sending: 'x' (4@40-49)
792 Freeing token 'x' (4@40-49)
793 sending: 'x' (5@50-59)
794 Freeing token 'x' (5@50-59)
795 sending: ')' (6@60-69)
796 line (-1@0-69): '(' (0@0-9) error (@10-59) ')' (6@60-69)
797 sending: '(' (7@70-79)
798 sending: 'x' (8@80-89)
799 thing (8@80-89): 'x' (8@80-89)
800 sending: ')' (9@90-99)
801 line (7@70-99): '(' (7@70-79) thing (8@80-89) ')' (9@90-99)
802 sending: '(' (10@100-109)
803 sending: 'x' (11@110-119)
804 thing (11@110-119): 'x' (11@110-119)
805 sending: ')' (12@120-129)
806 line (10@100-129): '(' (10@100-109) thing (11@110-119) ')' (12@120-129)
807 sending: 'y' (13@130-139)
808 input (0@129-129): /* Nothing */
809 input (2@100-129): line (10@100-129) input (0@129-129)
810 input (2@70-129): line (7@70-99) input (2@100-129)
811 input (2@0-129): line (-1@0-69) input (2@70-129)
812 130.130-139.138: syntax error, unexpected 'y', expecting END
813 Freeing nterm input (2@0-129)
814 Freeing token 'y' (13@130-139)
819 # Syntax error caught by the parser where lookahead = END
820 # --------------------------------------------------------
821 # Load the stack and provoke an error that cannot be caught by the
822 # grammar, to check that the stack is cleared. And make sure the
823 # lookahead is freed.
828 AT_PARSER_CHECK([./input '(x)(x)x'], 1, [],
829 [[sending: '(' (0@0-9)
830 sending: 'x' (1@10-19)
831 thing (1@10-19): 'x' (1@10-19)
832 sending: ')' (2@20-29)
833 line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
834 sending: '(' (3@30-39)
835 sending: 'x' (4@40-49)
836 thing (4@40-49): 'x' (4@40-49)
837 sending: ')' (5@50-59)
838 line (3@30-59): '(' (3@30-39) thing (4@40-49) ')' (5@50-59)
839 sending: 'x' (6@60-69)
840 thing (6@60-69): 'x' (6@60-69)
841 sending: END (7@70-79)
842 70.70-79.78: syntax error, unexpected END, expecting 'x'
843 Freeing nterm thing (6@60-69)
844 Freeing nterm line (3@30-59)
845 Freeing nterm line (0@0-29)
846 Freeing token END (7@70-79)
851 # Check destruction upon stack overflow
852 # -------------------------------------
853 # Upon stack overflow, all symbols on the stack should be destroyed.
854 # Only check for yacc.c.
856 AT_PARSER_CHECK([./input '(x)(x)(x)(x)(x)(x)(x)'], 2, [],
857 [[sending: '(' (0@0-9)
858 sending: 'x' (1@10-19)
859 thing (1@10-19): 'x' (1@10-19)
860 sending: ')' (2@20-29)
861 line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29)
862 sending: '(' (3@30-39)
863 sending: 'x' (4@40-49)
864 thing (4@40-49): 'x' (4@40-49)
865 sending: ')' (5@50-59)
866 line (3@30-59): '(' (3@30-39) thing (4@40-49) ')' (5@50-59)
867 sending: '(' (6@60-69)
868 sending: 'x' (7@70-79)
869 thing (7@70-79): 'x' (7@70-79)
870 sending: ')' (8@80-89)
871 line (6@60-89): '(' (6@60-69) thing (7@70-79) ')' (8@80-89)
872 sending: '(' (9@90-99)
873 sending: 'x' (10@100-109)
874 thing (10@100-109): 'x' (10@100-109)
875 sending: ')' (11@110-119)
876 line (9@90-119): '(' (9@90-99) thing (10@100-109) ')' (11@110-119)
877 sending: '(' (12@120-129)
878 sending: 'x' (13@130-139)
879 thing (13@130-139): 'x' (13@130-139)
880 sending: ')' (14@140-149)
881 line (12@120-149): '(' (12@120-129) thing (13@130-139) ')' (14@140-149)
882 sending: '(' (15@150-159)
883 sending: 'x' (16@160-169)
884 thing (16@160-169): 'x' (16@160-169)
885 sending: ')' (17@170-179)
886 line (15@150-179): '(' (15@150-159) thing (16@160-169) ')' (17@170-179)
887 sending: '(' (18@180-189)
888 sending: 'x' (19@190-199)
889 thing (19@190-199): 'x' (19@190-199)
890 sending: ')' (20@200-209)
891 200.200-209.208: memory exhausted
892 Freeing nterm thing (19@190-199)
893 Freeing nterm line (15@150-179)
894 Freeing nterm line (12@120-149)
895 Freeing nterm line (9@90-119)
896 Freeing nterm line (6@60-89)
897 Freeing nterm line (3@30-59)
898 Freeing nterm line (0@0-29)
899 Parsing FAILED (status 2).
903 AT_BISON_OPTION_POPDEFS
904 ])# _AT_CHECK_PRINTER_AND_DESTRUCTOR
907 # AT_CHECK_PRINTER_AND_DESTRUCTOR([BISON-OPTIONS], [UNION-FLAG], [SKIP_FLAG])
908 # ---------------------------------------------------------------------------
909 m4_define([AT_CHECK_PRINTER_AND_DESTRUCTOR],
910 [AT_SETUP([Printers and Destructors$2]m4_ifval([$1], [[: $1]]))
913 _AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4],
914 [%define parse.error verbose
924 AT_CHECK_PRINTER_AND_DESTRUCTOR([])
925 AT_CHECK_PRINTER_AND_DESTRUCTOR([], [ with union])
927 AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
928 AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [ with union])
930 AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
931 AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
935 ## ----------------------------------------- ##
936 ## Default tagless %printer and %destructor. ##
937 ## ----------------------------------------- ##
939 # Check that the right %printer and %destructor are called, that they're not
940 # called for $end, and that $$ and @$ work correctly.
942 AT_SETUP([Default tagless %printer and %destructor])
943 AT_BISON_OPTION_PUSHDEFS([%locations %debug])
944 AT_DATA_GRAMMAR([[input.y]],
945 [[%define parse.error verbose
956 fprintf (yyoutput, "<*> printer should not be called.\n");
960 fprintf (yyoutput, "<> printer for '%c' @ %d", $$, @$.first_column);
963 fprintf (stdout, "<> destructor for '%c' @ %d.\n", $$, @$.first_column);
967 fprintf (yyoutput, "'b'/'c' printer for '%c' @ %d", $$, @$.first_column);
970 fprintf (stdout, "'b'/'c' destructor for '%c' @ %d.\n", $$, @$.first_column);
974 fprintf (yyoutput, "<*> destructor should not be called.\n");
979 start: 'a' 'b' 'c' 'd' 'e' { $$ = 'S'; USE(($1, $2, $3, $4, $5)); } ;
983 ]AT_YYLEX_DEFINE(["abcd"], [[yylval = res]])[
987 AT_BISON_CHECK([-o input.c input.y], [], [],
988 [[input.y:30.3-5: warning: useless %destructor for type <*> [-Wother]
989 input.y:30.3-5: warning: useless %printer for type <*> [-Wother]
992 AT_PARSER_CHECK([./input --debug], 1,
993 [[<> destructor for 'd' @ 4.
994 'b'/'c' destructor for 'c' @ 3.
995 'b'/'c' destructor for 'b' @ 2.
996 <> destructor for 'a' @ 1.
1000 Reading a token: Next token is token 'a' (1.1: <> printer for 'a' @ 1)
1001 Shifting token 'a' (1.1: <> printer for 'a' @ 1)
1003 Reading a token: Next token is token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
1004 Shifting token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
1006 Reading a token: Next token is token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
1007 Shifting token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
1009 Reading a token: Next token is token 'd' (1.4: <> printer for 'd' @ 4)
1010 Shifting token 'd' (1.4: <> printer for 'd' @ 4)
1012 Reading a token: Now at end of input.
1013 1.5: syntax error, unexpected $end, expecting 'e'
1014 Error: popping token 'd' (1.4: <> printer for 'd' @ 4)
1016 Error: popping token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
1018 Error: popping token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
1020 Error: popping token 'a' (1.1: <> printer for 'a' @ 1)
1022 Cleanup: discarding lookahead token $end (1.5: )
1026 AT_BISON_OPTION_POPDEFS
1031 ## ------------------------------------------------------ ##
1032 ## Default tagged and per-type %printer and %destructor. ##
1033 ## ------------------------------------------------------ ##
1035 AT_SETUP([Default tagged and per-type %printer and %destructor])
1036 AT_BISON_OPTION_PUSHDEFS([%debug])
1037 AT_DATA_GRAMMAR([[input.y]],
1038 [[%define parse.error verbose
1042 ]AT_YYERROR_DECLARE[
1048 fprintf (yyoutput, "<> printer should not be called.\n");
1051 %union { int field0; int field1; int field2; }
1052 %type <field0> start 'a' 'g'
1056 fprintf (yyoutput, "<*>/<field2>/e printer");
1059 fprintf (stdout, "<*>/<field2>/e destructor.\n");
1063 %printer { fprintf (yyoutput, "<field1> printer"); } <field1>
1064 %destructor { fprintf (stdout, "<field1> destructor.\n"); } <field1>
1067 %printer { fprintf (yyoutput, "'c' printer"); } 'c'
1068 %destructor { fprintf (stdout, "'c' destructor.\n"); } 'c'
1071 %printer { fprintf (yyoutput, "'d' printer"); } 'd'
1072 %destructor { fprintf (stdout, "'d' destructor.\n"); } 'd'
1075 fprintf (yyoutput, "<> destructor should not be called.\n");
1081 'a' 'b' 'c' 'd' 'e' 'f' 'g'
1083 USE(($1, $2, $3, $4, $5, $6, $7));
1090 ]AT_YYLEX_DEFINE(["abcdef"])[
1094 AT_BISON_CHECK([-o input.c input.y], [], [],
1095 [[input.y:22.3-4: warning: useless %destructor for type <> [-Wother]
1096 input.y:22.3-4: warning: useless %printer for type <> [-Wother]
1099 AT_PARSER_CHECK([./input --debug], 1,
1100 [[<*>/<field2>/e destructor.
1101 <*>/<field2>/e destructor.
1104 <field1> destructor.
1105 <*>/<field2>/e destructor.
1109 Reading a token: Next token is token 'a' (<*>/<field2>/e printer)
1110 Shifting token 'a' (<*>/<field2>/e printer)
1112 Reading a token: Next token is token 'b' (<field1> printer)
1113 Shifting token 'b' (<field1> printer)
1115 Reading a token: Next token is token 'c' ('c' printer)
1116 Shifting token 'c' ('c' printer)
1118 Reading a token: Next token is token 'd' ('d' printer)
1119 Shifting token 'd' ('d' printer)
1121 Reading a token: Next token is token 'e' (<*>/<field2>/e printer)
1122 Shifting token 'e' (<*>/<field2>/e printer)
1124 Reading a token: Next token is token 'f' (<*>/<field2>/e printer)
1125 Shifting token 'f' (<*>/<field2>/e printer)
1127 Reading a token: Now at end of input.
1128 syntax error, unexpected $end, expecting 'g'
1129 Error: popping token 'f' (<*>/<field2>/e printer)
1130 Stack now 0 1 3 5 6 7
1131 Error: popping token 'e' (<*>/<field2>/e printer)
1133 Error: popping token 'd' ('d' printer)
1135 Error: popping token 'c' ('c' printer)
1137 Error: popping token 'b' (<field1> printer)
1139 Error: popping token 'a' (<*>/<field2>/e printer)
1141 Cleanup: discarding lookahead token $end ()
1145 AT_BISON_OPTION_POPDEFS
1150 ## ------------------------------------------------------------- ##
1151 ## Default %printer and %destructor for user-defined end token. ##
1152 ## ------------------------------------------------------------- ##
1154 AT_SETUP([Default %printer and %destructor for user-defined end token])
1158 m4_pushdef([AT_TEST],
1160 [m4_pushdef([kind], []) m4_pushdef([not_kind], [*])],
1161 [m4_pushdef([kind], [*]) m4_pushdef([not_kind], [])])
1163 AT_BISON_OPTION_PUSHDEFS([%locations %debug])
1164 AT_DATA_GRAMMAR([[input]]$1[[.y]],
1165 [[%define parse.error verbose
1170 ]AT_YYERROR_DECLARE[
1176 fprintf (yyoutput, "<]]not_kind[[> destructor should not be called.\n");
1181 fprintf (yyoutput, "<]]kind[[> for '%c' @ %d", $$, @$.first_column);
1184 fprintf (stdout, "<]]kind[[> for '%c' @ %d.\n", $$, @$.first_column);
1188 fprintf (yyoutput, "<]]not_kind[[> printer should not be called.\n");
1193 [[[%union { char tag; }
1194 %type <tag> start END]]])[[
1198 start: { $$ = 'S'; } ;
1201 #include <stdlib.h> /* abort */
1208 yylval]]m4_if($1, 0,, [[[.tag]]])[[ = 'E';
1209 yylloc.first_line = yylloc.last_line = 1;
1210 yylloc.first_column = yylloc.last_column = 1;
1216 AT_BISON_OPTION_POPDEFS
1218 AT_BISON_CHECK([-o input$1.c input$1.y], [], [],
1220 [[input0.y:30.3-5: warning: useless %destructor for type <*> [-Wother]
1221 input0.y:30.3-5: warning: useless %printer for type <*> [-Wother]
1223 [[input1.y:30.3-4: warning: useless %destructor for type <> [-Wother]
1224 input1.y:30.3-4: warning: useless %printer for type <> [-Wother]
1227 AT_COMPILE([input$1])
1229 AT_PARSER_CHECK([./input$1 --debug], 0,
1230 [[<]]kind[[> for 'E' @ 1.
1231 <]]kind[[> for 'S' @ 1.
1235 Reducing stack by rule 1 (line 49):
1236 -> $$ = nterm start (1.1: <]]kind[[> for 'S' @ 1)
1239 Reading a token: Now at end of input.
1240 Shifting token END (1.1: <]]kind[[> for 'E' @ 1)
1243 Cleanup: popping token END (1.1: <]]kind[[> for 'E' @ 1)
1244 Cleanup: popping nterm start (1.1: <]]kind[[> for 'S' @ 1)
1248 m4_popdef([not_kind])
1254 m4_popdef([AT_TEST])
1260 ## ------------------------------------------------------------------ ##
1261 ## Default %printer and %destructor are not for error or $undefined. ##
1262 ## ------------------------------------------------------------------ ##
1264 AT_SETUP([Default %printer and %destructor are not for error or $undefined])
1266 # If Bison were to apply the default %printer and %destructor to the error
1267 # token or to $undefined:
1268 # - For the error token:
1269 # - It would generate warnings for unused $n.
1270 # - It would invoke the %printer and %destructor on the error token's
1271 # semantic value, which would be initialized from the lookahead, which
1272 # would be destroyed separately.
1273 # - For $undefined, who knows what the semantic value would be.
1274 AT_BISON_OPTION_PUSHDEFS([%debug])
1275 AT_DATA_GRAMMAR([[input.y]],
1280 # include <stdlib.h>
1281 ]AT_YYERROR_DECLARE[
1287 fprintf (yyoutput, "'%c'", $$);
1290 fprintf (stderr, "DESTROY '%c'\n", $$);
1297 /* In order to reveal the problems that this bug caused during parsing, add
1299 | 'a' error 'b' 'c' { USE(($1, $3, $4)); $$ = 'S'; }
1304 ]AT_YYLEX_DEFINE(["abd"], [yylval = res])[
1307 AT_BISON_OPTION_POPDEFS
1309 AT_BISON_CHECK([-o input.c input.y], [], [],
1310 [[input.y:23.6-8: warning: useless %destructor for type <*> [-Wother]
1311 input.y:23.6-8: warning: useless %printer for type <*> [-Wother]
1314 AT_PARSER_CHECK([./input --debug], [1], [],
1317 Reading a token: Next token is token 'a' ('a')
1318 Shifting token 'a' ('a')
1320 Reading a token: Next token is token 'b' ('b')
1322 Shifting token error ()
1324 Next token is token 'b' ('b')
1325 Shifting token 'b' ('b')
1327 Reading a token: Next token is token $undefined ()
1328 Error: popping token 'b' ('b')
1331 Error: popping token error ()
1333 Shifting token error ()
1335 Next token is token $undefined ()
1336 Error: discarding token $undefined ()
1337 Error: popping token error ()
1339 Shifting token error ()
1341 Reading a token: Now at end of input.
1342 Cleanup: discarding lookahead token $end ()
1344 Cleanup: popping token error ()
1345 Cleanup: popping token 'a' ('a')
1353 ## ------------------------------------------------------ ##
1354 ## Default %printer and %destructor are not for $accept. ##
1355 ## ------------------------------------------------------ ##
1357 AT_SETUP([Default %printer and %destructor are not for $accept])
1359 # If YYSTYPE is a union and Bison were to apply the default %printer and
1360 # %destructor to $accept:
1361 # - The %printer and %destructor code generated for $accept would always be
1362 # dead code because $accept is currently never shifted onto the stack.
1363 # - $$ for $accept would always be of type YYSTYPE because it's not possible
1364 # to declare '%type <field> $accept'. (Also true for $undefined.)
1365 # - Thus, the compiler might complain that the user code assumes the wrong
1366 # type for $$ since the code might assume the type associated with a
1367 # specific union field, which is especially reasonable in C++ since that
1368 # type may be a base type. This test case checks for this problem. (Also
1369 # true for $undefined and the error token, so there are three warnings for
1370 # %printer and three for %destructor.)
1372 AT_BISON_OPTION_PUSHDEFS([%debug])
1373 AT_DATA_GRAMMAR([[input.y]],
1374 [[%debug /* So that %printer is actually compiled. */
1378 # include <stdlib.h>
1379 ]AT_YYERROR_DECLARE[
1386 fprintf (yyoutput, "'%c'", chr);
1390 fprintf (stderr, "DESTROY '%c'\n", chr);
1393 %union { char chr; }
1398 start: { USE($$); } ;
1405 AT_BISON_OPTION_POPDEFS
1407 AT_BISON_CHECK([-o input.c input.y], [], [],
1408 [[input.y:24.3-4: warning: useless %destructor for type <> [-Wother]
1409 input.y:24.3-4: warning: useless %printer for type <> [-Wother]
1417 ## ------------------------------------------------------ ##
1418 ## Default %printer and %destructor for mid-rule values. ##
1419 ## ------------------------------------------------------ ##
1421 AT_SETUP([Default %printer and %destructor for mid-rule values])
1423 AT_BISON_OPTION_PUSHDEFS([%debug])
1424 AT_DATA_GRAMMAR([[input.y]],
1425 [[%debug /* So that %printer is actually compiled. */
1428 ]AT_YYERROR_DECLARE[
1431 # define YYLTYPE int
1432 # define YYLLOC_DEFAULT(Current, Rhs, N) (void)(Rhs)
1433 # define LOCATION_PRINT(File, Loc)
1436 %printer { fprintf (yyoutput, "%d", @$); } <>
1437 %destructor { fprintf (stderr, "DESTROY %d\n", @$); } <>
1438 %printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
1439 %destructor { fprintf (yyoutput, "<*> destructor should not be called"); } <*>
1444 { @$ = 1; } // Not set or used.
1445 { USE ($$); @$ = 2; } // Both set and used.
1446 { USE ($$); @$ = 3; } // Only set.
1447 { @$ = 4; } // Only used.
1449 { USE (($$, $2, $4, $5)); @$ = 0; }
1457 AT_BISON_OPTION_POPDEFS
1459 AT_BISON_CHECK([-o input.c input.y], 0,,
1460 [[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
1461 input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
1462 input.y:33.3-23: warning: unset value: $$ [-Wother]
1463 input.y:32.3-23: warning: unused value: $3 [-Wother]
1466 AT_BISON_CHECK([-fcaret -o input.c input.y], 0,,
1467 [[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
1468 %printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
1470 input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
1471 %printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
1473 input.y:33.3-23: warning: unset value: $$ [-Wother]
1474 { @$ = 4; } // Only used.
1475 ^^^^^^^^^^^^^^^^^^^^^
1476 input.y:32.3-23: warning: unused value: $3 [-Wother]
1477 { USE ($$); @$ = 3; } // Only set.
1478 ^^^^^^^^^^^^^^^^^^^^^
1482 AT_PARSER_CHECK([./input --debug], 1,,
1485 Reducing stack by rule 1 (line 30):
1486 -> $$ = nterm $@1 (: )
1489 Reducing stack by rule 2 (line 31):
1490 -> $$ = nterm @2 (: 2)
1493 Reducing stack by rule 3 (line 32):
1494 -> $$ = nterm @3 (: 3)
1497 Reducing stack by rule 4 (line 33):
1498 -> $$ = nterm @4 (: 4)
1501 Reading a token: Now at end of input.
1503 Error: popping nterm @4 (: 4)
1506 Error: popping nterm @3 (: 3)
1509 Error: popping nterm @2 (: 2)
1512 Error: popping nterm $@1 (: )
1514 Cleanup: discarding lookahead token $end (: )
1521 ## ----------------------- ##
1522 ## @$ implies %locations. ##
1523 ## ----------------------- ##
1525 # Bison once forgot to check for @$ in actions other than semantic actions.
1527 # AT_CHECK_ACTION_LOCATIONS(ACTION-DIRECTIVE)
1528 # -------------------------------------------
1529 m4_define([AT_CHECK_ACTION_LOCATIONS],
1530 [AT_SETUP([[@$ in ]$1[ implies %locations]])
1531 AT_BISON_OPTION_PUSHDEFS([%debug])
1532 AT_DATA_GRAMMAR([[input.y]],
1535 ]AT_YYERROR_DECLARE[
1542 fprintf (stderr, "%d\n", @$.first_line);
1543 } ]m4_if($1, [%initial-action], [], [[start]])[
1561 AT_BISON_CHECK([[-o input.c input.y]])
1562 AT_COMPILE([[input]])
1563 AT_BISON_OPTION_POPDEFS
1566 AT_CHECK_ACTION_LOCATIONS([[%initial-action]])
1567 AT_CHECK_ACTION_LOCATIONS([[%destructor]])
1568 AT_CHECK_ACTION_LOCATIONS([[%printer]])
1571 ## ------------------------- ##
1572 ## Qualified $$ in actions. ##
1573 ## ------------------------- ##
1575 # Check that we can use qualified $$ (v.g., $<type>$) not only in rule
1576 # actions, but also where $$ is valid: %destructor/%printer and
1579 # FIXME: Not actually checking %destructor, but it's the same code as
1582 # To do that, use a semantic value that has two fields (sem_type),
1583 # declare symbols to have only one of these types (INT, float), and
1584 # use $<type>$ to get the other one. Including for symbols that are
1585 # not typed (UNTYPED).
1587 m4_pushdef([AT_TEST],
1588 [AT_SETUP([[Qualified $$ in actions: $1]])
1590 AT_BISON_OPTION_PUSHDEFS([%skeleton "$1" %debug])
1592 AT_DATA_GRAMMAR([[input.y]],
1597 typedef struct sem_type
1603 # define YYSTYPE sem_type
1606 # include <iostream>
1610 report (std::ostream& yyo, int ival, float fval)
1612 yyo << "ival: " << ival << ", fval: " << fval;
1618 report (FILE* yyo, int ival, float fval)
1620 fprintf (yyo, "ival: %d, fval: %1.1f", ival, fval);
1627 ]AT_YYERROR_DECLARE[
1634 %printer { report (yyo, $$, $<fval>$); } <ival>;
1635 %printer { report (yyo, $<ival>$, $$ ); } <fval>;
1636 %printer { report (yyo, $<ival>$, $<fval>$); } <>;
1647 $$ = $<fval>1 + $<fval>2;
1648 $<ival>$ = $<ival>1 + $][2;
1652 ]AT_YYLEX_DEFINE(AT_SKEL_CC_IF([[{yy::parser::token::UNTYPED,
1653 yy::parser::token::INT,
1655 [[{UNTYPED, INT, EOF}]]),
1656 [AT_VAL.ival = toknum * 10; AT_VAL.fval = toknum / 10.0;])[
1660 AT_FULL_COMPILE([[input]])
1661 AT_PARSER_CHECK([./input --debug], 0, [], [stderr])
1662 # Don't be too picky on the traces, GLR is not exactly the same. Keep
1663 # only the lines from the printer.
1664 AT_CHECK([[sed -ne '/ival:/p' stderr]], 0,
1665 [[Reading a token: Next token is token UNTYPED (ival: 10, fval: 0.1)
1666 Shifting token UNTYPED (ival: 10, fval: 0.1)
1667 Reading a token: Next token is token INT (ival: 20, fval: 0.2)
1668 Shifting token INT (ival: 20, fval: 0.2)
1669 $][1 = token UNTYPED (ival: 10, fval: 0.1)
1670 $][2 = token INT (ival: 20, fval: 0.2)
1671 -> $$ = nterm float (ival: 30, fval: 0.3)
1672 Cleanup: popping nterm float (ival: 30, fval: 0.3)
1675 AT_BISON_OPTION_POPDEFS
1685 m4_popdef([AT_TEST])
1687 ## -------------------------------------------------- ##
1688 ## Destroying lookahead assigned by semantic action. ##
1689 ## -------------------------------------------------- ##
1691 AT_SETUP([[Destroying lookahead assigned by semantic action]])
1693 AT_BISON_OPTION_PUSHDEFS
1694 AT_DATA_GRAMMAR([input.y],
1699 ]AT_YYERROR_DECLARE[
1704 %destructor { fprintf (stderr, "'a' destructor\n"); } 'a'
1705 %destructor { fprintf (stderr, "'b' destructor\n"); } 'b'
1709 // In a previous version of Bison, yychar assigned by the semantic
1710 // action below was not translated into yytoken before the lookahead was
1711 // discarded and thus before its destructor (selected according to
1712 // yytoken) was called in order to return from yyparse. This would
1713 // happen even if YYACCEPT was performed in a later semantic action as
1714 // long as only consistent states with default reductions were visited
1715 // in between. However, we leave YYACCEPT in the same semantic action
1716 // for this test in order to show that skeletons cannot simply translate
1717 // immediately after every semantic action because a semantic action
1718 // that has set yychar might not always return normally. Instead,
1719 // skeletons must translate before every use of yytoken.
1720 start: 'a' accept { USE($1); } ;
1722 assert (yychar == YYEMPTY);
1729 ]AT_YYLEX_DEFINE(["a"])[
1732 AT_BISON_OPTION_POPDEFS
1733 AT_BISON_CHECK([[-o input.c input.y]])
1734 AT_COMPILE([[input]])
1735 AT_PARSER_CHECK([[./input]], [[0]], [],
1746 AT_SETUP([[YYBACKUP]])
1748 AT_BISON_OPTION_PUSHDEFS([%pure-parser %debug])
1750 AT_DATA_GRAMMAR([input.y],
1757 # include <stdlib.h>
1758 # include <assert.h>
1760 ]AT_YYERROR_DECLARE[
1769 'a' { printf ("a: %d\n", $1); }
1770 | 'b' { YYBACKUP('a', 123); }
1771 | 'c' 'd' { YYBACKUP('a', 456); }
1776 ]AT_YYLEX_DEFINE(["bcd"], [*lvalp = (toknum + 1) * 10])[
1779 AT_BISON_OPTION_POPDEFS
1781 AT_BISON_CHECK([[-o input.c input.y]])
1782 AT_COMPILE([[input]])
1783 AT_PARSER_CHECK([[./input]], [[0]],