X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/a0de5091fc13a2fe53f72e6b2d3054b745d9dd8a..326e5cf81eada2ebd9007fa5fe9903a27a8bd067:/tests/regression.at diff --git a/tests/regression.at b/tests/regression.at index e0ab6935..c530428c 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -1,7 +1,6 @@ # Bison Regressions. -*- Autotest -*- -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software -# Foundation, Inc. +# Copyright (C) 2001-2010 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -39,7 +38,7 @@ int yylex (void); program: 'x'; ]]) -AT_CHECK([bison -o input.c input.y]) +AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) AT_COMPILE([input.o], [-DYYDEBUG -c input.c]) @@ -67,7 +66,7 @@ typedef union { char const *val; } YYSTYPE; program: { $$ = ""; }; ]]) -AT_CHECK([bison -o input.c input.y]) +AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) AT_CLEANUP @@ -105,7 +104,7 @@ exp: MY_TOKEN; %% ]]) -AT_CHECK([bison -y -o input.c input.y]) +AT_BISON_CHECK([-y -o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) AT_CLEANUP @@ -148,7 +147,7 @@ exp: MY_TOKEN; %% ]]) -AT_CHECK([bison -o input.c input.y]) +AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) AT_CLEANUP @@ -170,7 +169,7 @@ exp: { tests = {{{{{{{{{{}}}}}}}}}}; }; %% ]]) -AT_CHECK([bison -v -o input.c input.y]) +AT_BISON_CHECK([-v -o input.c input.y]) AT_CHECK([grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c], 0, [ignore]) @@ -197,7 +196,7 @@ exp: '(' exp ')' | NUM ; %% ]]) -AT_CHECK([bison -v -o input.c input.y], 0, [], +AT_BISON_CHECK([-v -o input.c input.y], 0, [], [[input.y:6.8-14: warning: symbol `"<="' used more than once as a literal string ]]) @@ -242,7 +241,7 @@ expr: }; ]]) -AT_CHECK([bison -o input.c -v input.y]) +AT_BISON_CHECK([-o input.c -v input.y]) # Check the contents of the report. AT_CHECK([cat input.output], [], @@ -364,7 +363,7 @@ exp: ; %% ]]) -AT_CHECK([bison -v -o input.c input.y]) +AT_BISON_CHECK([-v -o input.c input.y]) AT_CLEANUP @@ -387,14 +386,13 @@ default: 'a' } %{ ]]) -AT_CHECK([bison input.y], [1], [], +AT_BISON_CHECK([input.y], [1], [], [[input.y:2.1: invalid character: `?' input.y:3.14: invalid character: `}' input.y:4.1: invalid character: `%' input.y:4.2: invalid character: `&' input.y:5.1-17: invalid directive: `%a-does-not-exist' -input.y:6.1: invalid character: `%' -input.y:6.2: invalid character: `-' +input.y:6.1-2: invalid directive: `%-' input.y:7.1-8.0: missing `%}' at end of file input.y:7.1-8.0: syntax error, unexpected %{...%} ]]) @@ -414,7 +412,7 @@ AT_DATA([input.y], %union ]]) -AT_CHECK([bison input.y], [1], [], +AT_BISON_CHECK([input.y], [1], [], [[input.y:3.1-15: syntax error, unexpected %initial-action, expecting {...} ]]) @@ -444,6 +442,7 @@ int yylex (void); %token C_TOKEN 'c' %token 'd' D_TOKEN %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!" +%token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!" %% exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"; %% @@ -469,10 +468,22 @@ main (void) } ]]) -AT_CHECK([bison -o input.c input.y]) +# Checking the warning message guarantees that the trigraph "??!" isn't +# unnecessarily escaped here even though it would need to be if encoded in a +# C-string literal. Also notice that unnecessary escaping, such as "\?", from +# the user specification is eliminated. +AT_BISON_CHECK([-o input.c input.y], [[0]], [[]], +[[input.y:22.8-14: warning: symbol SPECIAL redeclared +input.y:22.8-63: warning: symbol `"\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!"' used more than once as a literal string +]]) AT_COMPILE([input]) + +# Checking the error message here guarantees that yytname, which does contain +# C-string literals, does have the trigraph escaped correctly. Thus, the +# symbol name reported by the parser is exactly the same as that reported by +# Bison itself. AT_DATA([experr], -[[syntax error, unexpected "\\'?\"\a\b\f\n\r\t\v\001\201\001\201?\?!", expecting a +[[syntax error, unexpected "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!", expecting a ]]) AT_PARSER_CHECK([./input], 1, [], [experr]) AT_CLEANUP @@ -500,7 +511,7 @@ exp: ]]) # Pacify font-lock-mode: " -AT_CHECK([bison -o input.c input.y]) +AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) AT_CLEANUP @@ -540,7 +551,7 @@ CONST_DEC: %% ]]) -AT_CHECK([bison -v input.y]) +AT_BISON_CHECK([-v input.y]) AT_CHECK([cat input.output], 0, [[Grammar @@ -705,7 +716,7 @@ else: "else" statement; %% ]]) -AT_CHECK([bison -v -o input.c input.y]) +AT_BISON_CHECK([-v -o input.c input.y]) # Check only the tables. [sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c >tables.c] @@ -741,15 +752,6 @@ AT_CHECK([[cat tables.c]], 0, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6 }; -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 6, 9, 14 -}; -static const yytype_int8 yyrhs[] = -{ - 8, 0, -1, 9, -1, -1, 10, 11, -1, 3, - 4, 5, 8, -1, 6, 8, -1 -}; static const yytype_uint8 yyrline[] = { 0, 2, 2, 3, 3, 4, 5 @@ -763,32 +765,24 @@ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261 }; -static const yytype_uint8 yyr1[] = -{ - 0, 7, 8, 9, 9, 10, 11 -}; -static const yytype_uint8 yyr2[] = +static const yytype_int8 yypact[] = { - 0, 2, 1, 0, 2, 4, 2 + -2, -1, 4, -8, 0, 2, -8, -2, -8, -2, + -8, -8 }; static const yytype_uint8 yydefact[] = { 3, 0, 0, 2, 0, 0, 1, 3, 4, 3, 6, 5 }; -static const yytype_int8 yydefgoto[] = -{ - -1, 2, 3, 4, 8 -}; -static const yytype_int8 yypact[] = -{ - -2, -1, 4, -8, 0, 2, -8, -2, -8, -2, - -8, -8 -}; static const yytype_int8 yypgoto[] = { -8, -7, -8, -8, -8 }; +static const yytype_int8 yydefgoto[] = +{ + -1, 2, 3, 4, 8 +}; static const yytype_uint8 yytable[] = { 10, 1, 11, 5, 6, 0, 7, 9 @@ -802,6 +796,14 @@ static const yytype_uint8 yystos[] = 0, 3, 8, 9, 10, 4, 0, 6, 11, 5, 8, 8 }; +static const yytype_uint8 yyr1[] = +{ + 0, 7, 8, 9, 9, 10, 11 +}; +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 0, 2, 4, 2 +}; ]]) AT_CLEANUP @@ -874,7 +876,7 @@ member: STRING AT_LALR1_CC_IF( [/* A C++ error reporting function. */ void -yy::parser::error (const location&, const std::string& m) +yy::parser::error (const std::string& m) { std::cerr << m << std::endl; } @@ -925,12 +927,8 @@ m4_define([AT_CHECK_DANCER], [AT_SETUP([Dancer $1]) AT_BISON_OPTION_PUSHDEFS([$1]) _AT_DATA_DANCER_Y([$1]) -AT_CHECK([bison -o dancer.c dancer.y]) -AT_LALR1_CC_IF( - [AT_CHECK([bison -o dancer.cc dancer.y]) - AT_COMPILE_CXX([dancer])], - [AT_CHECK([bison -o dancer.c dancer.y]) - AT_COMPILE([dancer])]) +AT_BISON_CHECK([-o dancer.c dancer.y]) +AT_FULL_COMPILE([dancer]) AT_PARSER_CHECK([./dancer], 1, [], [syntax error, unexpected ':' ]) @@ -977,7 +975,7 @@ t: A | B; AT_LALR1_CC_IF( [/* A C++ error reporting function. */ void -yy::parser::error (const location&, const std::string& m) +yy::parser::error (const std::string& m) { std::cerr << m << std::endl; } @@ -1025,12 +1023,8 @@ m4_define([AT_CHECK_EXPECT2], [AT_SETUP([Expecting two tokens $1]) AT_BISON_OPTION_PUSHDEFS([$1]) _AT_DATA_EXPECT2_Y([$1]) -AT_CHECK([bison -o expect2.c expect2.y]) -AT_LALR1_CC_IF( - [AT_CHECK([bison -o expect2.cc expect2.y]) - AT_COMPILE_CXX([expect2])], - [AT_CHECK([bison -o expect2.c expect2.y]) - AT_COMPILE([expect2])]) +AT_BISON_CHECK([-o expect2.c expect2.y]) +AT_FULL_COMPILE([expect2]) AT_PARSER_CHECK([./expect2], 1, [], [syntax error, unexpected '+', expecting A or B ]) @@ -1096,7 +1090,7 @@ main (void) } ]]) -AT_CHECK([bison -t -o input.c input.y]) +AT_BISON_CHECK([-t -o input.c input.y]) AT_COMPILE([input]) AT_PARSER_CHECK([./input], 0, [[Bison would once convert this action to a midrule because of the subsequent braced code. @@ -1137,7 +1131,7 @@ start: 'a' "A" 'b'; %token 'a' "A"; ]]) -AT_CHECK([bison -t -o input.c input.y]) +AT_BISON_CHECK([-t -o input.c input.y]) AT_CLEANUP @@ -1149,11 +1143,12 @@ AT_CLEANUP AT_SETUP([[Extra lookahead sets in report]]) -# Within a single state, Bison used to print a reduction's lookahead set next -# to all items of the associated rule. Instead, it should only print it next -# to the item that is of the associated rule and whose dot is at the end of the -# RHS. Printing it next to items whose dot is not at the end of the RHS is -# sometimes redundant and, as in this test case, is sometimes incorrect. +# Bison prints each reduction's lookahead set only next to the associated +# state's one item that (1) is associated with the same rule as the reduction +# and (2) has its dot at the end of its RHS. Previously, Bison also +# erroneously printed the lookahead set next to all of the state's other items +# associated with the same rule. This bug affected only the `.output' file and +# not the generated parser source code. AT_DATA([[input.y]], [[%% @@ -1161,7 +1156,7 @@ start: a | 'a' a 'a' ; a: 'a' ; ]]) -AT_CHECK([[bison --report=all input.y]]) +AT_BISON_CHECK([[--report=all input.y]]) AT_CHECK([[sed -n '/^state 1$/,/^state 2$/p' input.output]], [[0]], [[state 1 @@ -1180,3 +1175,293 @@ state 2 ]]) AT_CLEANUP + + + +## ---------------------------------------- ## +## Token number in precedence declaration. ## +## ---------------------------------------- ## + +AT_SETUP([[Token number in precedence declaration]]) + +# POSIX says token numbers can be declared in %left, %right, and %nonassoc, but +# we lost this in Bison 1.50. + +AT_DATA_GRAMMAR([input.y], +[[%{ + #include + void yyerror (char const *); + int yylex (void); +%} + +%error-verbose +%left TK1 1 TK2 2 "tok alias" 3 + +%% + +start: TK1 sr_conflict "tok alias" ; + +sr_conflict: + TK2 + | TK2 "tok alias" + ; + +%% + +void +yyerror (char const *msg) +{ + fprintf (stderr, "%s\n", msg); +} + +int +yylex (void) +{ + static int const input[] = { 1, 2, 3, 0 }; + static int const *inputp = input; + return *inputp++; +} + +int +main (void) +{ + return yyparse (); +} +]]) + +AT_BISON_CHECK([[-o input.c input.y]], [[0]],, +[[input.y:24.5-19: warning: rule useless in parser due to conflicts: sr_conflict: TK2 "tok alias" +]]) +AT_COMPILE([[input]]) +AT_PARSER_CHECK([[./input]]) + +AT_CLEANUP + + + +## --------------------------- ## +## parse-gram.y: LALR = IELR. ## +## --------------------------- ## + +# If parse-gram.y's LALR and IELR parser tables ever begin to differ, we +# need to fix parse-gram.y or start using IELR. + +AT_SETUP([[parse-gram.y: LALR = IELR]]) + +# Avoid tests/bison's dark magic by processing a local copy of the +# grammar. Avoid differences in synclines by telling bison that the +# output files have the same name. +[cp $abs_top_srcdir/src/parse-gram.y input.y] +AT_BISON_CHECK([[-o input.c -Dlr.type=lalr input.y]]) +[mv input.c lalr.c] +AT_BISON_CHECK([[-o input.c -Dlr.type=ielr input.y]]) +[mv input.c ielr.c] +AT_CHECK([[diff -u lalr.c ielr.c]]) + +AT_CLEANUP + + + +## -------------------------------------------- ## +## parse.error=verbose and YYSTACK_USE_ALLOCA. ## +## -------------------------------------------- ## + +AT_SETUP([[parse.error=verbose and YYSTACK_USE_ALLOCA]]) + +AT_DATA_GRAMMAR([input.y], +[[%code { + #include + void yyerror (char const *); + int yylex (void); + #define YYSTACK_USE_ALLOCA 1 +} + +%define parse.error verbose + +%% + +start: check syntax_error syntax_error ; + +check: +{ + if (128 < sizeof yymsgbuf) + { + fprintf (stderr, + "The initial size of yymsgbuf in yyparse has increased\n" + "since this test group was last updated. As a result,\n" + "this test group may no longer manage to induce a\n" + "reallocation of the syntax error message buffer.\n" + "This test group must be adjusted to produce a longer\n" + "error message.\n"); + YYABORT; + } +} +; + +// Induce a syntax error message whose total length is more than +// sizeof yymsgbuf in yyparse. Each token here is 64 bytes. +syntax_error: + "123456789112345678921234567893123456789412345678951234567896123A" +| "123456789112345678921234567893123456789412345678951234567896123B" +| error 'a' 'b' 'c' +; + +%% + +void +yyerror (char const *msg) +{ + fprintf (stderr, "%s\n", msg); +} + +int +yylex (void) +{ + /* Induce two syntax error messages (which requires full error + recovery by shifting 3 tokens) in order to detect any loss of the + reallocated buffer. */ + static char const *input = "abc"; + return *input++; +} + +int +main (void) +{ + return yyparse (); +} +]]) + +AT_BISON_CHECK([[-o input.c input.y]]) +AT_COMPILE([[input]]) +AT_PARSER_CHECK([[./input]], [[1]], [], +[[syntax error, unexpected 'a', expecting 123456789112345678921234567893123456789412345678951234567896123A or 123456789112345678921234567893123456789412345678951234567896123B +syntax error, unexpected $end, expecting 123456789112345678921234567893123456789412345678951234567896123A or 123456789112345678921234567893123456789412345678951234567896123B +]]) + +AT_CLEANUP + + + +## ------------------------------ ## +## parse.error=verbose overflow. ## +## ------------------------------ ## + +# Imagine the case where YYSTACK_ALLOC_MAXIMUM = YYSIZE_MAXIMUM and an +# invocation of yysyntax_error has caused yymsg_alloc to grow to exactly +# YYSTACK_ALLOC_MAXIMUM (perhaps because the normal doubling of size had +# to be clipped to YYSTACK_ALLOC_MAXIMUM). In an old version of yacc.c, +# a subsequent invocation of yysyntax_error that overflows during its +# size calculation would return YYSIZE_MAXIMUM to yyparse. Then, +# yyparse would invoke yyerror using the old contents of yymsg. + +AT_SETUP([[parse.error=verbose overflow]]) + +AT_DATA_GRAMMAR([input.y], +[[%code { + #include + void yyerror (char const *); + int yylex (void); + + /* This prevents this test case from having to induce error messages + large enough to overflow size_t. */ + #define YYSIZE_T unsigned char + + /* Bring in malloc so yacc.c doesn't try to provide a malloc prototype + using our YYSIZE_T. */ + #include + + /* Max depth is usually much smaller than YYSTACK_ALLOC_MAXIMUM, and + we don't want gcc to warn everywhere this constant would be too big + to make sense for our YYSIZE_T. */ + #define YYMAXDEPTH 100 +} + +%define parse.error verbose + +%% + +start: syntax_error1 check syntax_error2 ; + +// Induce a syntax error message whose total length causes yymsg in +// yyparse to be reallocated to size YYSTACK_ALLOC_MAXIMUM, which +// should be 255. Each token here is 64 bytes. +syntax_error1: + "123456789112345678921234567893123456789412345678951234567896123A" +| "123456789112345678921234567893123456789412345678951234567896123B" +| "123456789112345678921234567893123456789412345678951234567896123C" +| error 'a' 'b' 'c' +; + +check: +{ + if (yymsg_alloc != YYSTACK_ALLOC_MAXIMUM + || YYSTACK_ALLOC_MAXIMUM != YYSIZE_MAXIMUM + || YYSIZE_MAXIMUM != 255) + { + fprintf (stderr, + "The assumptions of this test group are no longer\n" + "valid, so it may no longer catch the error it was\n" + "designed to catch. Specifically, the following\n" + "values should all be 255:\n\n"); + fprintf (stderr, " yymsg_alloc = %d\n", yymsg_alloc); + fprintf (stderr, " YYSTACK_ALLOC_MAXIMUM = %d\n", + YYSTACK_ALLOC_MAXIMUM); + fprintf (stderr, " YYSIZE_MAXIMUM = %d\n", YYSIZE_MAXIMUM); + YYABORT; + } +} +; + +// Now overflow. +syntax_error2: + "123456789112345678921234567893123456789412345678951234567896123A" +| "123456789112345678921234567893123456789412345678951234567896123B" +| "123456789112345678921234567893123456789412345678951234567896123C" +| "123456789112345678921234567893123456789412345678951234567896123D" +| "123456789112345678921234567893123456789412345678951234567896123E" +; + +%% + +void +yyerror (char const *msg) +{ + fprintf (stderr, "%s\n", msg); +} + +int +yylex (void) +{ + /* Induce two syntax error messages (which requires full error + recovery by shifting 3 tokens). */ + static char const *input = "abc"; + return *input++; +} + +int +main (void) +{ + /* Push parsers throw away the message buffer between tokens, so skip + this test under maintainer-push-check. */ + if (YYPUSH) + return 77; + return yyparse (); +} +]]) + +AT_BISON_CHECK([[-o input.c input.y]]) + +# gcc warns about tautologies and fallacies involving comparisons for +# unsigned char. However, it doesn't produce these same warnings for +# size_t and many other types when the warnings would seem to make just +# as much sense. We ignore the warnings. +[CFLAGS="$NO_WERROR_CFLAGS"] +AT_COMPILE([[input]]) + +AT_PARSER_CHECK([[./input]], [[2]], [], +[[syntax error, unexpected 'a', expecting 123456789112345678921234567893123456789412345678951234567896123A or 123456789112345678921234567893123456789412345678951234567896123B or 123456789112345678921234567893123456789412345678951234567896123C +syntax error +memory exhausted +]]) + +AT_CLEANUP