[PATCH for Dlang support] d: make enum SymbolKind idiomatic D

Adela Vais <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
The enum is now wrapped in a structure that contains its string representation.

* data/skeletons/d.m4, data/skeletons/lalr1.d: here.
---
 data/skeletons/d.m4    | 67 ++++++++++++++++++++++++++++++++++++++++--
 data/skeletons/lalr1.d | 56 ++++-------------------------------
 2 files changed, 70 insertions(+), 53 deletions(-)

diff --git a/data/skeletons/d.m4 b/data/skeletons/d.m4
index edb0c49e..2e086ab0 100644
--- a/data/skeletons/d.m4
+++ b/data/skeletons/d.m4
@@ -204,11 +204,74 @@ m4_define([b4_symbol_enum],
 # to use a signed type, which matters for yytoken.
 m4_define([b4_declare_symbol_enum],
 [[  /* Symbol kinds.  */
-  public enum SymbolKind
+  struct SymbolKind
   {
+    enum
+    {
     ]b4_symbol(-2, kind_base)[ = -2,  /* No symbol.  */
 ]b4_symbol_foreach([b4_symbol_enum])dnl
-[  };
+[    }
+
+    private int yycode_;
+    alias yycode_ this;
+
+    this(int code)
+    {
+      yycode_ = code;
+    }
+
+    /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+       First, the terminals, then, starting at \a YYNTOKENS_, nonterminals.  */
+    static immutable string[] yytname_ = @{
+  ]b4_tname[
+    @};
+
+    /* Return 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 contains an
+     apostrophe, a comma, or backslash (other than backslash-backslash).
+     YYSTR is taken from yytname.  */
+    final void toString(W)(W sink) const
+    if (isOutputRange!(W, char))
+    {
+      string yystr = yytname_[yycode_];
+
+      if (yystr[0] == '"')
+        {
+          string yyr;
+        strip_quotes:
+          for (int i = 1; i < yystr.length; i++)
+            switch (yystr[i])
+              {
+              case '\'':
+              case ',':
+                break strip_quotes;
+
+              case '\\':
+                if (yystr[++i] != '\\')
+                  break strip_quotes;
+                goto default;
+              default:
+                yyr ~= yystr[i];
+                break;
+
+              case '"':
+                put(sink, yyr);
+                return;
+              }
+        }
+      else if (yystr == "$end")
+      {
+        put(sink, "end of input");
+        return;
+      }
+
+      put(sink, yystr);
+    }
+  }
+  ]])])
+    [
+  }
 ]])])
 
 
diff --git a/data/skeletons/lalr1.d b/data/skeletons/lalr1.d
index 761125cb..b452c4e0 100644
--- a/data/skeletons/lalr1.d
+++ b/data/skeletons/lalr1.d
@@ -361,41 +361,6 @@ b4_user_union_members
     return YYNEWSTATE;
   }
 
-  /* Return 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 contains an
-     apostrophe, a comma, or backslash (other than backslash-backslash).
-     YYSTR is taken from yytname.  */
-  private final string yytnamerr_ (string yystr)
-  {
-    if (yystr[0] == '"')
-      {
-        string yyr;
-      strip_quotes:
-        for (int i = 1; i < yystr.length; i++)
-          switch (yystr[i])
-            {
-            case '\'':
-            case ',':
-              break strip_quotes;
-
-            case '\\':
-              if (yystr[++i] != '\\')
-                break strip_quotes;
-              goto default;
-            default:
-              yyr ~= yystr[i];
-              break;
-
-            case '"':
-              return yyr;
-            }
-      }
-    else if (yystr == "$end")
-      return "end of input";
-
-    return yystr;
-  }
 ]b4_parse_trace_if([[
   /*--------------------------------.
   | Print this symbol on YYOUTPUT.  |
@@ -732,7 +697,7 @@ m4_popdef([b4_at_dollar])])dnl
       // FIXME: This method of building the message is not compatible
       // with internationalization.
       string res = "syntax error, unexpected ";
-      res ~= yytnamerr_ (yytname_[tok]);
+      res ~= format!"%s"(tok);
       int yyn = yypact_[yystate];
       if (!yy_pact_value_is_default_ (yyn))
       {
@@ -757,7 +722,7 @@ m4_popdef([b4_at_dollar])])dnl
                    && !yy_table_value_is_error_ (yytable_[x + yyn]))
                {
                   res ~= count++ == 0 ? ", expecting " : " or ";
-                  res ~= yytnamerr_ (yytname_[x]);
+                  res ~= format!"%s"(SymbolKind(x));
                }
           }
       }
@@ -795,13 +760,6 @@ m4_popdef([b4_at_dollar])])dnl
 
   ]b4_parser_tables_define[
 
-  /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-     First, the terminals, then, starting at \a yyntokens_, nonterminals.  */
-  private static immutable string[] yytname_ =
-  @{
-  ]b4_tname[
-  @};
-
 ]b4_parse_trace_if([[
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
   private static immutable ]b4_int_type_for([b4_rline])[[] yyrline_ =
@@ -831,11 +789,10 @@ m4_popdef([b4_at_dollar])])dnl
   }
 ]])[
 
-  private static SymbolKind yytranslate_ (int t)
+  private static auto yytranslate_ (int t)
   {
 ]b4_api_token_raw_if(
-[[    import std.conv : to;
-    return to!SymbolKind (t);]],
+[[    return SymbolKind(t);]],
 [[    /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
     immutable ]b4_int_type_for([b4_translate])[[] translate_table =
     @{
@@ -848,10 +805,7 @@ m4_popdef([b4_at_dollar])])dnl
     if (t <= 0)
       return ]b4_symbol(0, kind)[;
     else if (t <= code_max)
-      {
-        import std.conv : to;
-        return to!SymbolKind (translate_table[t]);
-      }
+      return SymbolKind(translate_table[t]);
     else
       return ]b4_symbol(2, kind)[;]])[
   }
-- 
2.17.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.