summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/lalr1.cc1
-rw-r--r--tests/c++.at69
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])