bison-patches
[Top][All Lists]
Advanced

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

[PATCH 4/5] glr.c: add support for parse.error detailed


From: Akim Demaille
Subject: [PATCH 4/5] glr.c: add support for parse.error detailed
Date: Wed, 29 Jan 2020 19:49:16 +0100

* data/skeletons/glr.c (yystrlen, yysymbol_name): New.
Implement parse.error detailed.
* tests/calc.at: Check it.
---
 data/skeletons/glr.c | 103 ++++++++++++++++++++++++++++++-------------
 tests/calc.at        |   2 +
 2 files changed, 75 insertions(+), 30 deletions(-)

diff --git a/data/skeletons/glr.c b/data/skeletons/glr.c
index 697618a2..26ba01db 100644
--- a/data/skeletons/glr.c
+++ b/data/skeletons/glr.c
@@ -368,15 +368,6 @@ static const ]b4_int_type_for([b4_rline])[ yyrline[] =
 };
 #endif
 
-#if ]b4_error_verbose_if([[1]], [b4_api_PREFIX[DEBUG || ]b4_token_table_flag])[
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
-static const char *const yytname[] =
-{
-  ]b4_tname[
-};
-#endif
-
 #define YYPACT_NINF (]b4_pact_ninf[)
 #define YYTABLE_NINF (]b4_table_ninf[)
 
@@ -616,13 +607,47 @@ yyMemoryExhausted (yyGLRStack* yystackp)
   YYLONGJMP (yystackp->yyexception_buffer, 2);
 }
 
