diff --git a/tests/c++.at b/tests/c++.at index d708a5ba..cd71595c 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -386,6 +386,132 @@ AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructo m4_popdef([AT_TEST]) + +## ------------------------------------- ## +## Variants and Typed Mid-rule Actions. ## +## ------------------------------------- ## + +AT_SETUP([Variants and Typed Mid-rule Actions]) + +# See http://lists.gnu.org/archive/html/bug-bison/2017-06/msg00000.html. +# +# Check that typed mid-rule actions behave properly (pre-construction +# of $$ before the user action, support of %printer and %destructor, +# etc.). + +AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"]) + +AT_DATA_GRAMMAR([[input.y]], +[[%skeleton "lalr1.cc" +%defines + +%debug +%define parse.assert +%define api.value.type variant +%define api.token.constructor +%error-verbose + +%code +{ + #include + namespace yy + { + static yy::parser::symbol_type yylex(); + } +} + +%token NUMBER; +%nterm expr; +%token EOI 0; +%printer { yyo << $$; } ; +%destructor { std::cerr << "destroy: " << $$ << '\n'; } +%% +expr: + NUMBER { $$ = $1 * 10; } +| expr { $$ = 20; } NUMBER + { + std::cerr << "expr: " << $1 << ' ' << $2 << ' ' << $3 << '\n'; + $$ = 40; + } +; + +%% +namespace yy +{ + parser::symbol_type yylex() + { + static int loc = 0; + switch (loc++) + { + case 0: + return parser::make_NUMBER (1); + case 1: + return parser::make_NUMBER (30); + default: + return parser::make_EOI (); + } + } + + void parser::error(const std::string& message) + { + std::cerr << message << '\n'; + } +} + +int main() +{ + yy::parser p; + p.set_debug_level (1); + return p.parse(); +} +]]) + + +AT_FULL_COMPILE([[input]]) +# This used to print "Discarding 'a'." again at the end. +AT_PARSER_CHECK([[./input]], [[0]], [[]], +[[Starting parse +Entering state 0 +Reading a token: Next token is token NUMBER (1) +Shifting token NUMBER (1) +Entering state 1 +Reducing stack by rule 1 (line 34): + $1 = token NUMBER (1) +-> $$ = nterm expr (10) +destroy: 1 +Stack now 0 +Entering state 2 +Reading a token: Next token is token NUMBER (30) +Reducing stack by rule 2 (line 35): +-> $$ = nterm @1 (20) +Stack now 2 0 +Entering state 4 +Next token is token NUMBER (30) +Shifting token NUMBER (30) +Entering state 5 +Reducing stack by rule 3 (line 35): + $1 = nterm expr (10) + $2 = nterm @1 (20) + $3 = token NUMBER (30) +expr: 10 20 30 +-> $$ = nterm expr (40) +destroy: 30 +destroy: 20 +destroy: 10 +Stack now 0 +Entering state 2 +Reading a token: Next token is token EOI () +Shifting token EOI () +Entering state 3 +Cleanup: popping token EOI () +Cleanup: popping nterm expr (40) +destroy: 40 +]]) + +AT_BISON_OPTION_POPDEFS +AT_CLEANUP + + ## ----------------------- ## ## Doxygen Documentation. ## ## ----------------------- ##