bison-patches
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]