-#if ]b4_error_verbose_if([[1]], [b4_api_PREFIX[DEBUG]])[
-/** A printable representation of TOKEN.  */
-static inline const char*
-yysymbol_name (yySymbol yytoken)
+#if ]b4_error_verbose_if([[1]], [b4_api_PREFIX[DEBUG || ]b4_token_table_flag])[
+/* The user-facing name of the symbol whose (internal) number is
+   YYSYMBOL.  No bounds checking.  */
+static const char *yysymbol_name (yySymbol yysymbol) YY_ATTRIBUTE_UNUSED;
+
+]m4_bmatch(b4_percent_define_get([[parse.error]]),
+           [simple\|verbose],
+[[/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
 {
-  return yytoken == YYEMPTY ? "" : yytname[yytoken];
-}
+  ]b4_tname[
+};
+
+static const char *
+yysymbol_name (yySymbol yysymbol)
+{
+  return yytname[yysymbol];
+}]],
+[[/* The user-facing name of the symbol whose (internal) number is
+   YYSYMBOL.  No bounds checking.  */
+static const char *yysymbol_name (yySymbol yysymbol) YY_ATTRIBUTE_UNUSED;
+
+static const char *
+yysymbol_name (yySymbol yysymbol)
+{
+  static const char *const yy_sname[] =
+  {
+  ]b4_symbol_names[
+  };]m4_ifdef([b4_translatable], [[
+  /* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YYTNAME[SYMBOL-NUM] is
+     internationalizable.  */
+  static ]b4_int_type_for([b4_translate])[ yytranslatable[] =
+  {
+  ]b4_translatable[
+  };
+  return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
+          ? _(yy_sname[yysymbol])
+          : yy_sname[yysymbol]);]], [[
+  return yy_sname[yysymbol];]])[
+}]])[
 #endif
 
 #if ]b4_api_PREFIX[DEBUG
@@ -680,11 +705,19 @@ static void yypdumpstack (yyGLRStack* yystackp)
 
 #endif /* !]b4_api_PREFIX[DEBUG */
 
-]m4_case(b4_percent_define_get([parse.error]), [verbose],
-[[# ifndef yystpcpy
-#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-#   define yystpcpy stpcpy
-#  else
+]m4_case(b4_percent_define_get([[parse.error]]),
+         [simple],
+[[]],
+[[#ifndef yystrlen
+# define yystrlen(S) (YY_CAST (ptrdiff_t, strlen (S)))
+#endif
+
+]m4_bmatch(b4_percent_define_get([[parse.error]]),
+           [detailed\|verbose],
+[[#ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#  define yystpcpy stpcpy
+# else
 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
    YYDEST.  */
 static char *
@@ -698,10 +731,12 @@ yystpcpy (char *yydest, const char *yysrc)
 
   return yyd - 1;
 }
-#  endif
 # endif
+#endif]])[
 
-# ifndef yytnamerr
+]m4_case(b4_percent_define_get([[parse.error]]),
+         [verbose],
+[[#ifndef yytnamerr
 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
    quotes and backslashes, so that it's suitable for yyerror.  The
    heuristic is that double-quoting is unnecessary unless the string
@@ -748,10 +783,10 @@ yytnamerr (char *yyres, const char *yystr)
   if (yyres)
     return yystpcpy (yyres, yystr) - yyres;
   else
-    return YY_CAST (ptrdiff_t, strlen (yystr));
+    return yystrlen (yystr);
 }
-# endif
-]])[
+#endif
+]])])[
 
 /** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
  *  at YYVSP[YYLOW0].yystate.yypred.  Leaves YYVSP[YYLOW1].yystate.yypred
@@ -2151,9 +2186,11 @@ yyreportSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
   if (yystackp->yyerrState != 0)
     return;
 ]m4_case(b4_percent_define_get([parse.error]),
+         [custom],
+[[  if (yyreport_syntax_error (yystackp]b4_user_args[))
+    yyMemoryExhausted (yystackp);]],
          [simple],
 [[  yyerror (]b4_lyyerror_args[YY_("syntax error"));]],
-         [verbose],
 [[  {
   yybool yysize_overflow = yyfalse;
   char* yymsg = YY_NULLPTR;
@@ -2169,6 +2206,8 @@ yyreportSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
   /* Actual size of YYARG. */
   int yycount
     = yysyntax_error_arguments (yystackp, yyarg, YYERROR_VERBOSE_ARGS_MAXIMUM);
+  if (yycount == -2)
+    yyMemoryExhausted (yystackp);
 
   switch (yycount)
     {
@@ -2188,12 +2227,15 @@ yyreportSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
 
   /* Compute error message size.  Don't count the "%s"s, but reserve
      room for the terminator.  */
-  yysize = YY_CAST (ptrdiff_t, strlen (yyformat)) - 2 * yycount + 1;
+  yysize = yystrlen (yyformat) - 2 * yycount + 1;
   {
     int yyi;
     for (yyi = 0; yyi < yycount; ++yyi)
       {
-        ptrdiff_t yysz = yytnamerr (YY_NULLPTR, yysymbol_name (yyarg[yyi]));
+        ptrdiff_t yysz
+          = ]m4_case(b4_percent_define_get([[parse.error]]),
+                     [verbose], [[yytnamerr (YY_NULLPTR, 
yytname[yyarg[yyi]])]],
+                     [[yystrlen (yysymbol_name (yyarg[yyi]))]]);[
         if (YYSIZEMAX - yysize < yysz)
           yysize_overflow = yytrue;
         else
@@ -2211,8 +2253,9 @@ yyreportSyntaxError (yyGLRStack* 
yystackp]b4_user_formals[)
       while ((*yyp = *yyformat))
         {
           if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-            {
-              yyp += yytnamerr (yyp, yysymbol_name (yyarg[yyi++]));
+            {]m4_case(b4_percent_define_get([[parse.error]]), [verbose], [[
+              yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]);]], [[
+              yyp = yystpcpy (yyp, yysymbol_name (yyarg[yyi++]));]])[
               yyformat += 2;
             }
           else
diff --git a/tests/calc.at b/tests/calc.at
index 074bd90a..0de22373 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -878,6 +878,7 @@ AT_CHECK_CALC_GLR([%define api.pure %locations])
 AT_CHECK_CALC_GLR([%define parse.error verbose %locations])
 
 AT_CHECK_CALC_GLR([%define parse.error verbose %locations %defines 
%name-prefix "calc" %verbose %yacc])
+AT_CHECK_CALC_GLR([%define parse.error detailed %locations %defines 
%name-prefix "calc" %verbose %yacc])
 
 AT_CHECK_CALC_GLR([%debug])
 AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines 
%name-prefix "calc" %verbose %yacc])
@@ -989,6 +990,7 @@ AT_CHECK_CALC_LALR1_D([%define parse.error verbose %define 
api.prefix {calc} %ve
 AT_CHECK_CALC_LALR1_D([%debug])
 
 AT_CHECK_CALC_LALR1_D([%define parse.error verbose %debug %verbose])
+
 #AT_CHECK_CALC_LALR1_D([%define parse.error verbose %debug %define 
api.token.prefix {TOK_} %verbose])
 
 #AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %verbose 
%parse-param {semantic_value *result}{int *count}{int *nerrs}])
-- 
2.25.0




reply via email to

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