summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkim Demaille <demaille@gostai.com>2012-01-25 16:57:58 +0100
committerAkim Demaille <demaille@gostai.com>2012-01-26 21:36:35 +0100
commit94556574b56eed6d42395bf8264f1ee9eec08eac (patch)
treee6d6942267724b0b91345f513b0c566784741f2e
parent7aadf26359e95f8b113c972e42155c908bb850b8 (diff)
downloadbison-94556574b56eed6d42395bf8264f1ee9eec08eac.tar.gz
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
-rw-r--r--NEWS2
-rw-r--r--THANKS1
-rw-r--r--data/yacc.c25
-rw-r--r--tests/actions.at65
4 files changed, 81 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index e8928846..28ba8338 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 f67bd0cd..7a9a587e 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 67d6abda..2beef804 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 87051cef..2da52941 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 <stdio.h>
+# include <stdlib.h>
+# include <assert.h>
+
+ 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