[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
glr.c: obey the parse.assert %define variable
From: |
Akim Demaille |
Subject: |
glr.c: obey the parse.assert %define variable |
Date: |
Sat, 7 Dec 2019 10:56:20 +0100 |
commit 70daeffc4065c2c187a97cc03b32e925dbf0c369
Author: Akim Demaille <address@hidden>
Date: Sat Dec 7 09:47:54 2019 +0100
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.
diff --git a/NEWS b/NEWS
index 9b0ee9bb..92ffc91c 100644
--- a/NEWS
+++ b/NEWS
@@ -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]
diff --git a/TODO b/TODO
index 5258b72d..ae3a6c96 100644
--- a/TODO
+++ b/TODO
@@ -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.
diff --git a/data/skeletons/glr.c b/data/skeletons/glr.c
index 1f809bb6..467f7db9 100644
--- a/data/skeletons/glr.c
+++ b/data/skeletons/glr.c
@@ -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),
diff --git a/doc/bison.texi b/doc/bison.texi
index 2cb6afc3..032c3ac8 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -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.
diff --git a/tests/glr-regression.at b/tests/glr-regression.at
index 67e3b3f8..3d261ad4 100644
--- a/tests/glr-regression.at
+++ b/tests/glr-regression.at
@@ -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>
@@ -1669,6 +1686,7 @@ AT_DATA_GRAMMAR([input.y],
]AT_YYLEX_DECLARE[
%}
+%define parse.assert
%debug
%glr-parser
@@ -1762,7 +1780,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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- glr.c: obey the parse.assert %define variable,
Akim Demaille <=