From 94556574b56eed6d42395bf8264f1ee9eec08eac Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Wed, 25 Jan 2012 16:57:58 +0100 Subject: [PATCH] yacc: fix YYBACKUP. Reported by David Kastrup: https://lists.gnu.org/archive/html/bug-bison/2011-10/msg00002.html. * data/yacc.c (YYBACKUP): Accept rhs size. Restore the proper state value. * TODO (YYBACKUP): Make it... * tests/actions.at: a new test case. * NEWS, THANKS: Update. (cherry picked from commit d115aad9112fb4e2fe1b268c9db7390732d39539) Conflicts: TODO data/yacc.c --- NEWS | 2 ++ THANKS | 1 + data/yacc.c | 25 +++++++++++----------- tests/actions.at | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index e892884..28ba833 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ Bison News ** Minor improvements have been made to the manual. +** YYBACKUP works as expected. + * Changes in version 2.5 (2011-05-14): ** Grammar symbol names can now contain non-initial dashes: diff --git a/THANKS b/THANKS index f67bd0c..7a9a587 100644 --- a/THANKS +++ b/THANKS @@ -29,6 +29,7 @@ Csaba Raduly csaba_22@yahoo.co.uk Dagobert Michelsen dam@baltic-online.de Daniel Hagerty hag@gnu.org David J. MacKenzie djm@gnu.org +David Kastrup dak@gnu.org Derek M. Jones derek@knosof.co.uk Di-an Jan dianj@freeshell.org Dick Streefland dick.streefland@altium.nl diff --git a/data/yacc.c b/data/yacc.c index 67d6abd..2beef80 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -712,18 +712,19 @@ static const ]b4_int_type_for([b4_stos])[ yystos[] = #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (1); \]b4_lac_if([[ - YY_LAC_DISCARD ("YYBACKUP"); \]])[ - goto yybackup; \ - } \ - else \ - { \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \]b4_lac_if([[ + YY_LAC_DISCARD ("YYBACKUP"); \]])[ + goto yybackup; \ + } \ + else \ + { \ yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")); \ YYERROR; \ } \ diff --git a/tests/actions.at b/tests/actions.at index 87051ce..2da5294 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -1525,3 +1525,68 @@ AT_PARSER_CHECK([[./input]], [[0]], [], ]]) AT_CLEANUP + +## ---------- ## +## YYBACKUP. ## +## ---------- ## + +AT_SETUP([[YYBACKUP]]) + +AT_DATA_GRAMMAR([input.y], +[[ +%error-verbose +%debug +%pure-parser +%code { +# include +# include +# include + + static void yyerror (const char *msg); + static int yylex (YYSTYPE *yylval); +} +%% +input: + exp exp {} +; + +exp: + 'a' { printf ("a: %d\n", $1); } +| 'b' { YYBACKUP('a', 123); } +| 'c' 'd' { YYBACKUP('a', 456); } +; + +%% +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++]; +} + +static void +yyerror (const char *msg) +{ + fprintf (stderr, "%s\n", msg); +} + +int +main (void) +{ + yydebug = !!getenv("YYDEBUG"); + return yyparse (); +} +]]) + +AT_BISON_CHECK([[-o input.c input.y]]) +AT_COMPILE([[input]]) +AT_PARSER_CHECK([[./input]], [[0]], +[[a: 123 +a: 456 +a: 789 +]]) + +AT_CLEANUP -- 2.7.4