# Executing Actions. -*- Autotest -*-
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software
-# Foundation, Inc.
+
+# Copyright (C) 2001-2012 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# instead of being attached to the empty rule dedicated to this
# action.
+AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%{
-# include <stdio.h>
-# include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
%}
%%
exp: { putchar ('0'); }
{ putchar ('\n'); }
;
%%
-static int
-yylex (void)
-{
- static char const input[] = "123456789";
- static size_t toknum;
- if (! (toknum < sizeof input))
- abort ();
- return input[toknum++];
-}
-
-static void
-yyerror (const char *msg)
-{
- fprintf (stderr, "%s\n", msg);
-}
-
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE(123456789)[
int
main (void)
{
return yyparse ();
}
]])
+AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-d -v -o input.c input.y])
AT_COMPILE([input])
AT_SETUP([Exotic Dollars])
+AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%{
-# include <stdio.h>
-# include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
# define USE(Var)
%}
;
%%
-static int
-yylex (void)
-{
- static int called;
- if (called++)
- abort ();
- return EOF;
-}
-
-static void
-yyerror (const char *msg)
-{
- fprintf (stderr, "%s\n", msg);
-}
-
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE([])[
int
main (void)
{
[[15
]])
+# Make sure that fields after $n or $-n are parsed correctly. At one
+# point while implementing dashes in symbol names, we were dropping
+# fields after $-n.
+AT_DATA_GRAMMAR([[input.y]],
+[[
+%{
+# include <stdio.h>
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
+ typedef struct { int val; } stype;
+# define YYSTYPE stype
+%}
+
+%%
+start: one two { $$.val = $1.val + $2.val; } sum ;
+one: { $$.val = 1; } ;
+two: { $$.val = 2; } ;
+sum: { printf ("%d\n", $0.val + $-1.val + $-2.val); } ;
+
+%%
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE()[
+int
+main (void)
+{
+ return yyparse ();
+}
+]])
+
+AT_BISON_CHECK([[-o input.c input.y]])
+AT_COMPILE([[input]])
+AT_PARSER_CHECK([[./input]], [[0]],
+[[6
+]])
+
+AT_BISON_OPTION_POPDEFS
AT_CLEANUP
}])
AT_LALR1_CC_IF([%define global_tokens_and_yystype])
m4_ifval([$6], [[%code provides {]], [[%code {]])
-AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])
-[static int yylex (]AT_LEX_FORMALS[);
-]AT_LALR1_CC_IF([], [static void yyerror (const char *msg);])
+AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
+]AT_YYLEX_DECLARE[
+]AT_LALR1_CC_IF([], [AT_YYERROR_DECLARE])
[}
]m4_ifval([$6], [%type <ival> '(' 'x' 'y' ')' ';' thing line input END])[
printf ("input (%d@%d-%d): /* Nothing */\n", $$, RANGE (@$));
}
| line input /* Right recursive to load the stack so that popping at
- END can be exercised. */
+ END can be exercised. */
{
$$ = 2;
printf ("input (%d@%d-%d): line (%d@%d-%d) input (%d@%d-%d)\n",
- $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2));
+ $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2));
}
;
;
%%
/* Alias to ARGV[1]. */
-const char *source = 0;
+const char *source = YY_NULL;
-static int
-yylex (]AT_LEX_FORMALS[)
+static
+]AT_YYLEX_PROTOTYPE[
{
static unsigned int counter = 0;
]])
])
-])
+AT_BISON_OPTION_POPDEFS
+])# _AT_CHECK_PRINTER_AND_DESTRUCTOR
# AT_CHECK_PRINTER_AND_DESTRUCTOR([BISON-OPTIONS], [UNION-FLAG], [SKIP_FLAG])
$3
_AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4],
-[%error-verbose
+[%define parse.error verbose
%debug
%verbose
%locations
# called for $end, and that $$ and @$ work correctly.
AT_SETUP([Default tagless %printer and %destructor])
-
+AT_BISON_OPTION_PUSHDEFS([%locations])
AT_DATA_GRAMMAR([[input.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%locations
%initial-action {
%{
# include <stdio.h>
# include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+]AT_YYLEX_DECLARE[
+]AT_YYERROR_DECLARE[
# define USE(SYM)
%}
start: 'a' 'b' 'c' 'd' 'e' { $$ = 'S'; USE(($1, $2, $3, $4, $5)); } ;
%%
-
-static int
-yylex (void)
-{
- static char const input[] = "abcd";
- static size_t toknum;
- if (! (toknum < sizeof input))
- abort ();
- yylval = input[toknum++];
- yylloc.first_line = yylloc.last_line = 1;
- yylloc.first_column = yylloc.last_column = toknum;
- return yylval;
-}
-
-static void
-yyerror (const char *msg)
-{
- fprintf (stderr, "%s\n", msg);
-}
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE([abcd], [[yylval = res]])[
int
main (void)
Shifting token 'd' (1.4-1.4: <> printer for 'd' @ 4)
Entering state 6
Reading a token: Now at end of input.
-syntax error, unexpected $end, expecting 'e'
+1.5-4: syntax error, unexpected $end, expecting 'e'
Error: popping token 'd' (1.4-1.4: <> printer for 'd' @ 4)
Stack now 0 1 3 5
Error: popping token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3)
Stack now 0
]])
+AT_BISON_OPTION_POPDEFS
AT_CLEANUP
## ------------------------------------------------------ ##
AT_SETUP([Default tagged and per-type %printer and %destructor])
-
+AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%{
# include <stdio.h>
# include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
# define USE(SYM)
%}
;
%%
-
-static int
-yylex (void)
-{
- static char const input[] = "abcdef";
- static size_t toknum;
- if (! (toknum < sizeof input))
- abort ();
- return input[toknum++];
-}
-
-static void
-yyerror (const char *msg)
-{
- fprintf (stderr, "%s\n", msg);
-}
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE([abcdef])[
int
main (void)
Stack now 0
]])
+AT_BISON_OPTION_POPDEFS
AT_CLEANUP
AT_SETUP([Default %printer and %destructor for user-defined end token])
# _AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(TYPED)
-# -----------------------------------------------------------------------------
+# -------------------------------------------------------------
m4_define([_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN],
[m4_if($1, 0,
[m4_pushdef([kind], []) m4_pushdef([not_kind], [*])],
[m4_pushdef([kind], [*]) m4_pushdef([not_kind], [])])
+AT_BISON_OPTION_PUSHDEFS([%locations])
AT_DATA_GRAMMAR([[input]]$1[[.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%locations
%initial-action {
%{
# include <stdio.h>
# include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
# define USE(SYM)
%}
yylloc.first_column = yylloc.last_column = 1;
return 0;
}
-
-static void
-yyerror (const char *msg)
-{
- fprintf (stderr, "%s\n", msg);
-}
+]AT_YYERROR_DEFINE[
int
main (void)
return yyparse ();
}
]])
+AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-o input$1.c input$1.y])
AT_COMPILE([input$1])
# semantic value, which would be initialized from the lookahead, which
# would be destroyed separately.
# - For $undefined, who knows what the semantic value would be.
-
+AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
[[%debug
%{
# include <stdio.h>
# include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
# define USE(SYM)
%}
;
%%
-
-static int
-yylex (void)
-{
- static char const input[] = "abd";
- static size_t toknum;
- if (! (toknum < sizeof input))
- abort ();
- yylval = input[toknum++];
- return yylval;
-}
-
-static void
-yyerror (const char *msg)
-{
- fprintf (stderr, "%s\n", msg);
-}
-
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE([abd], [yylval = res])[
int
main (void)
{
return yyparse ();
}
]])
+AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-o input.c input.y])
AT_COMPILE([input])
# true for $undefined and the error token, so there are three warnings for
# %printer and three for %destructor.)
+AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
[[%debug /* So that %printer is actually compiled. */
%{
# include <stdio.h>
# include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
# define USE(SYM)
%}
start: { USE($$); } ;
%%
-
-static int
-yylex (void)
-{
- static int called;
- if (called++)
- abort ();
- return 0;
-}
-
-static void
-yyerror (const char *msg)
-{
- fprintf (stderr, "%s\n", msg);
-}
-
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE([])[
int
main (void)
{
return yyparse ();
}
]])
+AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-o input.c input.y])
AT_COMPILE([input])
AT_SETUP([Default %printer and %destructor for mid-rule values])
+AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
[[%debug /* So that %printer is actually compiled. */
%{
# include <stdio.h>
# include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
# define USE(SYM)
# define YYLTYPE int
-# define YYLLOC_DEFAULT(Current, Rhs, N)
+# define YYLLOC_DEFAULT(Current, Rhs, N) (void)(Rhs)
# define YY_LOCATION_PRINT(File, Loc)
%}
;
%%
-
-static int
-yylex (void)
-{
- static int called;
- if (called++)
- abort ();
- return 0;
-}
-
-static void
-yyerror (const char *msg)
-{
- fprintf (stderr, "%s\n", msg);
-}
-
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE([])[
int
main (void)
{
return yyparse ();
}
]])
+AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-o input.c input.y], 0,,
[[input.y:33.3-23: warning: unset value: $$
# Bison once forgot to check for @$ in actions other than semantic actions.
# AT_CHECK_ACTION_LOCATIONS(ACTION-DIRECTIVE)
-# -------------------------------------------------------
+# -------------------------------------------
m4_define([AT_CHECK_ACTION_LOCATIONS],
[AT_SETUP([[@$ in ]$1[ implies %locations]])
-
+AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
[[%code {
#include <stdio.h>
- static int yylex (void);
- static void yyerror (char const *msg);
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
}
%debug
return 0;
}
-static void
-yyerror (char const *msg)
-{
- fprintf (stderr, "%s\n", msg);
-}
-
+]AT_YYERROR_DEFINE[
int
main (void)
{
AT_BISON_CHECK([[-o input.c input.y]])
AT_COMPILE([[input]])
-
+AT_BISON_OPTION_POPDEFS
AT_CLEANUP])
AT_CHECK_ACTION_LOCATIONS([[%initial-action]])
# 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 */ }
+: '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 ;
+ : '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 {}
+ : '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
[]"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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: future versions of Bison will not add the `;'
+[[input.y:8.48: warning: a ';' might be needed at the end of action code
+input.y:8.48: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: 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: warning: future versions of Bison will not add the ';'
]])
AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]], [[3]])
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])[
+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[
+ static int yylex (YYSTYPE *yylval);
+}
+%%
+input:
+ exp exp {}
+;
+
+exp:
+ 'a' { printf ("a: %d\n", $1); }
+| 'b' { YYBACKUP('a', 123); }
+| 'c' 'd' { YYBACKUP('a', 456); }
+;
+
+%%
+]AT_YYERROR_DEFINE[
+static int
+yylex (YYSTYPE *yylval)
+{
+ static char const input[] = "bcd";
+ static size_t toknum;
+ assert (toknum < sizeof input);
+ *yylval = (toknum + 1) * 10;
+ return input[toknum++];
+}
+
+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