Rewrite GLR parser to catch more buffer overrun, storage exhaustion,

and size overflow errors.
* data/glr.c: Include <stdio.h> etc. after user prolog, not before,
in case the user prolog sets feature-test macros like _GNU_SOURCE.
(YYSIZEMAX): New macro.
(yystpcpy): New function, taken from yacc.c.
(struct yyGLRStack.yyspaceLeft): Now size_t, not int.
(yyinitGLRStack, yyfreeGLRstack): Remove unnecessary forward decls,
so that we don't have to maintain their signatures.
(yyFail): Check for buffer overflow, by using vsnprintf rather
than vsprintf.  Allocate a bigger buffer if possible.
Report an error if buffer allocation fails.
(yyStackOverflow): New function.
(yyinitStateSet, yyinitGLRStack): Return a boolean indicating whether
the initialization was successful.  It might fail if storage was
exhausted.
(yyexpandGLRStack): Add more checks for storage allocation failure.
Use yyStackOverflow to report failures.
(yymarkStackDeleted, yyglrShift, yyglrShiftDefer, yydoAction):
(yysplitStack, yyprocessOneStack, yyparse, yypstack):
Don't assume stack number fits in int.
(yysplitStack): Check for storage allocation failure.
(yysplitStack, yyprocessOneStack): Add pure_formals, so that we
can print diagnostics on storage allocation failure.  All callers
changed.
(yyresolveValue): Use yybool for boolean.
(yyreportSyntaxError): Check for size-calculation overflow.
This code is taken from yacc.c.
(yyparse): Check for storage allocation errors when allocating
the initial stack.
This commit is contained in:
Paul Eggert
2005-07-05 21:58:37 +00:00
parent 1c59e0a121
commit 63cb01d656
2 changed files with 212 additions and 90 deletions

View File

@@ -1,3 +1,36 @@
2005-07-05 Paul Eggert <eggert@cs.ucla.edu>
Rewrite GLR parser to catch more buffer overrun, storage exhaustion,
and size overflow errors.
* data/glr.c: Include <stdio.h> etc. after user prolog, not before,
in case the user prolog sets feature-test macros like _GNU_SOURCE.
(YYSIZEMAX): New macro.
(yystpcpy): New function, taken from yacc.c.
(struct yyGLRStack.yyspaceLeft): Now size_t, not int.
(yyinitGLRStack, yyfreeGLRstack): Remove unnecessary forward decls,
so that we don't have to maintain their signatures.
(yyFail): Check for buffer overflow, by using vsnprintf rather
than vsprintf. Allocate a bigger buffer if possible.
Report an error if buffer allocation fails.
(yyStackOverflow): New function.
(yyinitStateSet, yyinitGLRStack): Return a boolean indicating whether
the initialization was successful. It might fail if storage was
exhausted.
(yyexpandGLRStack): Add more checks for storage allocation failure.
Use yyStackOverflow to report failures.
(yymarkStackDeleted, yyglrShift, yyglrShiftDefer, yydoAction):
(yysplitStack, yyprocessOneStack, yyparse, yypstack):
Don't assume stack number fits in int.
(yysplitStack): Check for storage allocation failure.
(yysplitStack, yyprocessOneStack): Add pure_formals, so that we
can print diagnostics on storage allocation failure. All callers
changed.
(yyresolveValue): Use yybool for boolean.
(yyreportSyntaxError): Check for size-calculation overflow.
This code is taken from yacc.c.
(yyparse): Check for storage allocation errors when allocating
the initial stack.
2005-07-05 Akim Demaille <akim@epita.fr> 2005-07-05 Akim Demaille <akim@epita.fr>
Extract calc++ from the documentation. Extract calc++ from the documentation.

View File

