diff options
-rw-r--r-- | data/lalr1.cc | 1 | ||||
-rw-r--r-- | tests/c++.at | 69 |
2 files changed, 44 insertions, 26 deletions
diff --git a/data/lalr1.cc b/data/lalr1.cc index 9ab9421e..d3ab008b 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -901,6 +901,7 @@ b4_dollar_popdef])[]dnl else if (!yyempty) { yy_destroy_ ("Error: discarding", yyla); + yyla.clear (); yyempty = true; } } diff --git a/tests/c++.at b/tests/c++.at index 1aa730f1..30304019 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -175,6 +175,9 @@ AT_CLEANUP ## Variants. ## ## ---------- ## +# Check that the variants are properly supported, including in error +# recovery. + # AT_TEST([DIRECTIVES]) # --------------------- # Check the support of variants in C++, with the additional DIRECTIVES. @@ -243,6 +246,7 @@ typedef std::list<std::string> strings_type; %token <::std::string> TEXT; %token <int> NUMBER; %token END_OF_FILE 0; +%token COMMA "," %type <::std::string> item; // Using the template type to exercize its parsing. @@ -259,13 +263,13 @@ result: ; list: - /* nothing */ { /* Generates an empty string list */ } -| list item { std::swap ($$,$][1); $$.push_back ($][2); } -| list error { std::swap ($$,$][1); } + item { $$.push_back ($][1); } +| list "," item { std::swap ($$, $][1); $$.push_back ($][3); } +| list error { std::swap ($$, $][1); } ; item: - TEXT { std::swap ($$,$][1); } + TEXT { std::swap ($$, $][1); } | NUMBER { if ($][1 == 3) YYERROR; else $$ = to_string ($][1); } ; %% @@ -285,30 +289,43 @@ namespace yy parser::location_type* yylloc])[)]])[ {]AT_LOCATION_IF([ typedef parser::location_type location;])[ - static int stage = -1; - ++stage; - if (stage == STAGE_MAX) - {]AT_TOKEN_CTOR_IF([[ + // The 5 is a syntax error whose recovery requires that we discard + // the lookahead. This tests a regression, see + // <http://savannah.gnu.org/support/?108481>. + static char const *input = "0,1,2,3,45,6"; + switch (int stage = *input++) + { + case 0:]AT_TOKEN_CTOR_IF([[ return parser::make_END_OF_FILE (]AT_LOCATION_IF([location ()])[);]], [AT_LOCATION_IF([ *yylloc = location ();])[ return parser::token::END_OF_FILE;]])[ - } - else if (stage % 2) - {]AT_TOKEN_CTOR_IF([[ - return parser::make_NUMBER (stage]AT_LOCATION_IF([, location ()])[);]], -[[ - yylval->BUILD (int, stage);]AT_LOCATION_IF([ - *yylloc = location ();])[ - return parser::token::NUMBER;]])[ - } - else - {]AT_TOKEN_CTOR_IF([[ - return parser::make_TEXT (to_string (stage)]AT_LOCATION_IF([, location ()])[);]], [[ - yylval->BUILD (std::string, to_string (stage));]AT_LOCATION_IF([ + + case ',': + ]AT_TOKEN_CTOR_IF([[ + return parser::make_COMMA (]AT_LOCATION_IF([location ()])[);]], [[ +]AT_LOCATION_IF([ *yylloc = location ();])[ - return parser::token::TEXT;]])[ - } + return parser::token::COMMA;]])[ + + default: + stage = stage - '0'; + if (stage % 2) + {]AT_TOKEN_CTOR_IF([[ + return parser::make_NUMBER (stage]AT_LOCATION_IF([, location ()])[);]], [[ + yylval->BUILD (int, stage);]AT_LOCATION_IF([ + *yylloc = location ();])[ + return parser::token::NUMBER;]])[ + } + else + {]AT_TOKEN_CTOR_IF([[ + return parser::make_TEXT (to_string (stage)]AT_LOCATION_IF([, location ()])[);]], [[ + yylval->BUILD (std::string, to_string (stage));]AT_LOCATION_IF([ + *yylloc = location ();])[ + return parser::token::TEXT;]])[ + } + } + abort (); } } @@ -319,7 +336,7 @@ namespace yy AT_FULL_COMPILE([list]) AT_PARSER_CHECK([./list], 0, -[(0, 1, 2, 4) +[(0, 1, 2, 4, 6) ]) AT_BISON_OPTION_POPDEFS @@ -328,11 +345,11 @@ AT_CLEANUP AT_TEST([[%skeleton "lalr1.cc" ]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert]]) -AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert]]) +AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %locations]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor]]) AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]]) -AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]]) +AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_} %locations]]) m4_popdef([AT_TEST]) |