bison-patches
[Top][All Lists]
Advanced

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

[PATCH 1/4] parse.stats: new feature of yacc.c


From: Akim Demaille
Subject: [PATCH 1/4] parse.stats: new feature of yacc.c
Date: Wed, 3 Jul 2019 07:25:35 +0200

Let's provide a means to get a summary of a parsing: number of shifts
and reductions (more things could come, such number of errors, etc.).

Backward compatibility and compatibility with Yacc is a problem: we
want to turn yydebug to use bit masks when parse.stats is specified,
but to remain a plain "Boolean" variable otherwise.  So we define
yydebug_trace to be -1 by default (so that the former "if (yydebug)" is
semantically equivalent to the new "if (yydebug & yydebug_trace)").

Another problem is the collision of symbols: bind these new
identifiers (yydebug_trace, yydebug_init, yydebug_type, etc.) to
%prefix.

* data/skeletons/c.m4 (b4_parse_stats_if): New.
(b4_declare_yydebug): Define yydebug_type.
* data/skeletons/yacc.c: Rename their prefix if needed.
Use `yydebug & yydebug_trace` instead of `yydebug` to
enable traces.
(yy_stats_t): New, when parse.stats is defined.
Use it when `yydebug & 2`.
---
 data/skeletons/c.m4   | 17 ++++++++++++++-
 data/skeletons/yacc.c | 50 ++++++++++++++++++++++++++++++++-----------
 2 files changed, 54 insertions(+), 13 deletions(-)

diff --git a/data/skeletons/c.m4 b/data/skeletons/c.m4
index fcf58a84..83281728 100644
--- a/data/skeletons/c.m4
+++ b/data/skeletons/c.m4
@@ -102,6 +102,12 @@ b4_percent_define_default([[api.value.union.name]],
                           [b4_api_PREFIX[][STYPE]])
 
 
+# b4_parse_stats_if(IF-TRUE, IF-FALSE)
+# ------------------------------------
+b4_percent_define_if_define([parse.stats])
+
+
+
 ## ------------------------ ##
 ## Pure/impure interfaces.  ##
 ## ------------------------ ##
@@ -138,7 +144,7 @@ b4_parse_param)
 
 
 # b4_parse_param_for(DECL, FORMAL, BODY)