@@ -142,12 +142,6 @@ b4_copyright([Skeleton parser for GLR parsing with Bison],
[ [
/* This is the parser code for GLR (Generalized LR) parser. */ /* This is the parser code for GLR (Generalized LR) parser. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <setjmp.h>
]b4_identification ]b4_identification
m4_if(b4_prefix[], [yy], [], m4_if(b4_prefix[], [yy], [],
[/* Substitute the variable and function names. */ [/* Substitute the variable and function names. */
@@ -218,6 +212,12 @@ static YYSTYPE yyval_default;
]/* Line __line__ of glr.c. */ ]/* Line __line__ of glr.c. */
b4_syncline([@oline@], [@ofile@]) b4_syncline([@oline@], [@ofile@])
[ [
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <setjmp.h>
#ifndef YYFREE #ifndef YYFREE
# define YYFREE free # define YYFREE free
#endif #endif
@@ -228,6 +228,8 @@ b4_syncline([@oline@], [@ofile@])
# define YYREALLOC realloc # define YYREALLOC realloc
#endif #endif
#define YYSIZEMAX ((size_t) -1)
#ifdef __cplusplus #ifdef __cplusplus
typedef bool yybool; typedef bool yybool;
#else #else
@@ -549,7 +551,7 @@ int yydebug;
/* Minimum number of free items on the stack allowed after an /* Minimum number of free items on the stack allowed after an
allocation. This is to allow allocation and initialization allocation. This is to allow allocation and initialization
to be completed by functions that call expandGLRStack before the to be completed by functions that call yyexpandGLRStack before the
stack is expanded, thus insuring that all necessary pointers get stack is expanded, thus insuring that all necessary pointers get
properly redirected to new data. */ properly redirected to new data. */
#define YYHEADROOM 2 #define YYHEADROOM 2
@@ -563,6 +565,30 @@ int yydebug;
#define YYSTACKEXPANDABLE 0 #define YYSTACKEXPANDABLE 0
#endif #endif
#if YYERROR_VERBOSE
# ifndef yystpcpy
# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
# define yystpcpy stpcpy
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
static char *
yystpcpy (char *yydest, const char *yysrc)
{
char *yyd = yydest;
const char *yys = yysrc;
while ((*yyd++ = *yys++) != '\0')
continue;
return yyd - 1;
}
# endif
# endif
#endif /* !YYERROR_VERBOSE */
/** State numbers, as in LALR(1) machine */ /** State numbers, as in LALR(1) machine */
typedef int yyStateNum; typedef int yyStateNum;
@@ -643,15 +669,13 @@ struct yyGLRStack {
jmp_buf yyexception_buffer; jmp_buf yyexception_buffer;
yyGLRStackItem* yyitems; yyGLRStackItem* yyitems;
yyGLRStackItem* yynextFree; yyGLRStackItem* yynextFree;
int yyspaceLeft; size_t yyspaceLeft;
yyGLRState* yysplitPoint; yyGLRState* yysplitPoint;
yyGLRState* yylastDeleted; yyGLRState* yylastDeleted;
yyGLRStateSet yytops; yyGLRStateSet yytops;
}; };
static void yyinitGLRStack (yyGLRStack* yystack, size_t yysize);
static void yyexpandGLRStack (yyGLRStack* yystack]b4_pure_formals[); static void yyexpandGLRStack (yyGLRStack* yystack]b4_pure_formals[);
static void yyfreeGLRStack (yyGLRStack* yystack);
static void static void
yyFail (yyGLRStack* yystack]b4_pure_formals[, const char* yyformat, ...) yyFail (yyGLRStack* yystack]b4_pure_formals[, const char* yyformat, ...)
@@ -659,18 +683,43 @@ yyFail (yyGLRStack* yystack]b4_pure_formals[, const char* yyformat, ...)
yystack->yyerrflag = 1; yystack->yyerrflag = 1;
if (yyformat != NULL) if (yyformat != NULL)
{ {
char yymsg[256]; char yysmallbuf[1024];
char const *yymsg = yysmallbuf;
char *yybigbuf = NULL;
int yymsglen;
va_list yyap; va_list yyap;
va_start (yyap, yyformat); va_start (yyap, yyformat);
vsprintf (yymsg, yyformat, yyap); yymsglen = vsnprintf (yysmallbuf, sizeof yysmallbuf, yyformat, yyap);
va_end (yyap);
if (yymsglen < 0)
yymsg = "message is too long to be printed";
else if (sizeof yysmallbuf <= yymsglen && yymsglen < YYSIZEMAX)
{
size_t yybigsize = yymsglen;
yybigsize++;
yymsg = yybigbuf = YYMALLOC (yybigsize);
va_start (yyap, yyformat);
vsnprintf (yybigbuf, yybigsize, yyformat, yyap);
va_end (yyap);
}
yyerror (]b4_yyerror_args[yymsg); yyerror (]b4_yyerror_args[yymsg);
YYFREE (yybigbuf);
} }
longjmp (yystack->yyexception_buffer, 1); longjmp (yystack->yyexception_buffer, 1);
} }
static void
yyStackOverflow (yyGLRStack* yystack]b4_pure_formals[)
{
yyFail (yystack]b4_pure_args[, "parser stack overflow");
}
#if YYDEBUG || YYERROR_VERBOSE #if YYDEBUG || YYERROR_VERBOSE
/** A printable representation of TOKEN. Valid until next call to /** A printable representation of TOKEN. */
* tokenName. */
static inline const char* static inline const char*
yytokenName (yySymbol yytoken) yytokenName (yySymbol yytoken)
{ {
@@ -909,13 +958,16 @@ yyaddDeferredAction (yyGLRStack* yystack, yyGLRState* yystate,
/* GLRStacks */ /* GLRStacks */
/** Initialize SET to a singleton set containing an empty stack. */ /** Initialize SET to a singleton set containing an empty stack. */
static void static yybool
yyinitStateSet (yyGLRStateSet* yyset) yyinitStateSet (yyGLRStateSet* yyset)
{ {
yyset->yysize = 1; yyset->yysize = 1;
yyset->yycapacity = 16; yyset->yycapacity = 16;
yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]); yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]);
if (! yyset->yystates)
return yyfalse;
yyset->yystates[0] = NULL; yyset->yystates[0] = NULL;
return yytrue;
} }
static void yyfreeStateSet (yyGLRStateSet* yyset) static void yyfreeStateSet (yyGLRStateSet* yyset)
@@ -925,7 +977,7 @@ static void yyfreeStateSet (yyGLRStateSet* yyset)
/** Initialize STACK to a single empty stack, with total maximum /** Initialize STACK to a single empty stack, with total maximum
* capacity for all stacks of SIZE. */ * capacity for all stacks of SIZE. */
static void static yybool
yyinitGLRStack (yyGLRStack* yystack, size_t yysize) yyinitGLRStack (yyGLRStack* yystack, size_t yysize)
{ {
yystack->yyerrflag = 0; yystack->yyerrflag = 0;
@@ -936,7 +988,7 @@ yyinitGLRStack (yyGLRStack* yystack, size_t yysize)
(yyGLRStackItem*) YYMALLOC (yysize * sizeof yystack->yynextFree[0]); (yyGLRStackItem*) YYMALLOC (yysize * sizeof yystack->yynextFree[0]);
yystack->yysplitPoint = NULL; yystack->yysplitPoint = NULL;
yystack->yylastDeleted = NULL; yystack->yylastDeleted = NULL;
yyinitStateSet (&yystack->yytops); return yyinitStateSet (&yystack->yytops) && yystack->yyitems;
} }
#define YYRELOC(YYFROMITEMS,YYTOITEMS,YYX,YYTYPE) \ #define YYRELOC(YYFROMITEMS,YYTOITEMS,YYX,YYTYPE) \
@@ -951,18 +1003,20 @@ static void
yyexpandGLRStack (yyGLRStack* yystack]b4_pure_formals[) yyexpandGLRStack (yyGLRStack* yystack]b4_pure_formals[)
{ {
#if YYSTACKEXPANDABLE #if YYSTACKEXPANDABLE
yyGLRStack yynewStack; yyGLRStackItem* yynewItems;
yyGLRStackItem* yyp0, *yyp1; yyGLRStackItem* yyp0, *yyp1;
size_t yysize, yynewSize; size_t yysize, yynewSize;
size_t yyn; size_t yyn;
yysize = yystack->yynextFree - yystack->yyitems; yysize = yystack->yynextFree - yystack->yyitems;
if (YYMAXDEPTH <= yysize) if (YYMAXDEPTH <= yysize)
yyFail (yystack][]b4_pure_args[, "parser stack overflow"); yyStackOverflow (yystack]b4_pure_args[);
yynewSize = 2*yysize; yynewSize = 2*yysize;
if (YYMAXDEPTH < yynewSize) if (YYMAXDEPTH < yynewSize)
yynewSize = YYMAXDEPTH; yynewSize = YYMAXDEPTH;
yyinitGLRStack (&yynewStack, yynewSize); yynewItems = (yyGLRStackItem*) YYMALLOC (yynewSize * sizeof yynewItems[0]);
for (yyp0 = yystack->yyitems, yyp1 = yynewStack.yyitems, yyn = yysize; if (! yynewItems)
yyStackOverflow (yystack]b4_pure_args[);
for (yyp0 = yystack->yyitems, yyp1 = yynewItems, yyn = yysize;
0 < yyn; 0 < yyn;
yyn -= 1, yyp0 += 1, yyp1 += 1) yyn -= 1, yyp0 += 1, yyp1 += 1)
{ {
@@ -989,22 +1043,22 @@ yyexpandGLRStack (yyGLRStack* yystack]b4_pure_formals[)
} }
} }
if (yystack->yysplitPoint != NULL) if (yystack->yysplitPoint != NULL)
yystack->yysplitPoint = YYRELOC (yystack->yyitems, yynewStack.yyitems, yystack->yysplitPoint = YYRELOC (yystack->yyitems, yynewItems,
yystack->yysplitPoint, yystate); yystack->yysplitPoint, yystate);
for (yyn = 0; yyn < yystack->yytops.yysize; yyn += 1) for (yyn = 0; yyn < yystack->yytops.yysize; yyn += 1)
if (yystack->yytops.yystates[yyn] != NULL) if (yystack->yytops.yystates[yyn] != NULL)
yystack->yytops.yystates[yyn] = yystack->yytops.yystates[yyn] =
YYRELOC (yystack->yyitems, yynewStack.yyitems, YYRELOC (yystack->yyitems, yynewItems,
yystack->yytops.yystates[yyn], yystate); yystack->yytops.yystates[yyn], yystate);
YYFREE (yystack->yyitems); YYFREE (yystack->yyitems);
yystack->yyitems = yynewStack.yyitems; yystack->yyitems = yynewItems;
yystack->yynextFree = yynewStack.yynextFree + yysize; yystack->yynextFree = yynewItems + yysize;
yystack->yyspaceLeft = yynewStack.yyspaceLeft - yysize; yystack->yyspaceLeft = yynewSize - yysize;
#else #else
yyFail (yystack][]b4_pure_args[, "parser stack overflow"); yyStackOverflow (yystack]b4_pure_args[);
#endif #endif
} }
@@ -1027,7 +1081,7 @@ yyupdateSplit (yyGLRStack* yystack, yyGLRState* yys)
/** Invalidate stack #K in STACK. */ /** Invalidate stack #K in STACK. */
static inline void static inline void
yymarkStackDeleted (yyGLRStack* yystack, int yyk) yymarkStackDeleted (yyGLRStack* yystack, size_t yyk)
{ {
if (yystack->yytops.yystates[yyk] != NULL) if (yystack->yytops.yystates[yyk] != NULL)
yystack->yylastDeleted = yystack->yytops.yystates[yyk]; yystack->yylastDeleted = yystack->yytops.yystates[yyk];
@@ -1080,7 +1134,8 @@ yyremoveDeletes (yyGLRStack* yystack)
/** Shift to a new state on stack #K of STACK, corresponding to LR state /** Shift to a new state on stack #K of STACK, corresponding to LR state
* LRSTATE, at input position POSN, with (resolved) semantic value SVAL. */ * LRSTATE, at input position POSN, with (resolved) semantic value SVAL. */
static inline void static inline void
yyglrShift (yyGLRStack* yystack, int yyk, yyStateNum yylrState, size_t yyposn, yyglrShift (yyGLRStack* yystack, size_t yyk, yyStateNum yylrState,
size_t yyposn,
YYSTYPE yysval, YYLTYPE* yylocp]b4_user_formals[) YYSTYPE yysval, YYLTYPE* yylocp]b4_user_formals[)
{ {
yyGLRStackItem* yynewItem; yyGLRStackItem* yynewItem;
@@ -1104,7 +1159,7 @@ yyglrShift (yyGLRStack* yystack, int yyk, yyStateNum yylrState, size_t yyposn,
* state YYLRSTATE, at input position YYPOSN, with the (unresolved) * state YYLRSTATE, at input position YYPOSN, with the (unresolved)
* semantic value of YYRHS under the action for YYRULE. */ * semantic value of YYRHS under the action for YYRULE. */
static inline void static inline void
yyglrShiftDefer (yyGLRStack* yystack, int yyk, yyStateNum yylrState, yyglrShiftDefer (yyGLRStack* yystack, size_t yyk, yyStateNum yylrState,
size_t yyposn, yyGLRState* rhs, yyRuleNum yyrule]b4_pure_formals[) size_t yyposn, yyGLRState* rhs, yyRuleNum yyrule]b4_pure_formals[)
{ {
yyGLRStackItem* yynewItem; yyGLRStackItem* yynewItem;
@@ -1129,7 +1184,7 @@ yyglrShiftDefer (yyGLRStack* yystack, int yyk, yyStateNum yylrState,
* and *LOCP to the computed location (if any). Return value is as * and *LOCP to the computed location (if any). Return value is as
* for userAction. */ * for userAction. */
static inline YYRESULTTAG static inline YYRESULTTAG
yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule, yydoAction (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[) YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
{ {
int yynrhs = yyrhsLength (yyrule); int yynrhs = yyrhsLength (yyrule);
@@ -1263,8 +1318,8 @@ yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
return yyok; return yyok;
} }
static int static size_t
yysplitStack (yyGLRStack* yystack, int yyk) yysplitStack (yyGLRStack* yystack, size_t yyk]b4_pure_formals[)
{ {
if (yystack->yysplitPoint == NULL) if (yystack->yysplitPoint == NULL)
{ {
@@ -1273,11 +1328,15 @@ yysplitStack (yyGLRStack* yystack, int yyk)
} }
if (yystack->yytops.yysize >= yystack->yytops.yycapacity) if (yystack->yytops.yysize >= yystack->yytops.yycapacity)
{ {
yystack->yytops.yycapacity *= 2; yyGLRState** yynewStates;
yystack->yytops.yystates = if (! ((yystack->yytops.yycapacity
(yyGLRState**) YYREALLOC (yystack->yytops.yystates, <= (YYSIZEMAX / (2 * sizeof yynewStates[0])))
(yystack->yytops.yycapacity && (yynewStates =
* sizeof yystack->yytops.yystates[0])); (yyGLRState**) YYREALLOC (yystack->yytops.yystates,
((yystack->yytops.yycapacity *= 2)
* sizeof yynewStates[0])))))
yyStackOverflow (yystack]b4_pure_args[);
yystack->yytops.yystates = yynewStates;
} }
yystack->yytops.yystates[yystack->yytops.yysize] yystack->yytops.yystates[yystack->yytops.yysize]
= yystack->yytops.yystates[yyk]; = yystack->yytops.yystates[yyk];
@@ -1503,10 +1562,10 @@ yyresolveValue (yySemanticOption* yyoptionList, yyGLRStack* yystack,
{ {
yySemanticOption* yybest; yySemanticOption* yybest;
yySemanticOption* yyp; yySemanticOption* yyp;
int yymerge; yybool yymerge;
yybest = yyoptionList; yybest = yyoptionList;
yymerge = 0; yymerge = yyfalse;
for (yyp = yyoptionList->yynext; yyp != NULL; yyp = yyp->yynext) for (yyp = yyoptionList->yynext; yyp != NULL; yyp = yyp->yynext)
{ {
if (yyidenticalOptions (yybest, yyp)) if (yyidenticalOptions (yybest, yyp))
@@ -1518,13 +1577,13 @@ yyresolveValue (yySemanticOption* yyoptionList, yyGLRStack* yystack,
yyreportAmbiguity (yybest, yyp, yystack]b4_pure_args[); yyreportAmbiguity (yybest, yyp, yystack]b4_pure_args[);
break; break;
case 1: case 1:
yymerge = 1; yymerge = yytrue;
break; break;
case 2: case 2:
break; break;
case 3: case 3:
yybest = yyp; yybest = yyp;
yymerge = 0; yymerge = yyfalse;
break; break;
} }
} }
@@ -1598,9 +1657,9 @@ yycompressStack (yyGLRStack* yystack)
} }
static YYRESULTTAG static YYRESULTTAG
yyprocessOneStack (yyGLRStack* yystack, int yyk, yyprocessOneStack (yyGLRStack* yystack, size_t yyk,
size_t yyposn, YYSTYPE* yylvalp, YYLTYPE* yyllocp size_t yyposn, YYSTYPE* yylvalp, YYLTYPE* yyllocp
]b4_user_formals[) ]b4_pure_formals[)
{ {
int yyaction; int yyaction;
const short int* yyconflicts; const short int* yyconflicts;
@@ -1610,7 +1669,8 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
while (yystack->yytops.yystates[yyk] != NULL) while (yystack->yytops.yystates[yyk] != NULL)
{ {
yyStateNum yystate = yystack->yytops.yystates[yyk]->yylrState; yyStateNum yystate = yystack->yytops.yystates[yyk]->yylrState;
YYDPRINTF ((stderr, "Stack %d Entering state %d\n", yyk, yystate)); YYDPRINTF ((stderr, "Stack %lu Entering state %d\n",
(unsigned long int) yyk, yystate));
YYASSERT (yystate != YYFINAL); YYASSERT (yystate != YYFINAL);
@@ -1619,7 +1679,8 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
yyrule = yydefaultAction (yystate); yyrule = yydefaultAction (yystate);
if (yyrule == 0) if (yyrule == 0)
{ {
YYDPRINTF ((stderr, "Stack %d dies.\n", yyk)); YYDPRINTF ((stderr, "Stack %lu dies.\n",
(unsigned long int) yyk));
yymarkStackDeleted (yystack, yyk); yymarkStackDeleted (yystack, yyk);
return yyok; return yyok;
} }
@@ -1639,19 +1700,20 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
while (*yyconflicts != 0) while (*yyconflicts != 0)
{ {
int yynewStack = yysplitStack (yystack, yyk); size_t yynewStack = yysplitStack (yystack, yyk]b4_pure_args[);
YYDPRINTF ((stderr, "Splitting off stack %d from %d.\n", YYDPRINTF ((stderr, "Splitting off stack %lu from %lu.\n",
yynewStack, yyk)); (unsigned long int) yynewStack,
(unsigned long int) yyk));
YYCHK (yyglrReduce (yystack, yynewStack, YYCHK (yyglrReduce (yystack, yynewStack,
*yyconflicts, yyfalse]b4_lpure_args[)); *yyconflicts, yyfalse]b4_lpure_args[));
YYCHK (yyprocessOneStack (yystack, yynewStack, yyposn, YYCHK (yyprocessOneStack (yystack, yynewStack, yyposn,
yylvalp, yyllocp]b4_user_args[)); yylvalp, yyllocp]b4_pure_args[));
yyconflicts += 1; yyconflicts += 1;
} }
if (yyisShiftAction (yyaction)) if (yyisShiftAction (yyaction))
{ {
YYDPRINTF ((stderr, "On stack %d, ", yyk)); YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yyk));
YY_SYMBOL_PRINT ("shifting", *yytokenp, yylvalp, yyllocp); YY_SYMBOL_PRINT ("shifting", *yytokenp, yylvalp, yyllocp);
yyglrShift (yystack, yyk, yyaction, yyposn+1, yyglrShift (yystack, yyk, yyaction, yyposn+1,
*yylvalp, yyllocp]b4_user_args[); *yylvalp, yyllocp]b4_user_args[);
@@ -1661,7 +1723,8 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
} }
else if (yyisErrorAction (yyaction)) else if (yyisErrorAction (yyaction))
{ {
YYDPRINTF ((stderr, "Stack %d dies.\n", yyk)); YYDPRINTF ((stderr, "Stack %lu dies.\n",
(unsigned long int) yyk));
yymarkStackDeleted (yystack, yyk); yymarkStackDeleted (yystack, yyk);
break; break;
} }
@@ -1688,10 +1751,24 @@ yyreportSyntaxError (yyGLRStack* yystack,
yyn = yypact[yystack->yytops.yystates[0]->yylrState]; yyn = yypact[yystack->yytops.yystates[0]->yylrState];
if (YYPACT_NINF < yyn && yyn < YYLAST) if (YYPACT_NINF < yyn && yyn < YYLAST)
{ {
size_t yysize = 0; size_t yysize0 = strlen (yytokenName (*yytokenp));
const char* yyprefix; size_t yysize = yysize0;
char* yymsg; size_t yysize1;
yybool yysize_overflow = yyfalse;
char* yymsg = NULL;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
int yyx; int yyx;
char *yyfmt;
char const *yyf;
static char const yyunexpected[] = "syntax error, unexpected %s";
static char const yyexpecting[] = ", expecting %s";
static char const yyor[] = " or %s";
char yyformat[sizeof yyunexpected
+ sizeof yyexpecting - 1
+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
* (sizeof yyor - 1))];
char const *yyprefix = yyexpecting;
/* Start YYX at -YYN if negative to avoid negative indexes in /* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */ YYCHECK. */
@@ -1700,41 +1777,53 @@ yyreportSyntaxError (yyGLRStack* yystack,
/* Stay within bounds of both yycheck and yytname. */ /* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn; int yychecklim = YYLAST - yyn;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yycount = 0; int yycount = 1;
yyarg[0] = yytokenName (*yytokenp);
yyfmt = yystpcpy (yyformat, yyunexpected);
yyprefix = ", expecting ";
for (yyx = yyxbegin; yyx < yyxend; ++yyx) for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{ {
yysize += strlen (yyprefix) + strlen (yytokenName (yyx)); if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
yycount += 1;
if (yycount == 5)
{ {
yysize = 0; yycount = 1;
yysize = yysize0;
yyformat[sizeof yyunexpected - 1] = '\0';
break; break;
} }
yyprefix = " or "; yyarg[yycount++] = yytokenName (yyx);
yysize1 = yysize + strlen (yytokenName (yyx));
yysize_overflow |= yysize1 < yysize;
yysize = yysize1;
yyfmt = yystpcpy (yyfmt, yyprefix);
yyprefix = yyor;
} }
yysize += (sizeof ("syntax error, unexpected ")
+ strlen (yytokenName (*yytokenp))); yyf = yyformat;
yymsg = (char*) YYMALLOC (yysize); yysize1 = yysize + (yyfmt - yyformat);
if (yymsg != 0) yysize_overflow |= yysize1 < yysize;
yysize = yysize1;
if (!yysize_overflow)
yymsg = (char *) YYMALLOC (yysize);
if (yymsg)
{ {
char* yyp = yymsg; char *yyp = yymsg;
sprintf (yyp, "syntax error%s%s", int yyi = 0;
(*yytokenp == YYEMPTY ? "" : ", unexpected "), while ((*yyp = *yyf))
yytokenName (*yytokenp));
yyp += strlen (yyp);
if (yycount < 5)
{ {
yyprefix = ", expecting "; if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
for (yyx = yyxbegin; yyx < yyxend; ++yyx) {
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) yyp = yystpcpy (yyp, yyarg[yyi++]);
{ yyf += 2;
sprintf (yyp, "%s%s", yyprefix, yytokenName (yyx)); }
yyp += strlen (yyp); else
yyprefix = " or "; {
} yyp++;
yyf++;
}
} }
yyerror (]b4_lyyerror_args[yymsg); yyerror (]b4_lyyerror_args[yymsg);
YYFREE (yymsg); YYFREE (yymsg);
@@ -1884,7 +1973,7 @@ yyrecoverSyntaxError (yyGLRStack* yystack,
]b4_c_ansi_function_def([yyparse], [int], b4_parse_param)[ ]b4_c_ansi_function_def([yyparse], [int], b4_parse_param)[
{ {
yySymbol yytoken; yySymbol yytoken = YYEMPTY;
yyGLRStack yystack; yyGLRStack yystack;
size_t yyposn; size_t yyposn;
]b4_pure_if( ]b4_pure_if(
@@ -1898,14 +1987,15 @@ yyrecoverSyntaxError (yyGLRStack* yystack,
YYSTYPE* const yylvalp = &yylval; YYSTYPE* const yylvalp = &yylval;
YYLTYPE* const yyllocp = &yylloc; YYLTYPE* const yyllocp = &yylloc;
yyinitGLRStack (&yystack, YYINITDEPTH);
yystack.yytokenp = &yytoken;
YYDPRINTF ((stderr, "Starting parse\n")); YYDPRINTF ((stderr, "Starting parse\n"));
if (setjmp (yystack.yyexception_buffer) != 0) if (setjmp (yystack.yyexception_buffer) != 0)
goto yyDone; goto yyDone;
if (! yyinitGLRStack (&yystack, YYINITDEPTH))
goto yyDone;
yystack.yytokenp = &yytoken;
yylval = yyval_default; yylval = yyval_default;
]b4_location_if([ ]b4_location_if([
#if YYLTYPE_IS_TRIVIAL #if YYLTYPE_IS_TRIVIAL
@@ -1924,7 +2014,6 @@ m4_popdef([b4_at_dollar])dnl
b4_syncline([@oline@], [@ofile@])])dnl b4_syncline([@oline@], [@ofile@])])dnl
[ [
yyglrShift (&yystack, 0, 0, 0, yylval, &yylloc]b4_user_args[); yyglrShift (&yystack, 0, 0, 0, yylval, &yylloc]b4_user_args[);
yytoken = YYEMPTY;
yyposn = 0; yyposn = 0;
while (yytrue) while (yytrue)
@@ -1992,11 +2081,11 @@ b4_syncline([@oline@], [@ofile@])])dnl
while (yytrue) while (yytrue)
{ {
int yys; size_t yys;
int yyn = yystack.yytops.yysize; size_t yyn = yystack.yytops.yysize;
for (yys = 0; yys < yyn; yys += 1) for (yys = 0; yys < yyn; yys += 1)
YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn, YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn,
yylvalp, yyllocp]b4_user_args[)); yylvalp, yyllocp]b4_lpure_args[));
yytoken = YYEMPTY; yytoken = YYEMPTY;
yyposn += 1; yyposn += 1;
yyremoveDeletes (&yystack); yyremoveDeletes (&yystack);
@@ -2036,7 +2125,7 @@ b4_syncline([@oline@], [@ofile@])])dnl
/* DEBUGGING ONLY */ /* DEBUGGING ONLY */
#ifdef YYDEBUG #ifdef YYDEBUG
static void yypstack (yyGLRStack* yystack, int yyk) ATTRIBUTE_UNUSED; static void yypstack (yyGLRStack* yystack, size_t yyk) ATTRIBUTE_UNUSED;
static void yypdumpstack (yyGLRStack* yystack) ATTRIBUTE_UNUSED; static void yypdumpstack (yyGLRStack* yystack) ATTRIBUTE_UNUSED;
static void static void
@@ -2061,7 +2150,7 @@ yypstates (yyGLRState* yyst)
} }
static void static void
yypstack (yyGLRStack* yystack, int yyk) yypstack (yyGLRStack* yystack, size_t yyk)
{ {
yypstates (yystack->yytops.yystates[yyk]); yypstates (yystack->yytops.yystates[yyk]);
} }