+
+
+## -------------------------------------------------- ##
+## 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"])[
+int
+main (void)
+{
+ return yyparse ();
+}
+]])
+AT_BISON_OPTION_POPDEFS
+AT_BISON_CHECK([[-o input.c input.y]])
+AT_COMPILE([[input]])
+AT_PARSER_CHECK([[./input]], [[0]], [],
+[['b' destructor
+'a' destructor
+]])
+
+AT_CLEANUP
+
+## ---------- ##
+## YYBACKUP. ##
+## ---------- ##
+
+AT_SETUP([[YYBACKUP]])
+
+AT_BISON_OPTION_PUSHDEFS([%pure-parser])
+
+AT_DATA_GRAMMAR([input.y],
+[[
+%error-verbose
+%debug
+%pure-parser
+%code {
+# include <stdio.h>
+# include <stdlib.h>
+# include <assert.h>
+
+ ]AT_YYERROR_DECLARE[
+ ]AT_YYLEX_DECLARE[
+}
+%%
+input:
+ exp exp {}
+;
+
+exp:
+ 'a' { printf ("a: %d\n", $1); }
+| 'b' { YYBACKUP('a', 123); }
+| 'c' 'd' { YYBACKUP('a', 456); }
+;
+
+%%
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE(["bcd"], [*lvalp = (toknum + 1) * 10])[
+
+int
+main (void)
+{
+ yydebug = !!getenv("YYDEBUG");
+ return yyparse ();
+}
+]])
+AT_BISON_OPTION_POPDEFS
+
+AT_BISON_CHECK([[-o input.c input.y]])
+AT_COMPILE([[input]])
+AT_PARSER_CHECK([[./input]], [[0]],
+[[a: 123
+a: 456
+]])
+
+AT_CLEANUP