1 # Bison Regressions. -*- Autotest -*-
3 # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 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 2, or (at your option)
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, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 AT_BANNER([[Regression tests.]])
24 ## ------------------ ##
25 ## Trivial grammars. ##
26 ## ------------------ ##
28 AT_SETUP([Trivial grammars])
30 AT_DATA_GRAMMAR([input.y],
32 void yyerror (char const *);
44 AT_CHECK([bison -o input.c input.y])
45 AT_COMPILE([input.o], [-c input.c])
46 AT_COMPILE([input.o], [-DYYDEBUG -c input.c])
52 ## ------------------------------------- ##
53 ## Early token definitions with --yacc. ##
54 ## ------------------------------------- ##
57 AT_SETUP([Early token definitions with --yacc])
59 # Found in GCJ: they expect the tokens to be defined before the user
60 # prologue, so that they can use the token definitions in it.
62 AT_DATA_GRAMMAR([input.y],
64 void yyerror (const char *s);
67 # error "MY_TOKEN not defined."
81 AT_CHECK([bison -y -o input.c input.y])
82 AT_COMPILE([input.o], [-c input.c])
88 ## ---------------------------------------- ##
89 ## Early token definitions without --yacc. ##
90 ## ---------------------------------------- ##
93 AT_SETUP([Early token definitions without --yacc])
95 # Found in GCJ: they expect the tokens to be defined before the user
96 # prologue, so that they can use the token definitions in it.
98 AT_DATA_GRAMMAR([input.y],
101 void yyerror (const char *s);
103 void print_my_token (void);
105 print_my_token (void)
107 enum yytokentype my_token = MY_TOKEN;
108 printf ("%d\n", my_token);
122 AT_CHECK([bison -o input.c input.y])
123 AT_COMPILE([input.o], [-c input.c])
129 ## ---------------- ##
130 ## Braces parsing. ##
131 ## ---------------- ##
134 AT_SETUP([Braces parsing])
137 [[/* Bison used to swallow the character after `}'. */
140 exp: { tests = {{{{{{{{{{}}}}}}}}}}; };
144 AT_CHECK([bison -v -o input.c input.y])
146 AT_CHECK([grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c], 0, [ignore])
151 ## ------------------ ##
152 ## Duplicate string. ##
153 ## ------------------ ##
156 AT_SETUP([Duplicate string])
159 [[/* `Bison -v' used to dump core when two tokens are defined with the same
160 string, as LE and GE below. */
167 exp: '(' exp ')' | NUM ;
171 AT_CHECK([bison -v -o input.c input.y], 0, [],
172 [[input.y:6.8-14: warning: symbol `"<="' used more than once as a literal string
178 ## ------------------- ##
179 ## Rule Line Numbers. ##
180 ## ------------------- ##
182 AT_SETUP([Rule Line Numbers])
184 AT_KEYWORDS([report])
216 AT_CHECK([bison -o input.c -v input.y])
218 # Check the contents of the report.
219 AT_CHECK([cat input.output], [],
233 Terminals, with rules where they appear
242 Nonterminals, with rules where they appear
247 on left: 2 4, on right: 0
249 on left: 1, on right: 2
251 on left: 3, on right: 4
256 0 $accept: . expr $end
258 'a' shift, and go to state 1
260 $default reduce using rule 3 (@2)
270 $default reduce using rule 1 (@1)
277 0 $accept: expr . $end
279 $end shift, and go to state 5
286 'c' shift, and go to state 6
293 'b' shift, and go to state 7
298 0 $accept: expr $end .
307 $default reduce using rule 4 (expr)
314 $default reduce using rule 2 (expr)
321 ## ---------------------- ##
322 ## Mixing %token styles. ##
323 ## ---------------------- ##
326 AT_SETUP([Mixing %token styles])
328 # Taken from the documentation.
330 [[%token <operator> OR "||"
331 %token <operator> LE 134 "<="
338 AT_CHECK([bison -v -o input.c input.y])
344 ## ---------------- ##
345 ## Invalid inputs. ##
346 ## ---------------- ##
349 AT_SETUP([Invalid inputs])
361 AT_CHECK([bison input.y], [1], [],
362 [[input.y:2.1: invalid character: `?'
363 input.y:3.14: invalid character: `}'
364 input.y:4.1: invalid character: `%'
365 input.y:4.2: invalid character: `&'
366 input.y:5.1-17: invalid directive: `%a-does-not-exist'
367 input.y:6.1: invalid character: `%'
368 input.y:6.2: invalid character: `-'
369 input.y:7.1-8.0: missing `%}' at end of file
375 AT_SETUP([Invalid inputs with {}])
387 AT_CHECK([bison input.y], [1], [],
388 [[input.y:3.1-15: syntax error, unexpected %initial-action, expecting {...}
395 ## ------------------- ##
396 ## Token definitions. ##
397 ## ------------------- ##
400 AT_SETUP([Token definitions])
402 # Bison managed, when fed with `%token 'f' "f"' to #define 'f'!
403 AT_DATA_GRAMMAR([input.y],
406 void yyerror (const char *s);
410 %token MYEOF 0 "end of file"
415 %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
417 exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!";
420 yyerror (char const *s)
422 fprintf (stderr, "%s\n", s);
438 AT_CHECK([bison -o input.c input.y])
441 [[syntax error, unexpected "\\'?\"\a\b\f\n\r\t\v\001\201\001\201?\?!", expecting a
443 AT_PARSER_CHECK([./input], 1, [], [experr])
448 ## -------------------- ##
449 ## Characters Escapes. ##
450 ## -------------------- ##
453 AT_SETUP([Characters Escapes])
455 AT_DATA_GRAMMAR([input.y],
457 void yyerror (const char *s);
467 # Pacify font-lock-mode: "
469 AT_CHECK([bison -o input.c input.y])
470 AT_COMPILE([input.o], [-c input.c])
479 # The generation of the reduction was once wrong in Bison, and made it
480 # miss some reductions. In the following test case, the reduction on
481 # `undef_id_tok' in state 1 was missing. This is stripped down from
482 # the actual web2c.y.
484 AT_SETUP([Web2c Report])
486 AT_KEYWORDS([report])
489 [[%token undef_id_tok const_id_tok
491 %start CONST_DEC_PART
500 | CONST_DEC_LIST CONST_DEC
504 { } undef_id_tok '=' const_id_tok ';'
509 AT_CHECK([bison -v input.y])
510 AT_CHECK([cat input.output], 0,
513 0 $accept: CONST_DEC_PART $end
515 1 CONST_DEC_PART: CONST_DEC_LIST
517 2 CONST_DEC_LIST: CONST_DEC
518 3 | CONST_DEC_LIST CONST_DEC
522 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';'
525 Terminals, with rules where they appear
535 Nonterminals, with rules where they appear
540 on left: 1, on right: 0
542 on left: 2 3, on right: 1 3
544 on left: 5, on right: 2 3
546 on left: 4, on right: 5
551 0 $accept: . CONST_DEC_PART $end
553 $default reduce using rule 4 (@1)
555 CONST_DEC_PART go to state 1
556 CONST_DEC_LIST go to state 2
557 CONST_DEC go to state 3
563 0 $accept: CONST_DEC_PART . $end
565 $end shift, and go to state 5
570 1 CONST_DEC_PART: CONST_DEC_LIST .
571 3 CONST_DEC_LIST: CONST_DEC_LIST . CONST_DEC
573 undef_id_tok reduce using rule 4 (@1)
574 $default reduce using rule 1 (CONST_DEC_PART)
576 CONST_DEC go to state 6
582 2 CONST_DEC_LIST: CONST_DEC .
584 $default reduce using rule 2 (CONST_DEC_LIST)
589 5 CONST_DEC: @1 . undef_id_tok '=' const_id_tok ';'
591 undef_id_tok shift, and go to state 7
596 0 $accept: CONST_DEC_PART $end .
603 3 CONST_DEC_LIST: CONST_DEC_LIST CONST_DEC .
605 $default reduce using rule 3 (CONST_DEC_LIST)
610 5 CONST_DEC: @1 undef_id_tok . '=' const_id_tok ';'
612 '=' shift, and go to state 8
617 5 CONST_DEC: @1 undef_id_tok '=' . const_id_tok ';'
619 const_id_tok shift, and go to state 9
624 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok . ';'
626 ';' shift, and go to state 10
631 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';' .
633 $default reduce using rule 5 (CONST_DEC)
639 ## --------------- ##
641 ## --------------- ##
643 # The generation of the mapping `state -> action' was once wrong in
644 # extremely specific situations. web2c.y exhibits this situation.
645 # Below is a stripped version of the grammar. It looks like one can
646 # simplify it further, but just don't: it is tuned to exhibit a bug,
647 # which disapears when applying sane grammar transformations.
649 # It used to be wrong on yydefact only:
651 # static const yytype_uint8 yydefact[] =
653 # - 2, 0, 1, 0, 0, 2, 3, 2, 5, 4,
654 # + 2, 0, 1, 0, 0, 0, 3, 2, 5, 4,
658 # but let's check all the tables.
661 AT_SETUP([Web2c Actions])
663 AT_KEYWORDS([report])
667 statement: struct_stat;
668 struct_stat: /* empty. */ | if else;
669 if: "if" "const" "then" statement;
670 else: "else" statement;
674 AT_CHECK([bison -v -o input.c input.y])
676 # Check only the tables. We don't use --no-parser, because it is
677 # still to be implemented in the experimental branch of Bison.
678 [sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c >tables.c]
680 AT_CHECK([[cat tables.c]], 0,
681 [[static const yytype_uint8 yytranslate[] =
683 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
684 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
685 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
686 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
687 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
688 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
689 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
690 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
691 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
692 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
693 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
694 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
695 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
696 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
697 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
698 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
699 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
700 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
701 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
702 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
703 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
704 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
705 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
706 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
707 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
708 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
711 static const yytype_uint8 yyprhs[] =
715 static const yytype_int8 yyrhs[] =
717 8, 0, -1, 9, -1, -1, 10, 11, -1, 3,
718 4, 5, 8, -1, 6, 8, -1
720 static const yytype_uint8 yyrline[] =
724 static const char *const yytname[] =
726 "$end", "error", "$undefined", "\"if\"", "\"const\"", "\"then\"",
727 "\"else\"", "$accept", "statement", "struct_stat", "if", "else", 0
729 static const yytype_uint16 yytoknum[] =
731 0, 256, 257, 258, 259, 260, 261
733 static const yytype_uint8 yyr1[] =
735 0, 7, 8, 9, 9, 10, 11
737 static const yytype_uint8 yyr2[] =
741 static const yytype_uint8 yydefact[] =
743 3, 0, 0, 2, 0, 0, 1, 3, 4, 3,
746 static const yytype_int8 yydefgoto[] =
750 static const yytype_int8 yypact[] =
752 -2, -1, 4, -8, 0, 2, -8, -2, -8, -2,
755 static const yytype_int8 yypgoto[] =
759 static const yytype_uint8 yytable[] =
761 10, 1, 11, 5, 6, 0, 7, 9
763 static const yytype_int8 yycheck[] =
765 7, 3, 9, 4, 0, -1, 6, 5
767 static const yytype_uint8 yystos[] =
769 0, 3, 8, 9, 10, 4, 0, 6, 11, 5,
777 ## ------------------------- ##
778 ## yycheck Bound Violation. ##
779 ## ------------------------- ##
782 # _AT_DATA_DANCER_Y(BISON-OPTIONS)
783 # --------------------------------
784 # The following grammar, taken from Andrew Suffield's GPL'd implementation
785 # of DGMTP, the Dancer Generic Message Transport Protocol, used to violate
786 # yycheck's bounds where issuing a verbose error message. Keep this test
787 # so that possible bound checking compilers could check all the skeletons.
788 m4_define([_AT_DATA_DANCER_Y],
789 [AT_DATA_GRAMMAR([dancer.y],
791 static int yylex (AT_LALR1_CC_IF([int *], [void]));
794 static void yyerror (const char *);])
797 %token ARROW INVALID NUMBER STRING DATA
801 /* Grammar follows */
806 header: '<' from ARROW to '>' type ':'
807 | '<' ARROW to '>' type ':'
841 [/* A C++ error reporting function. */
843 yy::parser::error (const location&, const std::string& m)
845 std::cerr << m << std::endl;
852 parser.set_debug_level (!!YYDEBUG);
853 return parser.parse ();
857 yyerror (const char *s)
859 fprintf (stderr, "%s\n", s);
863 yylex (AT_LALR1_CC_IF([int *lval], [void]))
865 static int toknum = 0;
866 static int tokens[] =
870 ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[
871 return tokens[toknum++];
880 ])# _AT_DATA_DANCER_Y
883 # AT_CHECK_DANCER(BISON-OPTIONS)
884 # ------------------------------
885 # Generate the grammar, compile it, run it.
886 m4_define([AT_CHECK_DANCER],
887 [AT_SETUP([Dancer $1])
888 AT_BISON_OPTION_PUSHDEFS([$1])
889 _AT_DATA_DANCER_Y([$1])
890 AT_CHECK([bison -o dancer.c dancer.y])
892 [AT_CHECK([bison -o dancer.cc dancer.y])
893 AT_COMPILE_CXX([dancer])],
894 [AT_CHECK([bison -o dancer.c dancer.y])
895 AT_COMPILE([dancer])])
896 AT_PARSER_CHECK([./dancer], 1, [],
897 [syntax error, unexpected ':'
899 AT_BISON_OPTION_POPDEFS
904 AT_CHECK_DANCER([%glr-parser])
905 AT_CHECK_DANCER([%skeleton "lalr1.cc"])
908 ## ------------------------------------------ ##
909 ## Diagnostic that expects two alternatives. ##
910 ## ------------------------------------------ ##
913 # _AT_DATA_EXPECT2_Y(BISON-OPTIONS)
914 # --------------------------------
915 m4_define([_AT_DATA_EXPECT2_Y],
916 [AT_DATA_GRAMMAR([expect2.y],
918 static int yylex (AT_LALR1_CC_IF([int *], [void]));
921 static void yyerror (const char *);])
939 [/* A C++ error reporting function. */
941 yy::parser::error (const location&, const std::string& m)
943 std::cerr << m << std::endl;
950 return parser.parse ();
954 yyerror (const char *s)
956 fprintf (stderr, "%s\n", s);
960 yylex (AT_LALR1_CC_IF([int *lval], [void]))
962 static int toknum = 0;
963 static int tokens[] =
967 ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[
968 return tokens[toknum++];
977 ])# _AT_DATA_EXPECT2_Y
980 # AT_CHECK_EXPECT2(BISON-OPTIONS)
981 # ------------------------------
982 # Generate the grammar, compile it, run it.
983 m4_define([AT_CHECK_EXPECT2],
984 [AT_SETUP([Expecting two tokens $1])
985 AT_BISON_OPTION_PUSHDEFS([$1])
986 _AT_DATA_EXPECT2_Y([$1])
987 AT_CHECK([bison -o expect2.c expect2.y])
989 [AT_CHECK([bison -o expect2.cc expect2.y])
990 AT_COMPILE_CXX([expect2])],
991 [AT_CHECK([bison -o expect2.c expect2.y])
992 AT_COMPILE([expect2])])
993 AT_PARSER_CHECK([./expect2], 1, [],
994 [syntax error, unexpected '+', expecting A or B
996 AT_BISON_OPTION_POPDEFS
1001 AT_CHECK_EXPECT2([%glr-parser])
1002 AT_CHECK_EXPECT2([%skeleton "lalr1.cc"])