-# ---------------------------------------
+# --------------------------------------
 # Iterate over the user parameters, binding the declaration to DECL,
 # the formal name to FORMAL, and evaluating the BODY.
 m4_define([b4_parse_param_for],
@@ -789,6 +795,15 @@ m4_define([b4_YYDEBUG_define],
 m4_define([b4_declare_yydebug],
 [b4_YYDEBUG_define[
 #if ]b4_api_PREFIX[DEBUG
+/* Values of ]b4_prefix[debug.  */
+enum ]b4_prefix[debug_type
+{
+  ]b4_prefix[debug_none = 0,]b4_parse_stats_if([[
+  ]b4_prefix[debug_trace = 1 << 0,
+  ]b4_prefix[debug_stats = 1 << 1,
+  ]b4_prefix[debug_all = -1]], [[
+  ]b4_prefix[debug_trace = -1]])[
+};
 extern int ]b4_prefix[debug;
 #endif][]dnl
 ])
diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c
index e9c31a84..fe22b0d8 100644
--- a/data/skeletons/yacc.c
+++ b/data/skeletons/yacc.c
@@ -356,8 +356,13 @@ m4_if(b4_api_prefix, [yy], [],
 #define yylex           ]b4_prefix[lex
 #define yyerror         ]b4_prefix[error
 #define yydebug         ]b4_prefix[debug
-#define yynerrs         ]b4_prefix[nerrs
-]]b4_pure_if([], [[
+#define yydebug_init    ]b4_prefix[debug_init
+#define yydebug_none    ]b4_prefix[debug_none
+#define yydebug_trace   ]b4_prefix[debug_trace
+#define yydebug_stats   ]b4_prefix[debug_stats
+#define yydebug_all     ]b4_prefix[debug_all
+#define yydebug_type    ]b4_prefix[debug_type
+#define yynerrs         ]b4_prefix[nerrs]]b4_pure_if([], [[
 #define yylval          ]b4_prefix[lval
 #define yychar          ]b4_prefix[char]b4_locations_if([[
 #define yylloc          ]b4_prefix[lloc]])]))[
@@ -697,7 +702,7 @@ static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
 
 # define YYDPRINTF(Args)                        \
 do {                                            \
-  if (yydebug)                                  \
+  if (yydebug & yydebug_trace)                  \
     YYFPRINTF Args;                             \
 } while (0)
 
@@ -705,7 +710,7 @@ do {                                            \
 
 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
 do {                                                                      \
-  if (yydebug)                                                            \
+  if (yydebug & yydebug_trace)                                            \
     {                                                                     \
       YYFPRINTF (stderr, "%s ", Title);                                   \
       yy_symbol_print (stderr,                                            \
@@ -736,7 +741,7 @@ do {                                                        
              \
 
 # define YY_STACK_PRINT(Bottom, Top)                            \
 do {                                                            \
-  if (yydebug)                                                  \
+  if (yydebug & yydebug_trace)                                  \
     yy_stack_print ((Bottom), (Top));                           \
 } while (0)
 
@@ -772,7 +777,7 @@ do {                                                        
    \
 
 # define YY_REDUCE_PRINT(Rule)          \
 do {                                    \
-  if (yydebug)                          \
+  if (yydebug & yydebug_trace)          \
     yy_reduce_print (yyssp, yyvsp, ]b4_locations_if([yylsp, 
])[Rule]b4_user_args[); \
 } while (0)
 
@@ -926,7 +931,7 @@ do {                                                        
     \
 do {                                                                     \
   if (yy_lac_established)                                                \
     {                                                                    \
-      if (yydebug)                                                       \
+      if (yydebug & yydebug_trace)                                       \
         YYFPRINTF (stderr, "LAC: initial context discarded due to "      \
                    Event "\n");                                          \
       yy_lac_established = 0;                                            \
@@ -1231,7 +1236,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
               }
         }]b4_lac_if([[
 # if ]b4_api_PREFIX[DEBUG
-      else if (yydebug)
+      else if (yydebug & yydebug_trace)
         YYFPRINTF (stderr, "No expected tokens.\n");
 # endif]])[
     }
@@ -1436,7 +1441,16 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
   char *yymsg = yymsgbuf;
   YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
 #endif
-
+]b4_parse_stats_if([[
+#if ]b4_api_PREFIX[DEBUG
+  typedef struct yy_stats_t {
+    int num_reductions;
+    int num_shifts;
+  } yy_stats_t;
+  static yy_stats_t yy_stats_init;
+  yy_stats_t yy_stats = yy_stats_init;
+#endif
+]])[
 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp 
-= (N)])[)
 
   /* The number of symbols on the RHS of the reduced rule.
@@ -1641,7 +1655,10 @@ yyread_pushed_token:]])[
     yyerrstatus--;
 
   /* Shift the lookahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);]b4_parse_stats_if([[
+#if ]b4_api_PREFIX[DEBUG
+  ++yy_stats.num_shifts;
+#endif]])[
 
   /* Discard the shifted token.  */
   yychar = YYEMPTY;]b4_lac_if([[
@@ -1686,7 +1703,10 @@ yyreduce:
 [[  /* Default location. */
   YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
   yyerror_range[1] = yyloc;]])[
-  YY_REDUCE_PRINT (yyn);]b4_lac_if([[
+  YY_REDUCE_PRINT (yyn);]b4_parse_stats_if([[
+#if ]b4_api_PREFIX[DEBUG
+  ++yy_stats.num_reductions;
+#endif]])[]b4_lac_if([[
   {
     int yychar_backup = yychar;
     switch (yyn)
@@ -1938,7 +1958,13 @@ yyreturn:
     YYSTACK_FREE (yyss);
 #endif]b4_lac_if([[
   if (yyes != yyesa)
-    YYSTACK_FREE (yyes);]])b4_push_if([[
+    YYSTACK_FREE (yyes);]])[]b4_parse_stats_if([[
+#if ]b4_api_PREFIX[DEBUG
+  if (yydebug & yydebug_stats)
+    YYFPRINTF (stderr,
+               "num_reductions: %d\nnum_shifts: %d\n",
+               yy_stats.num_reductions, yy_stats.num_shifts);
+#endif]])[]b4_push_if([[
   yyps->yynew = 1;
 
 
-- 
2.22.0




reply via email to

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