glr.c: obey the parse.assert %define variable

* data/skeletons/glr.c (YYASSERT): Rename as...
(YY_ASSERT): this, for consistency with yacc.c, and also to emphasize
the fact that this is not for the end user (YY_ prefix).
* tests/glr-regression.at: Define parse.assert.
This commit is contained in:
Akim Demaille
2019-12-07 09:47:54 +01:00
parent d4a6c3c58a
commit 357336d254
5 changed files with 58 additions and 34 deletions

7
NEWS
View File

@@ -2,6 +2,13 @@ GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?]
** Changes
*** Debugging glr.c and glr.cc
The glr.c skeleton always had asserts to check its own behavior (not the
user's). These assertions are now under the control of the parse.assert
%define variable (disabled by default).
* Noteworthy changes in release 3.4.91 (2019-11-20) [beta]

5
TODO
View File

@@ -2,11 +2,6 @@
** Deprecate YYPRINT
The doc shows it too much.
** glr.c: parse.assert
There are many assertions in glr.c that are there to check the skeleton
itself, not the user code. So it should be under the control of
parse.assert.
** java, d: error.verbose
The code checks dynamically for error.verbose. It should be controlled by
M4.

View File

@@ -311,15 +311,20 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
# define YYLONGJMP(Env, Val) \
do { \
longjmp (Env, Val); \
YYASSERT (0); \
YY_ASSERT (0); \
} while (yyfalse)
#endif
]b4_attribute_define([noreturn])[
#ifndef YYASSERT
# define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0)))
]b4_parse_assert_if([[#ifdef NDEBUG
# define YY_ASSERT(E) ((void) (0 && (E)))
#else
# include <assert.h> /* INFRINGES ON USER NAME SPACE */
# define YY_ASSERT(E) assert (E)
#endif
]],
[[#define YY_ASSERT(E) ((void) (0 && (E)))]])[
/* YYFINAL -- State number of the termination state. */
#define YYFINAL ]b4_final_state_number[
@@ -756,10 +761,7 @@ yyMemoryExhausted (yyGLRStack* yystackp)
static inline const char*
yytokenName (yySymbol yytoken)
{
if (yytoken == YYEMPTY)
return "";
return yytname[yytoken];
return yytoken == YYEMPTY ? "" : yytname[yytoken];
}
#endif
@@ -1090,7 +1092,7 @@ yyaddDeferredAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyGLRState* yystate,
{
yySemanticOption* yynewOption =
&yynewGLRStackItem (yystackp, yyfalse)->yyoption;
YYASSERT (!yynewOption->yyisState);
YY_ASSERT (!yynewOption->yyisState);
yynewOption->yystate = yyrhs;
yynewOption->yyrule = yyrule;
if (yystackp->yytops.yylookaheadNeeds[yyk])
@@ -1336,7 +1338,7 @@ yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yyStateNum yylrState,
ptrdiff_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
{
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
YYASSERT (yynewState->yyisState);
YY_ASSERT (yynewState->yyisState);
yynewState->yylrState = yylrState;
yynewState->yyposn = yyposn;
@@ -1406,7 +1408,7 @@ yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
/* Standard special case: single stack. */
yyGLRStackItem* yyrhs
= YY_REINTERPRET_CAST (yyGLRStackItem*, yystackp->yytops.yystates[yyk]);
YYASSERT (yyk == 0);
YY_ASSERT (yyk == 0);
yystackp->yynextFree -= yynrhs;
yystackp->yyspaceLeft += yynrhs;
yystackp->yytops.yystates[0] = & yystackp->yynextFree[-1].yystate;
@@ -1426,7 +1428,7 @@ yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
for (yyi = 0; yyi < yynrhs; yyi += 1)
{
yys = yys->yypred;
YYASSERT (yys);
YY_ASSERT (yys);
}
yyupdateSplit (yystackp, yys);
yystackp->yytops.yystates[yyk] = yys;
@@ -1482,7 +1484,7 @@ yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
0 < yyn; yyn -= 1)
{
yys = yys->yypred;
YYASSERT (yys);
YY_ASSERT (yys);
}
yyupdateSplit (yystackp, yys);
yynewLRState = yyLRgotoState (yys->yylrState, yylhsNonterm (yyrule));
@@ -1520,7 +1522,7 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
{
if (yystackp->yysplitPoint == YY_NULLPTR)
{
YYASSERT (yyk == 0);
YY_ASSERT (yyk == 0);
yystackp->yysplitPoint = yystackp->yytops.yystates[yyk];
}
if (yystackp->yytops.yycapacity <= yystackp->yytops.yysize)
@@ -1674,7 +1676,7 @@ yyresolveStates (yyGLRState* yys, int yyn,
{
if (0 < yyn)
{
YYASSERT (yys->yypred);
YY_ASSERT (yys->yypred);
YYCHK (yyresolveStates (yys->yypred, yyn-1, yystackp]b4_user_args[));
if (! yys->yyresolved)
YYCHK (yyresolveValue (yys, yystackp]b4_user_args[));
@@ -1807,7 +1809,7 @@ yyresolveLocations (yyGLRState *yys1, int yyn1,
yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
int yynrhs;
yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal;
YYASSERT (yyoption);
YY_ASSERT (yyoption);
yynrhs = yyrhsLength (yyoption->yyrule);
if (0 < yynrhs)
{
@@ -1882,7 +1884,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
yymerge = yyfalse;
break;
default:
/* This cannot happen so it is not worth a YYASSERT (yyfalse),
/* This cannot happen so it is not worth a YY_ASSERT (yyfalse),
but some compilers complain if the default case is
omitted. */
break;
@@ -1985,7 +1987,7 @@ yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
YY_DPRINTF ((stderr, "Stack %ld Entering state %d\n", yyk, yystate));
YYASSERT (yystate != YYFINAL);
YY_ASSERT (yystate != YYFINAL);
if (yyisDefaultedState (yystate))
{
@@ -2492,7 +2494,7 @@ b4_dollar_popdef])[]dnl
goto yyreturn;
yybuglab:
YYASSERT (yyfalse);
YY_ASSERT (yyfalse);
goto yyabortlab;
yyabortlab:
@@ -2586,8 +2588,8 @@ yypdumpstack (yyGLRStack* yystackp)
YY_CAST (long, yyp - yystackp->yyitems)));
if (*YY_REINTERPRET_CAST (yybool *, yyp))
{
YYASSERT (yyp->yystate.yyisState);
YYASSERT (yyp->yyoption.yyisState);
YY_ASSERT (yyp->yystate.yyisState);
YY_ASSERT (yyp->yyoption.yyisState);
YY_FPRINTF ((stderr, "Res: %d, LR State: %d, posn: %ld, pred: %ld",
yyp->yystate.yyresolved, yyp->yystate.yylrState,
YY_CAST (long, yyp->yystate.yyposn),
@@ -2598,8 +2600,8 @@ yypdumpstack (yyGLRStack* yystackp)
}
else
{
YYASSERT (!yyp->yystate.yyisState);
YYASSERT (!yyp->yyoption.yyisState);
YY_ASSERT (!yyp->yystate.yyisState);
YY_ASSERT (!yyp->yyoption.yyisState);
YY_FPRINTF ((stderr, "Option. rule: %d, state: %ld, next: %ld",
yyp->yyoption.yyrule - 1,
YYINDEX (yyp->yyoption.yystate),

View File

@@ -6494,9 +6494,12 @@ Obsoleted by @code{api.namespace}
@deffn Directive {%define parse.assert}
@itemize
@item Languages(s): C++
@item Languages(s): C, C++
@item Purpose: Issue runtime assertions to catch invalid uses.
In C, some important invariants in the implementation of the parser are
checked when this option is enabled.
In C++, when variants are used (@pxref{C++ Variants}), symbols must be
constructed and destroyed properly. This option checks these constraints.

View File

@@ -41,9 +41,9 @@ static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
%}
%define parse.assert
%glr-parser
/* -------- productions ------ */
%%
@@ -128,6 +128,7 @@ AT_DATA_GRAMMAR([glr-regr2a.y],
]AT_YYLEX_DECLARE[
%}
%define parse.assert
%glr-parser
%%
@@ -265,6 +266,7 @@ static int MergeRule (int x0, int x1);
%}
%define parse.assert
%glr-parser
%token BAD_CHAR
@@ -370,6 +372,7 @@ AT_SETUP([Duplicate representation of merged trees])
AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([glr-regr4.y],
[[
%define parse.assert
%union { char *ptr; }
%type <ptr> S A A1 A2 B
%glr-parser
@@ -469,6 +472,7 @@ AT_DATA_GRAMMAR([glr-regr5.y],
enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
%}
%define parse.assert
%glr-parser
%union { int value; }
%type <value> start
@@ -524,6 +528,7 @@ AT_DATA_GRAMMAR([glr-regr6.y],
]AT_YYLEX_DECLARE[
%}
%define parse.assert
%glr-parser
%union { int value; }
%type <value> 'a'
@@ -580,6 +585,7 @@ AT_DATA_GRAMMAR([glr-regr7.y],
static count_node *tail;
%}
%define parse.assert
%glr-parser
%union { count_node *node; }
%type <node> 'a'
@@ -667,6 +673,7 @@ AT_DATA_GRAMMAR([glr-regr8.y],
%token T_PORT
%token T_SIGNAL
%define parse.assert
%glr-parser
%%
@@ -756,6 +763,7 @@ AT_DATA_GRAMMAR([glr-regr9.y],
# define USE(Var)
%}
%define parse.assert
%glr-parser
%union { int dummy; }
%type <dummy> 'a'
@@ -831,6 +839,7 @@ AT_DATA_GRAMMAR([glr-regr10.y],
static char garbage[GARBAGE_SIZE];
%}
%define parse.assert
%glr-parser
%union { char *ptr; }
%type <ptr> start
@@ -884,6 +893,7 @@ AT_DATA_GRAMMAR([glr-regr11.y],
# define USE(val)
%}
%define parse.assert
%glr-parser
%union { int dummy; }
%type <int> 'a'
@@ -934,6 +944,7 @@ AT_SETUP([Leaked semantic values if user action cuts parse])
AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([glr-regr12.y],
[[
%define parse.assert
%glr-parser
%union { int dummy; }
%token PARENT_RHS_AFTER
@@ -1073,6 +1084,7 @@ AT_DATA_GRAMMAR([glr-regr13.y],
#define USE(value)
%}
%define parse.assert
%union { char value; }
%type <value> 'a' 'b'
%glr-parser
@@ -1213,6 +1225,7 @@ AT_DATA_GRAMMAR([glr-regr14.y],
#define USE(value)
%}
%define parse.assert
%type <value> 'a' 'b' 'c' 'd' stack_explosion
%glr-parser
%locations
@@ -1397,6 +1410,7 @@ AT_SETUP([Leaked semantic values when reporting ambiguity])
AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([glr-regr15.y],
[[
%define parse.assert
%glr-parser
%destructor { parent_rhs_before_value = 0; } parent_rhs_before
@@ -1479,6 +1493,7 @@ AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([glr-regr16.y],
[[
%define parse.assert
%glr-parser
%destructor { lookahead_value = 0; } 'b'
@@ -1540,6 +1555,7 @@ AT_BISON_OPTION_PUSHDEFS([%glr-parser %locations %define api.pure])
AT_DATA_GRAMMAR([glr-regr17.y],
[[
%define parse.assert
%glr-parser
%locations
%define api.pure
@@ -1612,7 +1628,8 @@ AT_SETUP([Missed %merge type warnings when LHS type is declared later])
AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([glr-regr18.y],
[[%glr-parser
[[%define parse.assert
%glr-parser
%{
#include <stdlib.h>
@@ -1625,7 +1642,6 @@ AT_DATA_GRAMMAR([glr-regr18.y],
int type2;
int type3;
}
%%
sym1: sym2 %merge<merge> { $$ = $1; } ;
@@ -1661,14 +1677,14 @@ AT_SETUP([Ambiguity reports])
AT_BISON_OPTION_PUSHDEFS([%debug])
AT_DATA_GRAMMAR([input.y],
[[
%{
[[%{
#include <stdio.h>
#include <stdlib.h>
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
%}
%define parse.assert
%debug
%glr-parser
@@ -1762,7 +1778,8 @@ AT_CLEANUP
AT_SETUP([Predicates])
AT_DATA_GRAMMAR([input.y],
[[%glr-parser
[[%define parse.assert
%glr-parser
%define parse.error verbose
%expect-rr 1
%code requires