bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 7/9] glr2.cc: make yyparse a member function


From: Akim Demaille
Subject: [PATCH 7/9] glr2.cc: make yyparse a member function
Date: Sun, 13 Dec 2020 08:49:25 +0100

Amusingly enough, glr2.cc still had its core function, yyparse, being
a free function instead of a member function.

* data/skeletons/glr2.cc (yyparse): Remove this free function called
from yyparser::parse.  Inline its body into...
(yyparser::parse): this member function.
This requires moving a bit the yychar, etc. macros.
Access to token can be simplified (the
b4_namespace_ref::b4_parser_class prefix is no longer needed).
---
 data/skeletons/glr2.cc | 382 +++++++++++++++++++----------------------
 1 file changed, 180 insertions(+), 202 deletions(-)

diff --git a/data/skeletons/glr2.cc b/data/skeletons/glr2.cc
index 6fce8445..78fdf45a 100644
--- a/data/skeletons/glr2.cc
+++ b/data/skeletons/glr2.cc
@@ -2849,189 +2849,6 @@ yypreference (const semantic_option& y0, const 
semantic_option& y1)
   } while (0)
 
 
-/*----------.
-| yyparse.  |
-`----------*/
-
-int
-yyparse (]b4_namespace_ref[::]b4_parser_class[& yyparser]b4_user_formals[)
-{
-  int yyresult;
-  glr_stack yystack(YYINITDEPTH, yyparser]b4_user_args[);
-  glr_stack* const yystackp = &yystack;
-  size_t yyposn;
-
-  YY_DEBUG_STREAM << "Starting parse\n";
-
-  yychar = ]b4_namespace_ref::b4_parser_class::token::b4_symbol(empty, id)[;
-  yylval = yyval_default;]b4_locations_if([
-  yylloc = yyloc_default;])[
-]m4_ifdef([b4_initial_action], [
-b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
-  b4_user_initial_action
-b4_dollar_popdef])[]dnl
-[
-  switch (YYSETJMP (yystack.yyexception_buffer))
-    {
-    case 0: break;
-    case 1: goto yyabortlab;
-    case 2: goto yyexhaustedlab;
-    default: goto yybuglab;
-    }
-  yystack.yyglrShift (create_state_set_index(0), 0, 0, 
yylval]b4_locations_if([, &yylloc])[);
-  yyposn = 0;
-
-  while (true)
-    {
-      /* For efficiency, we have two loops, the first of which is
-         specialized to deterministic operation (single stack, no
-         potential ambiguity).  */
-      /* Standard mode */
-      while (true)
-        {
-          const state_num yystate = yystack.firstTopState()->yylrState;
-          YY_DEBUG_STREAM << "Entering state " << yystate << "\n";
-          if (yystate == YYFINAL)
-            goto yyacceptlab;
-          if (yyisDefaultedState (yystate))
-            {
-              const rule_num yyrule = yydefaultAction (yystate);
-              if (yyrule == 0)
-                {]b4_locations_if([[
-                  yystack.yyerror_range[1].getState().yyloc = yylloc;]])[
-                  yystack.yyreportSyntaxError ();
-                  goto yyuser_error;
-                }
-              YYCHK1 (yystack.yyglrReduce (create_state_set_index(0), yyrule, 
true));
-            }
-          else
-            {
-              const yysymbol_kind_t yytoken = ]b4_yygetToken_call[;
-              const short* yyconflicts;
-              const int yyaction = yygetLRActions (yystate, yytoken, 
yyconflicts);
-              if (*yyconflicts != 0)
-                break;
-              if (yyisShiftAction (yyaction))
-                {
-                  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-                  yychar = 
]b4_namespace_ref::b4_parser_class::token::b4_symbol(empty, id)[;
-                  yyposn += 1;
-                  yystack.yyglrShift (create_state_set_index(0), yyaction, 
yyposn, yylval]b4_locations_if([, &yylloc])[);
-                  if (0 < yystack.yyerrState)
-                    yystack.yyerrState -= 1;
-                }
-              else if (yyisErrorAction (yyaction))
-                {]b4_locations_if([[
-                  yystack.yyerror_range[1].getState().yyloc = yylloc;]])[
-                  /* Don't issue an error message again for exceptions
-                     thrown from the scanner.  */
-                  if (yychar != 
]b4_namespace_ref::b4_parser_class::token::b4_symbol(error, id)[)
-                    yystack.yyreportSyntaxError ();
-                  goto yyuser_error;
-                }
-              else
-                YYCHK1 (yystack.yyglrReduce (create_state_set_index(0), 
-yyaction, true));
-            }
-        }
-
-      while (true)
-        {
-          for (state_set_index yys = create_state_set_index(0); yys.uget() < 
yystack.yystateStack.numTops(); ++yys)
-            yystackp->yystateStack.yytops.setLookaheadNeeds(yys, yychar != 
]b4_namespace_ref::b4_parser_class::token::b4_symbol(empty, id)[);
-
-          /* 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
-                (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 prevent double destructor calls
-             on yylval in the event of memory exhaustion.  */
-
-          for (state_set_index yys = create_state_set_index(0); yys.uget() < 
yystack.yystateStack.numTops(); ++yys)
-            YYCHK1 (yystack.yyprocessOneStack (yys, yyposn]b4_locations_if([, 
&yylloc])[));
-          yystack.yystateStack.yytops.yyremoveDeletes ();
-          if (yystack.yystateStack.yytops.size() == 0)
-            {
-              yystack.yystateStack.yytops.yyundeleteLastStack ();
-              if (yystack.yystateStack.yytops.size() == 0)
-                yystack.yyFail (]b4_locations_if([&yylloc, ])[YY_("syntax 
error"));
-              YYCHK1 (yystack.yyresolveStack ());
-              YY_DEBUG_STREAM << "Returning to deterministic 
operation.\n";]b4_locations_if([[
-              yystack.yyerror_range[1].getState().yyloc = yylloc;]])[
-              yystack.yyreportSyntaxError ();
-              goto yyuser_error;
-            }
-
-          /* 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, yychar is set to 
]b4_symbol(empty, id)[
-             before the loop to make sure the user destructor for yylval isn't
-             called twice.  */
-          yysymbol_kind_t yytoken_to_shift = YYTRANSLATE (yychar);
-          yychar = ]b4_namespace_ref::b4_parser_class::token::b4_symbol(empty, 
id)[;
-          yyposn += 1;
-          for (state_set_index yys = create_state_set_index(0); yys.uget() < 
yystack.yystateStack.numTops(); ++yys)
-            {
-              const state_num yystate = yystack.topState(yys)->yylrState;
-              const short* yyconflicts;
-              const int yyaction = yygetLRActions (yystate, yytoken_to_shift,
-                              yyconflicts);
-              /* Note that yyconflicts were handled by yyprocessOneStack.  */
-              YY_DEBUG_STREAM << "On stack " << yys.get() << ", ";
-              YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, &yylloc);
-              yystack.yyglrShift (yys, yyaction, yyposn,
-                          yylval]b4_locations_if([, &yylloc])[);
-              YY_DEBUG_STREAM << "Stack " << yys.get() << " now in state #"
-                        << yystack.topState(yys)->yylrState << '\n';
-            }
-
-          if (yystack.yystateStack.yytops.size() == 1)
-            {
-              YYCHK1 (yystack.yyresolveStack ());
-              YY_DEBUG_STREAM  << "Returning to deterministic operation.\n";
-              yystack.yystateStack.yycompressStack ();
-              break;
-            }
-        }
-      continue;
-    yyuser_error:
-      yystack.yyrecoverSyntaxError (]b4_locations_if([&yylloc])[);
-      yyposn = yystack.firstTopState()->yyposn;
-    }
-
- yyacceptlab:
-  yyresult = 0;
-  goto yyreturn;
-
- yybuglab:
-  YYASSERT (false);
-  goto yyabortlab;
-
- yyabortlab:
-  yyresult = 1;
-  goto yyreturn;
-
- yyexhaustedlab:
-  yyparser.error (]b4_locations_if([yylloc, ])[YY_("memory exhausted"));
-  yyresult = 2;
-  goto yyreturn;
-
- yyreturn:
-  return yyresult;
-}
-
-
 /* DEBUGGING ONLY */
 #if ]b4_api_PREFIX[DEBUG
 static void
