mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-18 16:53:02 +00:00
yysyntax_error: avoid duplicate lookahead collection.
Except when memory reallocation is required, this change eliminates the need to invoke yysyntax_error twice and thus to repeat the collection of lookaheads. It also prepares for future extensions that will make those repetitions more expensive and that will require additional memory management in yysyntax_error. Finally, it fixes an obscure bug already exercised in the test suite. * data/yacc.c (yysyntax_error): Add arguments for message buffer variables stored in the parser. Instead of size, return status similar to yyparse status but indicating success of message creation. Other than the actual reallocation of the message buffer, import and clean up memory management code from... (yyparse, yypush_parse): ... here. * tests/regression.at (parse.error=verbose overflow): No longer an expected failure.
This commit is contained in:
20
ChangeLog
20
ChangeLog
@@ -1,3 +1,23 @@
|
|||||||
|
2009-09-23 Joel E. Denny <jdenny@clemson.edu>
|
||||||
|
|
||||||
|
yysyntax_error: avoid duplicate lookahead collection.
|
||||||
|
Except when memory reallocation is required, this change
|
||||||
|
eliminates the need to invoke yysyntax_error twice and thus to
|
||||||
|
repeat the collection of lookaheads. It also prepares for
|
||||||
|
future extensions that will make those repetitions more
|
||||||
|
expensive and that will require additional memory management in
|
||||||
|
yysyntax_error. Finally, it fixes an obscure bug already
|
||||||
|
exercised in the test suite.
|
||||||
|
* data/yacc.c (yysyntax_error): Add arguments for message
|
||||||
|
buffer variables stored in the parser. Instead of size, return
|
||||||
|
status similar to yyparse status but indicating success of
|
||||||
|
message creation. Other than the actual reallocation of the
|
||||||
|
message buffer, import and clean up memory management code
|
||||||
|
from...
|
||||||
|
(yyparse, yypush_parse): ... here.
|
||||||
|
* tests/regression.at (parse.error=verbose overflow): No longer
|
||||||
|
an expected failure.
|
||||||
|
|
||||||
2009-09-23 Joel E. Denny <jdenny@clemson.edu>
|
2009-09-23 Joel E. Denny <jdenny@clemson.edu>
|
||||||
|
|
||||||
yysyntax_error: test memory management more.
|
yysyntax_error: test memory management more.
|
||||||
|
|||||||
142
data/yacc.c
142
data/yacc.c
@@ -889,26 +889,27 @@ yytnamerr (char *yyres, const char *yystr)
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* Copy into YYRESULT an error message about the unexpected token
|
/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
|
||||||
YYTOKEN while in state YYSTATE. Return the number of bytes copied,
|
about the unexpected token YYTOKEN while in state YYSTATE.
|
||||||
including the terminating null byte. If YYRESULT is null, do not
|
|
||||||
copy anything; just return the number of bytes that would be
|
Return 0 if *YYMSG was successfully written. Return 1 if an ordinary
|
||||||
copied. As a special case, return 0 if an ordinary "syntax error"
|
"syntax error" message will suffice instead. Return 2 if *YYMSG is
|
||||||
message will do. Return YYSIZE_MAXIMUM if overflow occurs during
|
not large enough to hold the message. In the last case, also set
|
||||||
size calculation. */
|
*YYMSG_ALLOC to either (a) the required number of bytes or (b) zero
|
||||||
static YYSIZE_T
|
if the required number of bytes is too large to store. */
|
||||||
yysyntax_error (char *yyresult, int yystate, int yytoken)
|
static int
|
||||||
|
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
|
||||||
|
int yystate, int yytoken)
|
||||||
{
|
{
|
||||||
int yyn = yypact[yystate];
|
int yyn = yypact[yystate];
|
||||||
|
|
||||||
if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
|
if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
|
||||||
return 0;
|
return 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
|
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
|
||||||
YYSIZE_T yysize = yysize0;
|
YYSIZE_T yysize = yysize0;
|
||||||
YYSIZE_T yysize1;
|
YYSIZE_T yysize1;
|
||||||
int yysize_overflow = 0;
|
|
||||||
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
|
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
|
||||||
/* Internationalized format string. */
|
/* Internationalized format string. */
|
||||||
const char *yyformat = 0;
|
const char *yyformat = 0;
|
||||||
@@ -942,11 +943,17 @@ yysyntax_error (char *yyresult, int yystate, int yytoken)
|
|||||||
}
|
}
|
||||||
yyarg[yycount++] = yytname[yyx];
|
yyarg[yycount++] = yytname[yyx];
|
||||||
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
|
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
|
||||||
yysize_overflow |= (yysize1 < yysize);
|
if (! (yysize <= yysize1
|
||||||
|
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM))
|
||||||
|
{
|
||||||
|
/* Overflow. */
|
||||||
|
*yymsg_alloc = 0;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
yysize = yysize1;
|
yysize = yysize1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (yycount)
|
switch (yycount)
|
||||||
{
|
{
|
||||||
#define YYCASE_(N, S) \
|
#define YYCASE_(N, S) \
|
||||||
case N: \
|
case N: \
|
||||||
@@ -961,32 +968,42 @@ yysyntax_error (char *yyresult, int yystate, int yytoken)
|
|||||||
}
|
}
|
||||||
|
|
||||||
yysize1 = yysize + yystrlen (yyformat);
|
yysize1 = yysize + yystrlen (yyformat);
|
||||||
yysize_overflow |= (yysize1 < yysize);
|
if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
|
||||||
|
{
|
||||||
|
/* Overflow. */
|
||||||
|
*yymsg_alloc = 0;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
yysize = yysize1;
|
yysize = yysize1;
|
||||||
|
|
||||||
if (yysize_overflow)
|
if (*yymsg_alloc < yysize)
|
||||||
return YYSIZE_MAXIMUM;
|
{
|
||||||
|
*yymsg_alloc = 2 * yysize;
|
||||||
|
if (! (yysize <= *yymsg_alloc
|
||||||
|
&& *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
|
||||||
|
*yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (yyresult)
|
/* Avoid sprintf, as that infringes on the user's name space.
|
||||||
{
|
Don't have undefined behavior even if the translation
|
||||||
/* Avoid sprintf, as that infringes on the user's name space.
|
produced a string with the wrong number of "%s"s. */
|
||||||
Don't have undefined behavior even if the translation
|
{
|
||||||
produced a string with the wrong number of "%s"s. */
|
char *yyp = *yymsg;
|
||||||
char *yyp = yyresult;
|
int yyi = 0;
|
||||||
int yyi = 0;
|
while ((*yyp = *yyformat) != '\0')
|
||||||
while ((*yyp = *yyformat) != '\0')
|
if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
|
||||||
if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
|
{
|
||||||
{
|
yyp += yytnamerr (yyp, yyarg[yyi++]);
|
||||||
yyp += yytnamerr (yyp, yyarg[yyi++]);
|
yyformat += 2;
|
||||||
yyformat += 2;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
yyp++;
|
||||||
yyp++;
|
yyformat++;
|
||||||
yyformat++;
|
}
|
||||||
}
|
}
|
||||||
}
|
return 0;
|
||||||
return yysize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* YYERROR_VERBOSE */
|
#endif /* YYERROR_VERBOSE */
|
||||||
@@ -1431,37 +1448,28 @@ yyerrlab:
|
|||||||
#if ! YYERROR_VERBOSE
|
#if ! YYERROR_VERBOSE
|
||||||
yyerror (]b4_yyerror_args[YY_("syntax error"));
|
yyerror (]b4_yyerror_args[YY_("syntax error"));
|
||||||
#else
|
#else
|
||||||
{
|
while (1)
|
||||||
YYSIZE_T yysize = yysyntax_error (0, yystate, yytoken);
|
{
|
||||||
if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
|
int yysyntax_error_status =
|
||||||
{
|
yysyntax_error (&yymsg_alloc, &yymsg, yystate, yytoken);
|
||||||
YYSIZE_T yyalloc = 2 * yysize;
|
if (yysyntax_error_status == 2 && 0 < yymsg_alloc)
|
||||||
if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
|
{
|
||||||
yyalloc = YYSTACK_ALLOC_MAXIMUM;
|
if (yymsg != yymsgbuf)
|
||||||
if (yymsg != yymsgbuf)
|
YYSTACK_FREE (yymsg);
|
||||||
YYSTACK_FREE (yymsg);
|
yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
|
||||||
yymsg = (char *) YYSTACK_ALLOC (yyalloc);
|
if (yymsg)
|
||||||
if (yymsg)
|
continue;
|
||||||
yymsg_alloc = yyalloc;
|
yymsg = yymsgbuf;
|
||||||
else
|
yymsg_alloc = sizeof yymsgbuf;
|
||||||
{
|
}
|
||||||
yymsg = yymsgbuf;
|
if (yysyntax_error_status == 0)
|
||||||
yymsg_alloc = sizeof yymsgbuf;
|
yyerror (]b4_yyerror_args[yymsg);
|
||||||
}
|
else
|
||||||
}
|
yyerror (]b4_yyerror_args[YY_("syntax error"));
|
||||||
|
if (yysyntax_error_status == 2)
|
||||||
if (0 < yysize && yysize <= yymsg_alloc)
|
goto yyexhaustedlab;
|
||||||
{
|
break;
|
||||||
(void) yysyntax_error (yymsg, yystate, yytoken);
|
}
|
||||||
yyerror (]b4_yyerror_args[yymsg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
yyerror (]b4_yyerror_args[YY_("syntax error"));
|
|
||||||
if (yysize != 0)
|
|
||||||
goto yyexhaustedlab;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
722
src/parse-gram.c
722
src/parse-gram.c
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
/* A Bison parser, made by GNU Bison 2.4.404-c6ab. */
|
/* A Bison parser, made by GNU Bison 2.4.425-305c-dirty. */
|
||||||
|
|
||||||
/* Interface for Bison's Yacc-like parsers in C
|
/* Interface for Bison's Yacc-like parsers in C
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
This special exception was added by the Free Software Foundation in
|
This special exception was added by the Free Software Foundation in
|
||||||
version 2.2 of Bison. */
|
version 2.2 of Bison. */
|
||||||
/* "%code requires" blocks. */
|
/* "%code requires" blocks. */
|
||||||
/* Line 1616 of yacc.c */
|
/* Line 1624 of yacc.c */
|
||||||
#line 201 "src/parse-gram.y"
|
#line 201 "src/parse-gram.y"
|
||||||
|
|
||||||
# ifndef PARAM_TYPE
|
# ifndef PARAM_TYPE
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|
||||||
/* Line 1616 of yacc.c */
|
/* Line 1624 of yacc.c */
|
||||||
#line 51 "src/parse-gram.h"
|
#line 51 "src/parse-gram.h"
|
||||||
|
|
||||||
/* Tokens. */
|
/* Tokens. */
|
||||||
@@ -173,7 +173,7 @@
|
|||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
typedef union YYSTYPE
|
typedef union YYSTYPE
|
||||||
{
|
{
|
||||||
/* Line 1616 of yacc.c */
|
/* Line 1624 of yacc.c */
|
||||||
#line 88 "src/parse-gram.y"
|
#line 88 "src/parse-gram.y"
|
||||||
|
|
||||||
assoc assoc;
|
assoc assoc;
|
||||||
@@ -186,13 +186,13 @@ typedef union YYSTYPE
|
|||||||
uniqstr uniqstr;
|
uniqstr uniqstr;
|
||||||
unsigned char character;
|
unsigned char character;
|
||||||
|
|
||||||
/* Line 1616 of yacc.c */
|
/* Line 1624 of yacc.c */
|
||||||
#line 225 "src/parse-gram.y"
|
#line 225 "src/parse-gram.y"
|
||||||
|
|
||||||
param_type param;
|
param_type param;
|
||||||
|
|
||||||
|
|
||||||
/* Line 1616 of yacc.c */
|
/* Line 1624 of yacc.c */
|
||||||
#line 197 "src/parse-gram.h"
|
#line 197 "src/parse-gram.h"
|
||||||
} YYSTYPE;
|
} YYSTYPE;
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
|
|||||||
@@ -1350,16 +1350,13 @@ AT_CLEANUP
|
|||||||
# Imagine the case where YYSTACK_ALLOC_MAXIMUM = YYSIZE_MAXIMUM and an
|
# Imagine the case where YYSTACK_ALLOC_MAXIMUM = YYSIZE_MAXIMUM and an
|
||||||
# invocation of yysyntax_error has caused yymsg_alloc to grow to exactly
|
# invocation of yysyntax_error has caused yymsg_alloc to grow to exactly
|
||||||
# YYSTACK_ALLOC_MAXIMUM (perhaps because the normal doubling of size had
|
# YYSTACK_ALLOC_MAXIMUM (perhaps because the normal doubling of size had
|
||||||
# to be clipped to YYSTACK_ALLOC_MAXIMUM). Now imagine a subsequent
|
# to be clipped to YYSTACK_ALLOC_MAXIMUM). In an old version of yacc.c,
|
||||||
# invocation of yysyntax_error that overflows during its size
|
# a subsequent invocation of yysyntax_error that overflows during its
|
||||||
# calculation and thus returns YYSIZE_MAXIMUM to yyparse. Then, yyparse
|
# size calculation would return YYSIZE_MAXIMUM to yyparse. Then,
|
||||||
# will invoke yyerror using the old contents of yymsg. This bug needs
|
# yyparse would invoke yyerror using the old contents of yymsg.
|
||||||
# to be fixed.
|
|
||||||
|
|
||||||
AT_SETUP([[parse.error=verbose overflow]])
|
AT_SETUP([[parse.error=verbose overflow]])
|
||||||
|
|
||||||
AT_XFAIL_IF([[:]])
|
|
||||||
|
|
||||||
AT_DATA_GRAMMAR([input.y],
|
AT_DATA_GRAMMAR([input.y],
|
||||||
[[%code {
|
[[%code {
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user