bison-patches
[Top][All Lists]
Advanced

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

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


From: Akim Demaille
Subject: [RFC PATCH 1/4] parse stats: new feature of yacc.c
Date: Sun, 7 Jul 2019 20:20:33 +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.).

See https://lists.gnu.org/archive/html/bison-patches/2019-07/msg00004.html.

We want to turn yydebug into a bit mask.  But that causes backward
compatibility and compatibility with Yacc issues: because it was
purely a Boolean value, yydebug = 2 would enable the (usual) traces
whereas today it would report only the stats.

It was decided to comply comply with POSIX Yacc's specification, but
to move the interface of Bison forward:

- with %yacc, nothing changes: if yydebug is assigned a nonnull
  value, the traditional traces are emitted.

  We define yydebug_trace to -1 (so that the former "if (yydebug)" is
  semantically equivalent to the new "if (yydebug & yydebug_trace)").

- without %yacc, yydebug is now a bit field: yydebug_trace (= 1)
  controls the traditional traces, yydebug_stats (= 2) controls the
  stats, and there is space for more in the future.

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   | 12 +++++++++-
 data/skeletons/yacc.c | 51 +++++++++++++++++++++++++++++++++----------
 2 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/data/skeletons/c.m4 b/data/skeletons/c.m4
index fcf58a84..2c9ee7c3 100644
--- a/data/skeletons/c.m4
+++ b/data/skeletons/c.m4
@@ -102,6 +102,7 @@ b4_percent_define_default([[api.value.union.name]],
                           [b4_api_PREFIX[][STYPE]])
 
 
+
 ## ------------------------ ##
 ## Pure/impure interfaces.  ##
 ## ------------------------ ##
@@ -138,7 +139,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 +790,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_yacc_if([[
+  ]b4_prefix[debug_trace = -1]], [[
+  ]b4_prefix[debug_trace = 1 << 0,
+  ]b4_prefix[debug_stats = 1 << 1,
+  ]b4_prefix[debug_all = -1]])[
+};
 extern int ]b4_prefix[debug;
 #endif][]dnl
 ])
diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c
index e9c31a84..0517fa67 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_yacc_if([], [[
+#if ]b4_api_PREFIX[DEBUG
+  typedef struct {
+    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_yacc_if([], [[
+#if ]b4_api_PREFIX[DEBUG
+  yy_stats.num_shifts += 1;
+#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_yacc_if([], [[
+#if ]b4_api_PREFIX[DEBUG
+  yy_stats.num_reductions += 1;
+#endif]])[]b4_lac_if([[
   {
     int yychar_backup = yychar;
     switch (yyn)
@@ -1938,7 +1958,14 @@ yyreturn:
     YYSTACK_FREE (yyss);
 #endif]b4_lac_if([[
   if (yyes != yyesa)
-    YYSTACK_FREE (yyes);]])b4_push_if([[
+    YYSTACK_FREE (yyes);]])[]b4_yacc_if([], [[
+#if ]b4_api_PREFIX[DEBUG
+  if (yydebug & yydebug_stats)
+    {
+      YYFPRINTF (stderr, "num_reductions: %d\n", yy_stats.num_reductions);
+      YYFPRINTF (stderr, "num_shifts: %d\n", 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]