]> git.saurik.com Git - bison.git/commitdiff
yacc: fix YYBACKUP.
authorAkim Demaille <demaille@gostai.com>
Wed, 25 Jan 2012 15:57:58 +0000 (16:57 +0100)
committerAkim Demaille <demaille@gostai.com>
Thu, 26 Jan 2012 20:36:35 +0000 (21:36 +0100)
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
THANKS
data/yacc.c
tests/actions.at

diff --git a/NEWS b/NEWS
index e8928846c0c720bc5f216235e47ceb8cd920bf07..28ba83388eb543f6ca1610b56fe8091ab6faa23b 100644 (file)
--- 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 f67bd0cdd508afc4a480b5be68ce66a2c1f06195..7a9a587e849988e4f31943b1496744fbafda6e7f 100644 (file)
--- 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
index 67d6abdab479a38bdbaa80c93e28388085e46d19..2beef804a32c2793be152b79c94f18a1a08a23aa 100644 (file)
@@ -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;                                                 \
     }                                                          \
index 87051cefe16a9192df780b20a76e6819a80eab57..2da529411568ab62d688be6f9501735c6dab7678 100644 (file)
@@ -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