mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-21 02:03:03 +00:00
* data/glr.c (yyprocessOneStack): Synchronize the shift for all
stacks, and iterate another stack in order to call user destructors. * tests/glr-regression.at (No users destructors if stack 0 deleted): New test case. (Duplicated user destructor for lookahead): This test now is expected to succeed.
This commit is contained in:
10
ChangeLog
10
ChangeLog
@@ -1,3 +1,13 @@
|
|||||||
|
2005-12-06 "Joel E. Denny" <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
|
* data/glr.c (yyprocessOneStack): Synchronize the shift for all
|
||||||
|
stacks, and iterate another stack in order to call user
|
||||||
|
destructors.
|
||||||
|
* tests/glr-regression.at (No users destructors if stack 0 deleted):
|
||||||
|
New test case.
|
||||||
|
(Duplicated user destructor for lookahead): This test now is expected
|
||||||
|
to succeed.
|
||||||
|
|
||||||
2005-12-01 Paul Eggert <eggert@cs.ucla.edu>
|
2005-12-01 Paul Eggert <eggert@cs.ucla.edu>
|
||||||
|
|
||||||
* NEWS: Document the following change.
|
* NEWS: Document the following change.
|
||||||
|
|||||||
137
data/glr.c
137
data/glr.c
@@ -507,8 +507,8 @@ static const ]b4_int_type_for([b4_stos])[ yystos[] =
|
|||||||
|
|
||||||
# define YY_LOCATION_PRINT(File, Loc) \
|
# define YY_LOCATION_PRINT(File, Loc) \
|
||||||
fprintf (File, "%d.%d-%d.%d", \
|
fprintf (File, "%d.%d-%d.%d", \
|
||||||
(Loc).first_line, (Loc).first_column, \
|
(Loc).first_line, (Loc).first_column, \
|
||||||
(Loc).last_line, (Loc).last_column)
|
(Loc).last_line, (Loc).last_column)
|
||||||
#endif
|
#endif
|
||||||
]],[
|
]],[
|
||||||
#ifndef YYLLOC_DEFAULT
|
#ifndef YYLLOC_DEFAULT
|
||||||
@@ -566,7 +566,7 @@ do { \
|
|||||||
{ \
|
{ \
|
||||||
YYFPRINTF (stderr, "%s ", Title); \
|
YYFPRINTF (stderr, "%s ", Title); \
|
||||||
yysymprint (stderr, \
|
yysymprint (stderr, \
|
||||||
Type, Value]b4_location_if([, Location])[]b4_user_args[); \
|
Type, Value]b4_location_if([, Location])[]b4_user_args[); \
|
||||||
YYFPRINTF (stderr, "\n"); \
|
YYFPRINTF (stderr, "\n"); \
|
||||||
} \
|
} \
|
||||||
} while (/*CONSTCOND*/ 0)
|
} while (/*CONSTCOND*/ 0)
|
||||||
@@ -867,7 +867,7 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
|
|||||||
YYSTYPE* yyvalp,
|
YYSTYPE* yyvalp,
|
||||||
YYLTYPE* YYOPTIONAL_LOC (yylocp),
|
YYLTYPE* YYOPTIONAL_LOC (yylocp),
|
||||||
yyGLRStack* yystack
|
yyGLRStack* yystack
|
||||||
]b4_user_formals[)
|
]b4_user_formals[)
|
||||||
{
|
{
|
||||||
yybool yynormal __attribute__ ((__unused__)) =
|
yybool yynormal __attribute__ ((__unused__)) =
|
||||||
(yystack->yysplitPoint == NULL);
|
(yystack->yysplitPoint == NULL);
|
||||||
@@ -962,15 +962,15 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (yys->yysemantics.yyfirstVal)
|
if (yys->yysemantics.yyfirstVal)
|
||||||
{
|
{
|
||||||
yySemanticOption *yyoption = yys->yysemantics.yyfirstVal;
|
yySemanticOption *yyoption = yys->yysemantics.yyfirstVal;
|
||||||
yyGLRState *yyrh;
|
yyGLRState *yyrh;
|
||||||
int yyn;
|
int yyn;
|
||||||
for (yyrh = yyoption->yystate, yyn = yyrhsLength (yyoption->yyrule);
|
for (yyrh = yyoption->yystate, yyn = yyrhsLength (yyoption->yyrule);
|
||||||
yyn > 0;
|
yyn > 0;
|
||||||
yyrh = yyrh->yypred, yyn -= 1)
|
yyrh = yyrh->yypred, yyn -= 1)
|
||||||
yydestroyGLRState (yymsg, yyrh]b4_user_args[);
|
yydestroyGLRState (yymsg, yyrh]b4_user_args[);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1016,7 +1016,7 @@ yydefaultAction (yyStateNum yystate)
|
|||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
yygetLRActions (yyStateNum yystate, int yytoken,
|
yygetLRActions (yyStateNum yystate, int yytoken,
|
||||||
int* yyaction, const short int** yyconflicts)
|
int* yyaction, const short int** yyconflicts)
|
||||||
{
|
{
|
||||||
int yyindex = yypact[yystate] + yytoken;
|
int yyindex = yypact[yystate] + yytoken;
|
||||||
if (yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
|
if (yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
|
||||||
@@ -1340,7 +1340,7 @@ yydoAction (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
|||||||
= yystack->yytops.yystates[yyk];]b4_location_if([[
|
= yystack->yytops.yystates[yyk];]b4_location_if([[
|
||||||
if (yynrhs == 0)
|
if (yynrhs == 0)
|
||||||
/* Set default location. */
|
/* Set default location. */
|
||||||
yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;]])[
|
yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;]])[
|
||||||
for (yyi = 0; yyi < yynrhs; yyi += 1)
|
for (yyi = 0; yyi < yynrhs; yyi += 1)
|
||||||
{
|
{
|
||||||
yys = yys->yypred;
|
yys = yys->yypred;
|
||||||
@@ -1387,9 +1387,9 @@ yy_reduce_print (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
|||||||
{
|
{
|
||||||
fprintf (stderr, " $%d = ", yyi + 1);
|
fprintf (stderr, " $%d = ", yyi + 1);
|
||||||
yysymprint (stderr, yyrhs[yyprhs[yyrule] + yyi],
|
yysymprint (stderr, yyrhs[yyprhs[yyrule] + yyi],
|
||||||
&]b4_rhs_value(yynrhs, yyi + 1)[
|
&]b4_rhs_value(yynrhs, yyi + 1)[
|
||||||
]b4_location_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
|
]b4_location_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
|
||||||
b4_user_args[);
|
b4_user_args[);
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1408,7 +1408,7 @@ yy_reduce_print (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
|||||||
*/
|
*/
|
||||||
static inline YYRESULTTAG
|
static inline YYRESULTTAG
|
||||||
yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
||||||
yybool yyforceEval]b4_user_formals[)
|
yybool yyforceEval]b4_user_formals[)
|
||||||
{
|
{
|
||||||
size_t yyposn = yystack->yytops.yystates[yyk]->yyposn;
|
size_t yyposn = yystack->yytops.yystates[yyk]->yyposn;
|
||||||
|
|
||||||
@@ -1623,7 +1623,7 @@ yyresolveStates (yyGLRState* yys, int yyn, yyGLRStack* yystack]b4_user_formals[)
|
|||||||
|
|
||||||
static YYRESULTTAG
|
static YYRESULTTAG
|
||||||
yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
|
yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
|
||||||
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
|
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
|
||||||
{
|
{
|
||||||
yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
|
yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
|
||||||
int yynrhs;
|
int yynrhs;
|
||||||
@@ -1748,7 +1748,7 @@ yyresolveValue (yySemanticOption* yyoptionList, yyGLRStack* yystack,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* This cannot happen so it is not worth a YYASSERT (yyfalse),
|
/* This cannot happen so it is not worth a YYASSERT (yyfalse),
|
||||||
but some compilers complain if the default case is
|
but some compilers complain if the default case is
|
||||||
omitted. */
|
omitted. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1827,7 +1827,7 @@ yycompressStack (yyGLRStack* yystack)
|
|||||||
|
|
||||||
static YYRESULTTAG
|
static YYRESULTTAG
|
||||||
yyprocessOneStack (yyGLRStack* yystack, size_t yyk,
|
yyprocessOneStack (yyGLRStack* yystack, size_t yyk,
|
||||||
size_t yyposn, YYSTYPE* yylvalp, YYLTYPE* yyllocp
|
size_t yyposn, YYSTYPE* yylvalp, YYLTYPE* yyllocp
|
||||||
]b4_pure_formals[)
|
]b4_pure_formals[)
|
||||||
{
|
{
|
||||||
int yyaction;
|
int yyaction;
|
||||||
@@ -1880,16 +1880,7 @@ yyprocessOneStack (yyGLRStack* yystack, size_t yyk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (yyisShiftAction (yyaction))
|
if (yyisShiftAction (yyaction))
|
||||||
{
|
break;
|
||||||
YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yyk));
|
|
||||||
YY_SYMBOL_PRINT ("shifting", *yytokenp, yylvalp, yyllocp);
|
|
||||||
yyglrShift (yystack, yyk, yyaction, yyposn+1,
|
|
||||||
*yylvalp, yyllocp);
|
|
||||||
YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
|
|
||||||
(unsigned long int) yyk,
|
|
||||||
yystack->yytops.yystates[yyk]->yylrState));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (yyisErrorAction (yyaction))
|
else if (yyisErrorAction (yyaction))
|
||||||
{
|
{
|
||||||
YYDPRINTF ((stderr, "Stack %lu dies.\n",
|
YYDPRINTF ((stderr, "Stack %lu dies.\n",
|
||||||
@@ -2187,7 +2178,7 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
|||||||
const short int* yyconflicts;
|
const short int* yyconflicts;
|
||||||
|
|
||||||
yyStateNum yystate = yystack.yytops.yystates[0]->yylrState;
|
yyStateNum yystate = yystack.yytops.yystates[0]->yylrState;
|
||||||
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
|
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
|
||||||
if (yystate == YYFINAL)
|
if (yystate == YYFINAL)
|
||||||
goto yyacceptlab;
|
goto yyacceptlab;
|
||||||
if (yyisDefaultedState (yystate))
|
if (yyisDefaultedState (yystate))
|
||||||
@@ -2208,7 +2199,7 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
|||||||
YYDPRINTF ((stderr, "Reading a token: "));
|
YYDPRINTF ((stderr, "Reading a token: "));
|
||||||
yychar = YYLEX;
|
yychar = YYLEX;
|
||||||
yytoken = YYTRANSLATE (yychar);
|
yytoken = YYTRANSLATE (yychar);
|
||||||
YY_SYMBOL_PRINT ("Next token is", yytoken, yylvalp, yyllocp);
|
YY_SYMBOL_PRINT ("Next token is", yytoken, yylvalp, yyllocp);
|
||||||
}
|
}
|
||||||
yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts);
|
yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts);
|
||||||
if (*yyconflicts != 0)
|
if (*yyconflicts != 0)
|
||||||
@@ -2236,14 +2227,59 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
|||||||
|
|
||||||
while (yytrue)
|
while (yytrue)
|
||||||
{
|
{
|
||||||
|
yySymbol yytoken_to_shift;
|
||||||
size_t yys;
|
size_t yys;
|
||||||
size_t yyn = yystack.yytops.yysize;
|
size_t yyn = yystack.yytops.yysize;
|
||||||
|
|
||||||
|
/* yyprocessOneStack returns one of three things:
|
||||||
|
|
||||||
|
- An error flag. If the caller is yyprocessOneStack, it
|
||||||
|
immediately returns as well. When the caller is finally
|
||||||
|
yyparse, it jumps to an error label via YYCHK1.
|
||||||
|
|
||||||
|
- yyok, but yyprocessOneStack has invoked yymarkStackDeleted
|
||||||
|
(&yystack, yys), which sets the top state of yys to NULL. Thus,
|
||||||
|
yyparse's following invocation of yyremoveDeletes will remove
|
||||||
|
the stack.
|
||||||
|
|
||||||
|
- yyok, when ready to shift a token.
|
||||||
|
|
||||||
|
Except in the first case, yyparse will invoke yyremoveDeletes and
|
||||||
|
then shift the next token onto all remaining stacks. This
|
||||||
|
synchronization of the shift (that is, after all preceding
|
||||||
|
reductions on all stacks) helps prevents double destructor calls
|
||||||
|
on yylval in the event of memory exhaustion. */
|
||||||
|
|
||||||
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_lpure_args[));
|
yylvalp, yyllocp]b4_lpure_args[));
|
||||||
|
yyremoveDeletes (&yystack);
|
||||||
|
yyn = yystack.yytops.yysize;
|
||||||
|
|
||||||
|
/* If any yyglrShift call fails, it will fail after shifting. Thus,
|
||||||
|
a copy of yylval will already be on stack 0 in the event of a
|
||||||
|
failure in the following loop. Thus, yytoken is set to YYEMPTY
|
||||||
|
before the loop to make sure the user destructor for yylval isn't
|
||||||
|
called twice. */
|
||||||
|
yytoken_to_shift = yytoken;
|
||||||
yytoken = YYEMPTY;
|
yytoken = YYEMPTY;
|
||||||
yyposn += 1;
|
yyposn += 1;
|
||||||
yyremoveDeletes (&yystack);
|
for (yys = 0; yys < yyn; yys += 1)
|
||||||
|
{
|
||||||
|
int yyaction;
|
||||||
|
const short int* yyconflicts;
|
||||||
|
yyStateNum yystate = yystack.yytops.yystates[yys]->yylrState;
|
||||||
|
yygetLRActions (yystate, yytoken_to_shift, &yyaction,
|
||||||
|
&yyconflicts);
|
||||||
|
/* Note that yyconflicts were handled by yyprocessOneStack. */
|
||||||
|
YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yys));
|
||||||
|
YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, yylvalp, yyllocp);
|
||||||
|
yyglrShift (&yystack, yys, yyaction, yyposn,
|
||||||
|
*yylvalp, yyllocp);
|
||||||
|
YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
|
||||||
|
(unsigned long int) yys,
|
||||||
|
yystack.yytops.yystates[yys]->yylrState));
|
||||||
|
}
|
||||||
if (yystack.yytops.yysize == 0)
|
if (yystack.yytops.yysize == 0)
|
||||||
{
|
{
|
||||||
yyundeleteLastStack (&yystack);
|
yyundeleteLastStack (&yystack);
|
||||||
@@ -2289,7 +2325,7 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
|||||||
yyreturn:
|
yyreturn:
|
||||||
if (yytoken != YYEOF && yytoken != YYEMPTY)
|
if (yytoken != YYEOF && yytoken != YYEMPTY)
|
||||||
yydestruct ("Cleanup: discarding lookahead",
|
yydestruct ("Cleanup: discarding lookahead",
|
||||||
yytoken, yylvalp]b4_location_if([, yyllocp])[]b4_user_args[);
|
yytoken, yylvalp]b4_location_if([, yyllocp])[]b4_user_args[);
|
||||||
|
|
||||||
/* If the stack is well-formed, pop the stack until it is empty,
|
/* If the stack is well-formed, pop the stack until it is empty,
|
||||||
destroying its entries as we go. But free the stack regardless
|
destroying its entries as we go. But free the stack regardless
|
||||||
@@ -2298,15 +2334,24 @@ b4_syncline([@oline@], [@ofile@])])dnl
|
|||||||
{
|
{
|
||||||
yyGLRState** yystates = yystack.yytops.yystates;
|
yyGLRState** yystates = yystack.yytops.yystates;
|
||||||
if (yystates)
|
if (yystates)
|
||||||
while (yystates[0])
|
{
|
||||||
{
|
size_t yysize = yystack.yytops.yysize;
|
||||||
yyGLRState *yys = yystates[0];
|
size_t yyk;
|
||||||
]b4_location_if([[ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
|
for (yyk = 0; yyk < yysize; yyk += 1)
|
||||||
)[ yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
|
if (yystates[yyk])
|
||||||
yystates[0] = yys->yypred;
|
{
|
||||||
yystack.yynextFree -= 1;
|
while (yystates[yyk])
|
||||||
yystack.yyspaceLeft += 1;
|
{
|
||||||
}
|
yyGLRState *yys = yystates[yyk];
|
||||||
|
]b4_location_if([[ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
|
||||||
|
)[ yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
|
||||||
|
yystates[yyk] = yys->yypred;
|
||||||
|
yystack.yynextFree -= 1;
|
||||||
|
yystack.yyspaceLeft += 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
yyfreeGLRStack (&yystack);
|
yyfreeGLRStack (&yystack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2390,7 +2435,7 @@ b4_epilogue
|
|||||||
m4_if(b4_defines_flag, 0, [],
|
m4_if(b4_defines_flag, 0, [],
|
||||||
[@output @output_header_name@
|
[@output @output_header_name@
|
||||||
b4_copyright([Skeleton parser for GLR parsing with Bison],
|
b4_copyright([Skeleton parser for GLR parsing with Bison],
|
||||||
[2002, 2003, 2004, 2005])[
|
[2002, 2003, 2004, 2005])[
|
||||||
|
|
||||||
/* As a special exception, when this parser skeleton is copied by
|
/* As a special exception, when this parser skeleton is copied by
|
||||||
Bison into a Bison output file, you may use that output file
|
Bison into a Bison output file, you may use that output file
|
||||||
|
|||||||
@@ -633,8 +633,6 @@ AT_CHECK([[./glr-regr7]], 2, [],
|
|||||||
[memory exhausted
|
[memory exhausted
|
||||||
])
|
])
|
||||||
|
|
||||||
AT_XFAIL_IF(:)
|
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
|
||||||
@@ -695,7 +693,7 @@ void yyerror(const char *msg)
|
|||||||
|
|
||||||
static int lexIndex;
|
static int lexIndex;
|
||||||
|
|
||||||
int yylex()
|
int yylex (void)
|
||||||
{
|
{
|
||||||
lexIndex += 1;
|
lexIndex += 1;
|
||||||
switch (lexIndex)
|
switch (lexIndex)
|
||||||
@@ -733,3 +731,84 @@ AT_CHECK([[./glr-regr8]], 0,
|
|||||||
[])
|
[])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------------------------------------------------------- ##
|
||||||
|
## No users destructors if stack 0 deleted ##
|
||||||
|
## Thanks to Joel E. Denny for this test; see ##
|
||||||
|
## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>. ##
|
||||||
|
## ------------------------------------------------------------------------- ##
|
||||||
|
|
||||||
|
AT_SETUP([No users destructors if stack 0 deleted])
|
||||||
|
|
||||||
|
AT_DATA_GRAMMAR([glr-regr9.y],
|
||||||
|
[[
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
static void yyerror (char const *);
|
||||||
|
static int yylex (void);
|
||||||
|
#define YYSTACKEXPANDABLE 0
|
||||||
|
static int tokens = 0;
|
||||||
|
static int destructors = 0;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%glr-parser
|
||||||
|
%union { int dummy; }
|
||||||
|
%type <dummy> 'a'
|
||||||
|
|
||||||
|
%destructor {
|
||||||
|
destructors += 1;
|
||||||
|
} 'a'
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
start:
|
||||||
|
ambig0 'a' { destructors += 2; }
|
||||||
|
| ambig1 start { destructors += 1; }
|
||||||
|
| ambig2 start { destructors += 1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
ambig0: 'a' ;
|
||||||
|
ambig1: 'a' ;
|
||||||
|
ambig2: 'a' ;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
static int
|
||||||
|
yylex (void)
|
||||||
|
{
|
||||||
|
tokens += 1;
|
||||||
|
return 'a';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
yyerror (char const *msg)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
int exit_status;
|
||||||
|
exit_status = yyparse ();
|
||||||
|
if (tokens != destructors)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return !exit_status;
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_CHECK([[bison -o glr-regr9.c glr-regr9.y]], 0, [],
|
||||||
|
[glr-regr9.y: conflicts: 1 reduce/reduce
|
||||||
|
])
|
||||||
|
AT_COMPILE([glr-regr9])
|
||||||
|
|
||||||
|
AT_CHECK([[./glr-regr9]], 0, [],
|
||||||
|
[memory exhausted
|
||||||
|
])
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
|
|||||||
Reference in New Issue
Block a user