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.
This commit is contained in:
Akim Demaille
2012-01-25 16:57:58 +01:00
parent 2c7f50be62
commit d115aad911
5 changed files with 71 additions and 46 deletions

2
NEWS
View File

@@ -66,6 +66,8 @@ Bison News
** Minor improvements have been made to the manual. ** Minor improvements have been made to the manual.
** YYBACKUP works as expected.
* Changes in version 2.5 (2011-05-14): * Changes in version 2.5 (2011-05-14):
** Grammar symbol names can now contain non-initial dashes: ** Grammar symbol names can now contain non-initial dashes:

1
THANKS
View File

@@ -29,6 +29,7 @@ Csaba Raduly csaba_22@yahoo.co.uk
Dagobert Michelsen dam@baltic-online.de Dagobert Michelsen dam@baltic-online.de
Daniel Hagerty hag@gnu.org Daniel Hagerty hag@gnu.org
David J. MacKenzie djm@gnu.org David J. MacKenzie djm@gnu.org
David Kastrup dak@gnu.org
Derek M. Jones derek@knosof.co.uk Derek M. Jones derek@knosof.co.uk
Di-an Jan dianj@freeshell.org Di-an Jan dianj@freeshell.org
Dick Streefland dick.streefland@altium.nl Dick Streefland dick.streefland@altium.nl

44
TODO
View File

@@ -118,50 +118,6 @@ so both 256 and 257 are "mysterious".
** YYFAIL ** YYFAIL
It is seems to be *really* obsolete now, shall we remove it? It is seems to be *really* obsolete now, shall we remove it?
** YYBACKUP
There is no test about it, no examples in the doc, and I'm not sure
what it should look like. For instance what follows crashes.
%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);
}
%%
exp:
'a' { printf ("a: %d\n", $1); }
| 'b' { YYBACKUP('a', 123); }
;
%%
static int
yylex (YYSTYPE *yylval)
{
static char const input[] = "b";
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 ();
}
** yychar == yyempty_ ** yychar == yyempty_
The code in yyerrlab reads: The code in yyerrlab reads:

View File

@@ -646,11 +646,12 @@ static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
#define YYBACKUP(Token, Value) \ #define YYBACKUP(Token, Value) \
do \ do \
if (yychar == YYEMPTY && yylen == 1) \ if (yychar == YYEMPTY) \
{ \ { \
yychar = (Token); \ yychar = (Token); \
yylval = (Value); \ yylval = (Value); \
YYPOPSTACK (1); \]b4_lac_if([[ YYPOPSTACK (yylen); \
yystate = *yyssp; \]b4_lac_if([[
YY_LAC_DISCARD ("YYBACKUP"); \]])[ YY_LAC_DISCARD ("YYBACKUP"); \]])[
goto yybackup; \ goto yybackup; \
} \ } \

View File

@@ -1525,3 +1525,68 @@ AT_PARSER_CHECK([[./input]], [[0]], [],
]]) ]])
AT_CLEANUP 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