@@ -3045,23 +2862,6 @@ static void yypdumpstack (glr_stack* yystackp) {
 
 #endif
 
-#undef yylval
-#undef yychar
-#undef yynerrs]b4_locations_if([
-#undef yylloc])
-
-m4_if(b4_prefix, [yy], [],
-[[/* Substitute the variable and function names.  */
-#define yyparse ]b4_prefix[parse
-#define yylex   ]b4_prefix[lex
-#define yyerror ]b4_prefix[error
-#define yylval  ]b4_prefix[lval
-#define yychar  ]b4_prefix[char
-#define yydebug ]b4_prefix[debug
-#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
-#define yylloc  ]b4_prefix[lloc]])])[
-
-
 ]b4_namespace_open[
 ]dnl In this section, the parse params are the original parse_params.
 m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
@@ -3088,8 +2888,186 @@ m4_pushdef([b4_parse_param], 
m4_defn([b4_parse_param_orig]))dnl
   int
   ]b4_parser_class[::parse ()
   {
-    return ::yyparse (*this]b4_user_args[);
-  }
+    ]b4_parser_class[ &yyparser = *this;
+    int yyresult;
+    glr_stack yystack(YYINITDEPTH, *this]b4_user_args[);
+    glr_stack* const yystackp = &yystack;
+    size_t yyposn;
+
+    YY_DEBUG_STREAM << "Starting parse\n";
+
+    yychar = ]b4_namespace_ref::b4_parser_class::token::b4_symbol(empty, id)[;
+    yylval = yyval_default;]b4_locations_if([
+    yylloc = yyloc_default;])[
+]m4_ifdef([b4_initial_action], [
+b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
+    b4_user_initial_action
+b4_dollar_popdef])[]dnl
+[
+    switch (YYSETJMP (yystack.yyexception_buffer))
+      {
+      case 0: break;
+      case 1: goto yyabortlab;
+      case 2: goto yyexhaustedlab;
+      default: goto yybuglab;
+      }
+    yystack.yyglrShift (create_state_set_index(0), 0, 0, 
yylval]b4_locations_if([, &yylloc])[);
+    yyposn = 0;
+
+    while (true)
+      {
+        /* For efficiency, we have two loops, the first of which is
+           specialized to deterministic operation (single stack, no
+           potential ambiguity).  */
+        /* Standard mode */
+        while (true)
+          {
+            const state_num yystate = yystack.firstTopState()->yylrState;
+            YY_DEBUG_STREAM << "Entering state " << yystate << "\n";
+            if (yystate == YYFINAL)
+              goto yyacceptlab;
+            if (yyisDefaultedState (yystate))
+              {
+                const rule_num yyrule = yydefaultAction (yystate);
+                if (yyrule == 0)
+                  {]b4_locations_if([[
+                    yystack.yyerror_range[1].getState().yyloc = yylloc;]])[
+                    yystack.yyreportSyntaxError ();
+                    goto yyuser_error;
+                  }
+                YYCHK1 (yystack.yyglrReduce (create_state_set_index(0), 
yyrule, true));
+              }
+            else
+              {
+                const yysymbol_kind_t yytoken = ]b4_yygetToken_call[;
+                const short* yyconflicts;
+                const int yyaction = yygetLRActions (yystate, yytoken, 
yyconflicts);
+                if (*yyconflicts != 0)
+                  break;
+                if (yyisShiftAction (yyaction))
+                  {
+                    YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+                    yychar = token::]b4_symbol(empty, id)[;
+                    yyposn += 1;
+                    yystack.yyglrShift (create_state_set_index(0), yyaction, 
yyposn, yylval]b4_locations_if([, &yylloc])[);
+                    if (0 < yystack.yyerrState)
+                      yystack.yyerrState -= 1;
+                  }
+                else if (yyisErrorAction (yyaction))
+                  {]b4_locations_if([[
+                    yystack.yyerror_range[1].getState().yyloc = yylloc;]])[
+                    /* Don't issue an error message again for exceptions
+                       thrown from the scanner.  */
+                    if (yychar != token::]b4_symbol(error, id)[)
+                      yystack.yyreportSyntaxError ();
+                    goto yyuser_error;
+                  }
+                else
+                  YYCHK1 (yystack.yyglrReduce (create_state_set_index(0), 
-yyaction, true));
+              }
+          }
+
+        while (true)
+          {
+            for (state_set_index yys = create_state_set_index(0); yys.uget() < 
yystack.yystateStack.numTops(); ++yys)
+              yystackp->yystateStack.yytops.setLookaheadNeeds(yys, yychar != 
token::]b4_symbol(empty, id)[);
+
+            /* 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
+                  (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 prevent double destructor calls
+               on yylval in the event of memory exhaustion.  */
+
+            for (state_set_index yys = create_state_set_index(0); yys.uget() < 
yystack.yystateStack.numTops(); ++yys)
+              YYCHK1 (yystack.yyprocessOneStack (yys, 
yyposn]b4_locations_if([, &yylloc])[));
+            yystack.yystateStack.yytops.yyremoveDeletes ();
+            if (yystack.yystateStack.yytops.size() == 0)
+              {
+                yystack.yystateStack.yytops.yyundeleteLastStack ();
+                if (yystack.yystateStack.yytops.size() == 0)
+                  yystack.yyFail (]b4_locations_if([&yylloc, ])[YY_("syntax 
error"));
+                YYCHK1 (yystack.yyresolveStack ());
+                YY_DEBUG_STREAM << "Returning to deterministic 
operation.\n";]b4_locations_if([[
+                yystack.yyerror_range[1].getState().yyloc = yylloc;]])[
+                yystack.yyreportSyntaxError ();
+                goto yyuser_error;
+              }
+
+            /* 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, yychar is set to 
]b4_symbol(empty, id)[
+               before the loop to make sure the user destructor for yylval 
isn't
+               called twice.  */
+            yysymbol_kind_t yytoken_to_shift = YYTRANSLATE (yychar);
+            yychar = token::]b4_symbol(empty, id)[;
+            yyposn += 1;
+            for (state_set_index yys = create_state_set_index(0); yys.uget() < 
yystack.yystateStack.numTops(); ++yys)
+              {
+                const state_num yystate = yystack.topState(yys)->yylrState;
+                const short* yyconflicts;
+                const int yyaction = yygetLRActions (yystate, yytoken_to_shift,
+                                yyconflicts);
+                /* Note that yyconflicts were handled by yyprocessOneStack.  */
+                YY_DEBUG_STREAM << "On stack " << yys.get() << ", ";
+                YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, 
&yylloc);
+                yystack.yyglrShift (yys, yyaction, yyposn,
+                            yylval]b4_locations_if([, &yylloc])[);
+                YY_DEBUG_STREAM << "Stack " << yys.get() << " now in state #"
+                          << yystack.topState(yys)->yylrState << '\n';
+              }
+
+            if (yystack.yystateStack.yytops.size() == 1)
+              {
+                YYCHK1 (yystack.yyresolveStack ());
+                YY_DEBUG_STREAM  << "Returning to deterministic operation.\n";
+                yystack.yystateStack.yycompressStack ();
+                break;
+              }
+          }
+        continue;
+      yyuser_error:
+        yystack.yyrecoverSyntaxError (]b4_locations_if([&yylloc])[);
+        yyposn = yystack.firstTopState()->yyposn;
+      }
+
+  yyacceptlab:
+    yyresult = 0;
+    goto yyreturn;
+
+  yybuglab:
+    YYASSERT (false);
+    goto yyabortlab;
+
+  yyabortlab:
+    yyresult = 1;
+    goto yyreturn;
+
+  yyexhaustedlab:
+    error (]b4_locations_if([yylloc, ])[YY_("memory exhausted"));
+    yyresult = 2;
+    goto yyreturn;
+
+  yyreturn:
+    return yyresult;
+}
+
+#undef yylval
+#undef yychar
+#undef yynerrs]b4_locations_if([
+#undef yylloc])[
 
 ]b4_parse_error_bmatch([custom\|detailed],
 [[  const char *
-- 
2.29.2




reply via email to

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