+%%
+float: UNTYPED INT
+{
+ $$ = $<fval>1 + $<fval>2;
+ $<ival>$ = $<ival>1 + $][2;
+};
+%%
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE(AT_SKEL_CC_IF([[{yy::parser::token::UNTYPED,
+ yy::parser::token::INT,
+ EOF}]],
+ [[{UNTYPED, INT, EOF}]]),
+ [AT_VAL.ival = toknum * 10; AT_VAL.fval = toknum / 10.0;])[
+int
+main (void)
+{]AT_SKEL_CC_IF([[
+ yy::parser p;
+ p.set_debug_level(1);
+ return p.parse ();]], [[
+ yydebug = 1;
+ return yyparse ();]])[
+}
+]])
+
+AT_FULL_COMPILE([[input]])
+AT_PARSER_CHECK([./input], 0, [], [stderr])
+# Don't be too picky on the traces, GLR is not exactly the same. Keep
+# only the lines from the printer.
+#
+# Don't care about locations. FIXME: remove their removal when Bison
+# supports C++ without locations.
+AT_CHECK([[sed -ne 's/([-0-9.]*: /(/;/ival:/p' stderr]], 0,
+[[Reading a token: Next token is token UNTYPED (ival: 10, fval: 0.1)
+Shifting token UNTYPED (ival: 10, fval: 0.1)
+Reading a token: Next token is token INT (ival: 20, fval: 0.2)
+Shifting token INT (ival: 20, fval: 0.2)
+ $][1 = token UNTYPED (ival: 10, fval: 0.1)
+ $][2 = token INT (ival: 20, fval: 0.2)
+-> $$ = nterm float (ival: 30, fval: 0.3)
+Cleanup: popping nterm float (ival: 30, fval: 0.3)
+]])
+
+AT_BISON_OPTION_POPDEFS
+
+AT_CLEANUP
+])
+
+AT_TEST([yacc.c])
+AT_TEST([glr.c])
+AT_TEST([lalr1.cc])
+AT_TEST([glr.cc])
+
+m4_popdef([AT_TEST])
+
+## ----------------------------------------------- ##
+## Fix user actions without a trailing semicolon. ##
+## ----------------------------------------------- ##
+
+AT_SETUP([[Fix user actions without a trailing semicolon]])
+
+# This feature is undocumented, but we accidentally broke it in 2.3a,
+# and there was a complaint at:
+# <http://lists.gnu.org/archive/html/bug-bison/2008-11/msg00001.html>.
+AT_BISON_OPTION_PUSHDEFS
+AT_DATA([input.y],
+[[%%
+start: test2 test1 test0 testc;
+
+test2
+: 'a' { semi; /* TEST:N:2 */ }
+| 'b' { if (0) {no_semi} /* TEST:N:2 */ }
+| 'c' { if (0) {semi;} /* TEST:N:2 */ }
+| 'd' { semi; no_semi /* TEST:Y:2 */ }
+| 'e' { semi(); no_semi() /* TEST:Y:2 */ }
+| 'f' { semi[]; no_semi[] /* TEST:Y:2 */ }
+| 'g' { semi++; no_semi++ /* TEST:Y:2 */ }
+| 'h' { {no_semi} no_semi /* TEST:Y:2 */ }
+| 'i' { {semi;} no_semi /* TEST:Y:2 */ }
+;
+test1
+ : 'a' { semi; // TEST:N:1 ;
+} | 'b' { if (0) {no_semi} // TEST:N:1 ;
+} | 'c' { if (0) {semi;} // TEST:N:1 ;
+} | 'd' { semi; no_semi // TEST:Y:1 ;
+} | 'e' { semi(); no_semi() // TEST:Y:1 ;
+} | 'f' { semi[]; no_semi[] // TEST:Y:1 ;
+} | 'g' { semi++; no_semi++ // TEST:Y:1 ;
+} | 'h' { {no_semi} no_semi // TEST:Y:1 ;
+} | 'i' { {semi;} no_semi // TEST:Y:1 ;
+} ;
+test0
+ : 'a' { semi; // TEST:N:1 {}
+} | 'b' { if (0) {no_semi} // TEST:N:1 {}
+} | 'c' { if (0) {semi;} // TEST:N:1 {}
+} | 'd' { semi; no_semi // TEST:Y:1 {}
+} | 'e' { semi(); no_semi() // TEST:Y:1 {}
+} | 'f' { semi[]; no_semi[] // TEST:Y:1 {}
+} | 'g' { semi++; no_semi++ // TEST:Y:1 {}
+} | 'h' { {no_semi} no_semi // TEST:Y:1 {}
+} | 'i' { {semi;} no_semi // TEST:Y:1 {}
+} ;
+
+testc
+: 'a' {
+#define TEST_MACRO_N \
+[]"broken\" $ @ $$ @$ [];\
+string;"}
+| 'b' {
+no_semi
+#define TEST_MACRO_N \
+[]"broken\" $ @ $$ @$ [];\
+string;"}
+]])
+AT_BISON_OPTION_POPDEFS
+
+AT_BISON_CHECK([[-o input.c input.y]], [0], [],
+[[input.y:8.48: warning: a ';' might be needed at the end of action code
+input.y:8.48: future versions of Bison will not add the ';'
+input.y:9.48: warning: a ';' might be needed at the end of action code
+input.y:9.48: future versions of Bison will not add the ';'
+input.y:10.48: warning: a ';' might be needed at the end of action code
+input.y:10.48: future versions of Bison will not add the ';'
+input.y:11.48: warning: a ';' might be needed at the end of action code
+input.y:11.48: future versions of Bison will not add the ';'
+input.y:12.48: warning: a ';' might be needed at the end of action code
+input.y:12.48: future versions of Bison will not add the ';'
+input.y:13.48: warning: a ';' might be needed at the end of action code
+input.y:13.48: future versions of Bison will not add the ';'
+input.y:20.1: warning: a ';' might be needed at the end of action code
+input.y:20.1: future versions of Bison will not add the ';'
+input.y:21.1: warning: a ';' might be needed at the end of action code
+input.y:21.1: future versions of Bison will not add the ';'
+input.y:22.1: warning: a ';' might be needed at the end of action code
+input.y:22.1: future versions of Bison will not add the ';'
+input.y:23.1: warning: a ';' might be needed at the end of action code
+input.y:23.1: future versions of Bison will not add the ';'
+input.y:24.1: warning: a ';' might be needed at the end of action code
+input.y:24.1: future versions of Bison will not add the ';'
+input.y:25.1: warning: a ';' might be needed at the end of action code
+input.y:25.1: future versions of Bison will not add the ';'
+input.y:31.1: warning: a ';' might be needed at the end of action code
+input.y:31.1: future versions of Bison will not add the ';'
+input.y:32.1: warning: a ';' might be needed at the end of action code
+input.y:32.1: future versions of Bison will not add the ';'
+input.y:33.1: warning: a ';' might be needed at the end of action code
+input.y:33.1: future versions of Bison will not add the ';'
+input.y:34.1: warning: a ';' might be needed at the end of action code
+input.y:34.1: future versions of Bison will not add the ';'
+input.y:35.1: warning: a ';' might be needed at the end of action code
+input.y:35.1: future versions of Bison will not add the ';'
+input.y:36.1: warning: a ';' might be needed at the end of action code
+input.y:36.1: future versions of Bison will not add the ';'
+]])
+
+AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]], [[3]])
+AT_MATCHES_CHECK([input.c], [[/\* TEST:Y:2 \*/ ;\}$]], [[6]])
+AT_MATCHES_CHECK([input.c], [[// TEST:N:1 [;{}]*\n\}$]], [[6]])
+AT_MATCHES_CHECK([input.c], [[// TEST:Y:1 [;{}]*\n;\}$]], [[12]])
+AT_MATCHES_CHECK([input.c], [[#define TEST_MACRO_N \\\n\[\]"broken\\" \$ \@ \$\$ \@\$ \[\];\\\nstring;"\}]], [[2]])
+
+AT_CLEANUP
+
+
+## -------------------------------------------------- ##
+## Destroying lookahead assigned by semantic action. ##
+## -------------------------------------------------- ##
+
+AT_SETUP([[Destroying lookahead assigned by semantic action]])
+
+AT_BISON_OPTION_PUSHDEFS
+AT_DATA_GRAMMAR([input.y],
+[[
+%code {
+ #include <assert.h>
+ #include <stdio.h>
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
+ #define USE(Var)
+}
+
+%destructor { fprintf (stderr, "'a' destructor\n"); } 'a'
+%destructor { fprintf (stderr, "'b' destructor\n"); } 'b'
+
+%%
+
+// In a previous version of Bison, yychar assigned by the semantic
+// action below was not translated into yytoken before the lookahead was
+// discarded and thus before its destructor (selected according to
+// yytoken) was called in order to return from yyparse. This would
+// happen even if YYACCEPT was performed in a later semantic action as
+// long as only consistent states with default reductions were visited
+// in between. However, we leave YYACCEPT in the same semantic action
+// for this test in order to show that skeletons cannot simply translate
+// immediately after every semantic action because a semantic action
+// that has set yychar might not always return normally. Instead,
+// skeletons must translate before every use of yytoken.
+start: 'a' accept { USE($1); } ;
+accept: /*empty*/ {
+ assert (yychar == YYEMPTY);
+ yychar = 'b';
+ YYACCEPT;
+} ;
+
+%%
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE(["a"])[