bison-patches
[Top][All Lists]
Advanced

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

[PATCH 6/9] parser: keep string aliases as the user wrote it


From: Akim Demaille
Subject: [PATCH 6/9] parser: keep string aliases as the user wrote it
Date: Sat, 13 Jun 2020 17:23:14 +0200

Currently our scanner decodes all the escapes in the strings, and we
later reescape the strings when we emit them.

This is troublesome, as we do not respect the user input.  For
instance, when the user writes in UTF-8, we destroy her string when we
write it back.  And this shows everywhere: in the reports we show the
escaped string instead of the actual alias:

    0 $accept: . exp $end
    1 exp: . exp "\342\212\225" exp
    2    | . exp "+" exp
    3    | . exp "+" exp
    4    | . "number"
    5    | . "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"

    "number"                                                    shift, and go 
to state 1
    "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"  shift, and go 
to state 2

This commit preserves the user's exact spelling of the string aliases,
instead of interpreting the escapes and then reescaping.  The report
now shows:

    0 $accept: . exp $end
    1 exp: . exp "⊕" exp
    2    | . exp "+" exp
    3    | . exp "+" exp
    4    | . "number"
    5    | . "Ñùṃéℝô"

    "number"          shift, and go to state 1
    "Ñùṃéℝô"  shift, and go to state 2

Likewise, the XML (and therefore HTML) outputs are fixed.

* src/scan-gram.l (STRING, TSTRING): Do not interpret the escapes in
the resulting string.
* src/parse-gram.y (unquote, parser_init, parser_free, unquote_free)
(handle_defines, handle_language, obstack_for_unquote): New.
Use them to unquote where needed.
* tests/regression.at, tests/report.at: Update.
---
 src/main.c          |   8 +-
 src/muscle-tab.c    |   3 +-
 src/parse-gram.y    | 193 +++++++++++++++++++++++++++++++++++++-------
 src/reader.c        |   1 +
 src/scan-gram.l     |  42 +++++-----
 tests/regression.at |   4 +-
 tests/report.at     | 144 ++++++++++++++++-----------------
 7 files changed, 266 insertions(+), 129 deletions(-)

diff --git a/src/main.c b/src/main.c
index 5dd54d34..18b6cc19 100644
--- a/src/main.c
+++ b/src/main.c
@@ -45,6 +45,7 @@
 #include "muscle-tab.h"
 #include "nullable.h"
 #include "output.h"
+#include "parse-gram.h"
 #include "print-graph.h"
 #include "print-xml.h"
 #include "print.h"
@@ -223,9 +224,12 @@ main (int argc, char *argv[])
   counterexample_free ();
   output_file_names_free ();
 
-  /* The scanner memory cannot be released right after parsing, as it
-     contains things such as user actions, prologue, epilogue etc.  */
+  /* The scanner and parser memory cannot be released right after
+     parsing, as it contains things such as user actions, prologue,
+     epilogue etc.  */
   gram_scanner_free ();
+  parser_free ();
+
   muscle_free ();
   code_scanner_free ();
   skel_scanner_free ();
diff --git a/src/muscle-tab.c b/src/muscle-tab.c
index d6d56f32..096c93ca 100644
--- a/src/muscle-tab.c
+++ b/src/muscle-tab.c
@@ -141,8 +141,7 @@ muscle_free (void)
 }
 
 /* Look for the muscle named KEY.  Return NULL if does not exist.  */
-static
-muscle_entry *
+static muscle_entry *
 muscle_lookup (char const *key)
 {
   muscle_entry probe;
diff --git a/src/parse-gram.y b/src/parse-gram.y
index 980bc4f5..01b2f1bb 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -23,6 +23,14 @@
   #include "symtab.h"
 }
 
+%code provides
+{
+  /* Initialize unquote.  */
+  void parser_init (void);
+  /* Deallocate storage for unquote.  */
+  void parser_free (void);
+}
+
 %code top
 {
   /* On column 0 to please syntax-check.  */
@@ -73,17 +81,20 @@
   static char *strip_braces (char *code);
 
   /* Convert CODE by calling code_props_plain_init if PLAIN, otherwise
-     code_props_symbol_action_init.  Call
+     code_props_symbol_action_init.  Calls
      gram_scanner_last_string_free to release the latest string from
      the scanner (should be CODE). */
   static char const *translate_code (char *code, location loc, bool plain);
 
   /* Convert CODE by calling code_props_plain_init after having
      stripped the first and last characters (expected to be '{', and
-     '}').  Call gram_scanner_last_string_free to release the latest
+     '}').  Calls gram_scanner_last_string_free to release the latest
      string from the scanner (should be CODE). */
   static char const *translate_code_braceless (char *code, location loc);
 
+  /* Handle a %defines directive.  */
+  static void handle_defines (char const *value);
+
   /* Handle a %error-verbose directive.  */
   static void handle_error_verbose (location const *loc, char const 
*directive);
 
@@ -92,6 +103,9 @@
                                   location const *dir_loc,
                                   char const *directive, char const *value);
 
+  /* Handle a %language directive.  */
+  static void handle_language (location const *loc, char const *lang);
+
   /* Handle a %name-prefix directive.  */
   static void handle_name_prefix (location const *loc,
                                   char const *directive, char const *value);
@@ -117,6 +131,13 @@
   /* Add style to semantic values in traces.  */
   static void tron (FILE *yyo);
   static void troff (FILE *yyo);
+
+  /* Interpret a quoted string (such as `"Hello, \"World\"\n\""`).
+     Manages the memory of the result.  */
+  static char *unquote (const char *str);
+
+  /* Discard the latest unquoted string.  */
+  static void unquote_free (char *last_string);
 }
 
 %define api.header.include {"parse-gram.h"}
@@ -315,11 +336,7 @@ prologue_declaration:
                                     MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
     }
 | "%defines"                       { defines_flag = true; }
-| "%defines" STRING
-    {
-      defines_flag = true;
-      spec_header_file = xstrdup ($2);
-    }
+| "%defines" STRING                { handle_defines ($2); }
 | "%error-verbose"                 { handle_error_verbose (&@$, $1); }
 | "%expect" INT                    { expected_sr_conflicts = $2; }
 | "%expect-rr" INT                 { expected_rr_conflicts = $2; }
@@ -334,11 +351,11 @@ prologue_declaration:
       muscle_code_grow ("initial_action", translate_code ($2, @2, false), @2);
       code_scanner_last_string_free ();
     }
-| "%language" STRING            { language_argmatch ($2, grammar_prio, @1); }
+| "%language" STRING            { handle_language (&@1, $2); }
 | "%name-prefix" STRING         { handle_name_prefix (&@$, $1, $2); }
 | "%no-lines"                   { no_lines_flag = true; }
 | "%nondeterministic-parser"    { nondeterministic_parser = true; }
-| "%output" STRING              { spec_outfile = $2; }
+| "%output" STRING              { spec_outfile = unquote ($2); 
gram_scanner_last_string_free (); }
 | "%param" { current_param = $1; } params { current_param = param_none; }
 | "%pure-parser"                { handle_pure_parser (&@$, $1); }
 | "%require" STRING             { handle_require (&@2, $2); }
@@ -549,7 +566,7 @@ alias:
 | string_as_id   { $$ = $1; }
 | TSTRING
     {
-      $$ = symbol_get (quotearg_style (c_quoting_style, $1), @1);
+      $$ = symbol_get ($1, @1);
       symbol_class_set ($$, token_sym, @1, false);
       $$->translatable = true;
     }
@@ -729,8 +746,8 @@ variable:
 value:
   %empty  { $$.kind = muscle_keyword; $$.chars = ""; }
 | ID      { $$.kind = muscle_keyword; $$.chars = $1; }
-| STRING  { $$.kind = muscle_string;  $$.chars = $1; }
-| "{...}" { $$.kind = muscle_code;    $$.chars = strip_braces ($1); }
+| STRING  { $$.kind = muscle_string;  $$.chars = unquote ($1); 
gram_scanner_last_string_free ();}
+| "{...}" { $$.kind = muscle_code;    $$.chars = strip_braces ($1); 
gram_scanner_last_string_free (); }
 ;
 
 
@@ -777,11 +794,11 @@ symbol:
 | string_as_id
 ;
 
-/* A string used as an ID: quote it.  */
+/* A string used as an ID.  */
 string_as_id:
   STRING
     {
-      $$ = symbol_get (quotearg_style (c_quoting_style, $1), @1);
+      $$ = symbol_get ($1, @1);
       symbol_class_set ($$, token_sym, @1, false);
     }
 ;
@@ -925,6 +942,17 @@ add_param (param_type type, char *decl, location loc)
 }
 
 
+static void
+handle_defines (char const *value)
+{
+  defines_flag = true;
+  char *file = unquote (value);
+  spec_header_file = xstrdup (file);
+  gram_scanner_last_string_free ();
+  unquote_free (file);
+}
+
+
 static void
 handle_error_verbose (location const *loc, char const *directive)
 {
@@ -937,8 +965,9 @@ handle_error_verbose (location const *loc, char const 
*directive)
 static void
 handle_file_prefix (location const *loc,
                     location const *dir_loc,
-                    char const *directive, char const *value)
+                    char const *directive, char const *value_quoted)
 {
+  char *value = unquote (value_quoted);
   bison_directive (loc, directive);
   bool warned = false;
 
@@ -958,11 +987,18 @@ handle_file_prefix (location const *loc,
     deprecated_directive (dir_loc, directive, "%file-prefix");
 }
 
+static void
+handle_language (location const *loc, char const *lang)
+{
+  language_argmatch (unquote (lang), grammar_prio, *loc);
+}
+
 
 static void
 handle_name_prefix (location const *loc,
-                    char const *directive, char const *value)
+                    char const *directive, char const *value_quoted)
 {
+  char *value = unquote (value_quoted);
   bison_directive (loc, directive);
 
   char buf1[1024];
@@ -1034,34 +1070,39 @@ str_to_version (char const *version)
 
 
 static void
-handle_require (location const *loc, char const *version)
+handle_require (location const *loc, char const *version_quoted)
 {
+  char *version = unquote (version_quoted);
   required_version = str_to_version (version);
   if (required_version == -1)
     {
       complain (loc, complaint, _("invalid version requirement: %s"),
                 version);
       required_version = 0;
-      return;
     }
-
-  /* Pretend to be at least that version, to check features published
-     in that version while developping it.  */
-  const char* api_version = "3.6";
-  const char* package_version =
-    0 < strverscmp (api_version, PACKAGE_VERSION)
-    ? api_version : PACKAGE_VERSION;
-  if (0 < strverscmp (version, package_version))
+  else
     {
-      complain (loc, complaint, _("require bison %s, but have %s"),
-                version, package_version);
-      exit (EX_MISMATCH);
+      /* Pretend to be at least that version, to check features published
+         in that version while developping it.  */
+      const char* api_version = "3.6";
+      const char* package_version =
+        0 < strverscmp (api_version, PACKAGE_VERSION)
+        ? api_version : PACKAGE_VERSION;
+      if (0 < strverscmp (version, package_version))
+        {
+          complain (loc, complaint, _("require bison %s, but have %s"),
+                    version, package_version);
+          exit (EX_MISMATCH);
+        }
     }
+  unquote_free (version);
+  gram_scanner_last_string_free ();
 }
 
 static void
-handle_skeleton (location const *loc, char const *skel)
+handle_skeleton (location const *loc, char const *skel_quoted)
 {
+  char *skel = unquote (skel_quoted);
   char const *skeleton_user = skel;
   if (strchr (skeleton_user, '/'))
     {
@@ -1142,3 +1183,95 @@ static void troff (FILE *yyo)
 {
   end_use_class ("value", yyo);
 }
+
+
+/*----------.
+| Unquote.  |
+`----------*/
+
+struct obstack obstack_for_unquote;
+
+void
+parser_init (void)
+{
+  obstack_init (&obstack_for_unquote);
+}
+
+void
+parser_free (void)
+{
+  obstack_free (&obstack_for_unquote, 0);
+}
+
+static void
+unquote_free (char *last_string)
+{
+  obstack_free (&obstack_for_unquote, last_string);
+}
+
+static char *
+unquote (const char *cp)
+{
+#define GROW(Char)                              \
+  obstack_1grow (&obstack_for_unquote, Char);
+  for (++cp; *cp && *cp != '"'; ++cp)
+    switch (*cp)
+      {
+      case '"':
+        break;
+      case '\\':
+        ++cp;
+        switch (*cp)
+          {
+          case '0': case '1': case '2': case '3': case '4':
+          case '5': case '6': case '7': case '8': case '9':
+            {
+              int c = cp[0] - '0';
+              if (c_isdigit (cp[1]))
+                {
+                  ++cp;
+                  c = c * 8 + cp[0] - '0';
+                }
+              if (c_isdigit (cp[1]))
+                {
+                  ++cp;
+                  c = c * 8 + cp[0] - '0';
+                }
+              GROW (c);
+            }
+            break;
+
+          case 'a': GROW ('\a'); break;
+          case 'b': GROW ('\b'); break;
+          case 'f': GROW ('\f'); break;
+          case 'n': GROW ('\n'); break;
+          case 'r': GROW ('\r'); break;
+          case 't': GROW ('\t'); break;
+          case 'v': GROW ('\v'); break;
+
+          case 'x':
+            {
+              int c = 0;
+              while (c_isxdigit (cp[1]))
+                {
+                  ++cp;
+                  c = (c * 16 + (c_isdigit (cp[0]) ? cp[0] - '0'
+                                 : c_isupper (cp[0]) ? cp[0] - 'A'
+                                 : cp[0] - '0'));
+                }
+              GROW (c);
+              break;
+            }
+          }
+        break;
+
+      default:
+        GROW (*cp);
+        break;
+      }
+  assert (*cp == '"');
+  ++cp;
+  assert (*cp == '\0');
+#undef GROW
+  return obstack_finish0 (&obstack_for_unquote);
+}
diff --git a/src/reader.c b/src/reader.c
index 21ab0df3..6461c79f 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -710,6 +710,7 @@ reader (const char *gram)
   symbols_new ();
 
   gram_scanner_open (gram);
+  parser_init ();
   gram_parse ();
   gram_scanner_close ();
 
diff --git a/src/scan-gram.l b/src/scan-gram.l
index ad254694..f8d85f23 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -88,16 +88,15 @@ static boundary scanner_cursor;
   do {                                                          \
     verify (UCHAR_MAX < ULONG_MAX);                             \
     long c = Char;                                              \
-    if (0 < c && c <= UCHAR_MAX)                                \
-      STRING_1GROW (c);                                         \
+    bool valid = 0 < c && c <= UCHAR_MAX;                       \
+    if (!valid)                                                 \
+      complain (loc, complaint,                                 \
+                _("invalid number after \\-escape: %s"),        \
+                yytext + 1);                                    \
+    if (YY_START == SC_ESCAPED_CHARACTER)                       \
+      STRING_1GROW (valid ? c : '?');                           \
     else                                                        \
-      {                                                         \
-        complain (loc, complaint,                               \
-                  _("invalid number after \\-escape: %s"),      \
-                  yytext + 1);                                  \
-        /* Avoid additional errors about empty char literal. */ \
-        STRING_1GROW ('?');                                     \
-      }                                                         \
+      STRING_GROW ();                                           \
   } while (0)
 
 
@@ -337,8 +336,8 @@ eqopt    ({sp}=)?
   "'"         token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
 
   /* Strings. */
-  "\""        token_start = loc->start; BEGIN SC_ESCAPED_STRING;
-  "_(\""      token_start = loc->start; BEGIN SC_ESCAPED_TSTRING;
+  "\""        token_start = loc->start; STRING_1GROW ('"'); BEGIN 
SC_ESCAPED_STRING;
+  "_(\""      token_start = loc->start; STRING_1GROW ('"'); BEGIN 
SC_ESCAPED_TSTRING;
 
   /* Prologue. */
   "%{"        code_start = loc->start; BEGIN SC_PROLOGUE;
@@ -559,6 +558,7 @@ eqopt    ({sp}=)?
 <SC_ESCAPED_STRING>
 {
   "\"" {
+    STRING_1GROW ('"');
     STRING_FINISH ();
     BEGIN INITIAL;
     loc->start = token_start;
@@ -571,6 +571,7 @@ eqopt    ({sp}=)?
 <SC_ESCAPED_TSTRING>
 {
   "\")" {
+    STRING_1GROW ('"');
     STRING_FINISH ();
     BEGIN INITIAL;
     loc->start = token_start;
@@ -664,16 +665,16 @@ eqopt    ({sp}=)?
     STRING_GROW_ESCAPE (strtol (yytext + 2, NULL, 16));
   }
 
-  \\a   STRING_1GROW ('\a');
-  \\b   STRING_1GROW ('\b');
-  \\f   STRING_1GROW ('\f');
-  \\n   STRING_1GROW ('\n');
-  \\r   STRING_1GROW ('\r');
-  \\t   STRING_1GROW ('\t');
-  \\v   STRING_1GROW ('\v');
+  \\a   STRING_GROW_ESCAPE ('\a');
+  \\b   STRING_GROW_ESCAPE ('\b');
+  \\f   STRING_GROW_ESCAPE ('\f');
+  \\n   STRING_GROW_ESCAPE ('\n');
+  \\r   STRING_GROW_ESCAPE ('\r');
+  \\t   STRING_GROW_ESCAPE ('\t');
+  \\v   STRING_GROW_ESCAPE ('\v');
 
   /* \\[\"\'?\\] would be shorter, but it confuses xgettext.  */
-  \\("\""|"'"|"?"|"\\")  STRING_1GROW (yytext[1]);
+  \\("\""|"'"|"?"|"\\")  STRING_GROW_ESCAPE (yytext[1]);
 
   \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
     STRING_GROW_ESCAPE (convert_ucn_to_byte (yytext));
@@ -1024,7 +1025,7 @@ gram_scanner_open (const char *gram)
 
 
 void
-gram_scanner_close ()
+gram_scanner_close (void)
 {
   xfclose (gram_in);
   /* Reclaim Flex's buffers.  */
@@ -1032,7 +1033,6 @@ gram_scanner_close ()
 }
 
 
-
 void
 gram_scanner_free (void)
 {
diff --git a/tests/regression.at b/tests/regression.at
index 7c67d1aa..099b39a0 100644
--- a/tests/regression.at
+++ b/tests/regression.at
@@ -415,7 +415,7 @@ AT_BISON_CHECK([-fcaret -o input.c input.y], [[0]], [[]],
 input.y:25.8-14: note: previous declaration
    25 | %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
       |        ^~~~~~~
-input.y:26.16-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" 
used more than once as a literal string [-Wother]
+input.y:26.16-63: warning: symbol 
"\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!" used more than once as a 
literal string [-Wother]
    26 | %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
       |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ]])
@@ -427,7 +427,7 @@ AT_COMPILE([input])
 # symbol name reported by the parser is exactly the same as that reported by
 # Bison itself.
 AT_PARSER_CHECK([input], 1, [],
-[[syntax error, unexpected a, expecting 
]AT_ERROR_VERBOSE_IF([["\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!"]], [[∃¬∩∪∀]])[
+[[syntax error, unexpected a, expecting 
]AT_ERROR_VERBOSE_IF([["\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"]], 
[[∃¬∩∪∀]])[
 ]])
 
 AT_BISON_OPTION_POPDEFS
diff --git a/tests/report.at b/tests/report.at
index 9ba6f664..c83d1704 100644
--- a/tests/report.at
+++ b/tests/report.at
@@ -1184,11 +1184,11 @@ Grammar
 
     0 $accept: exp $end
 
-    1 exp: exp "\342\212\225" exp
+    1 exp: exp "⊕" exp
     2    | exp "+" exp
     3    | exp "+" exp
     4    | "number"
-    5    | "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"
+    5    | "Ñùṃéℝô"
 
 
 Terminals, with rules where they appear
@@ -1196,9 +1196,9 @@ Terminals, with rules where they appear
     $end (0) 0
     error (256)
     "+" (258) 2 3
-    "\342\212\225" (259) 1
+    "⊕" (259) 1
     "number" (260) 4
-    "\303\221\303\271\341\271\203\303\251\342\204\235\303\264" (261) 5
+    "Ñùṃéℝô" (261) 5
 
 
 Nonterminals, with rules where they appear
@@ -1213,14 +1213,14 @@ Nonterminals, with rules where they appear
 State 0
 
     0 $accept: . exp $end
-    1 exp: . exp "\342\212\225" exp
+    1 exp: . exp "⊕" exp
     2    | . exp "+" exp
     3    | . exp "+" exp
     4    | . "number"
-    5    | . "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"
+    5    | . "Ñùṃéℝô"
 
-    "number"                                                    shift, and go 
to state 1
-    "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"  shift, and go 
to state 2
+    "number"          shift, and go to state 1
+    "Ñùṃéℝô"  shift, and go to state 2
 
     exp  go to state 3
 
@@ -1234,7 +1234,7 @@ State 1
 
 State 2
 
-    5 exp: "\303\221\303\271\341\271\203\303\251\342\204\235\303\264" .
+    5 exp: "Ñùṃéℝô" .
 
     $default  reduce using rule 5 (exp)
 
@@ -1242,13 +1242,13 @@ State 2
 State 3
 
     0 $accept: exp . $end
-    1 exp: exp . "\342\212\225" exp
+    1 exp: exp . "⊕" exp
     2    | exp . "+" exp
     3    | exp . "+" exp
 
-    $end            shift, and go to state 4
-    "+"             shift, and go to state 5
-    "\342\212\225"  shift, and go to state 6
+    $end   shift, and go to state 4
+    "+"    shift, and go to state 5
+    "⊕"  shift, and go to state 6
 
 
 State 4
@@ -1260,69 +1260,69 @@ State 4
 
 State 5
 
-    1 exp: . exp "\342\212\225" exp
+    1 exp: . exp "⊕" exp
     2    | . exp "+" exp
     2    | exp "+" . exp
     3    | . exp "+" exp
     3    | exp "+" . exp
     4    | . "number"
-    5    | . "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"
+    5    | . "Ñùṃéℝô"
 
-    "number"                                                    shift, and go 
to state 1
-    "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"  shift, and go 
to state 2
+    "number"          shift, and go to state 1
+    "Ñùṃéℝô"  shift, and go to state 2
 
     exp  go to state 7
 
 
 State 6
 
-    1 exp: . exp "\342\212\225" exp
-    1    | exp "\342\212\225" . exp
+    1 exp: . exp "⊕" exp
+    1    | exp "⊕" . exp
     2    | . exp "+" exp
     3    | . exp "+" exp
     4    | . "number"
-    5    | . "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"
+    5    | . "Ñùṃéℝô"
 
-    "number"                                                    shift, and go 
to state 1
-    "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"  shift, and go 
to state 2
+    "number"          shift, and go to state 1
+    "Ñùṃéℝô"  shift, and go to state 2
 
     exp  go to state 8
 
 
 State 7
 
-    1 exp: exp . "\342\212\225" exp
+    1 exp: exp . "⊕" exp
     2    | exp . "+" exp
-    2    | exp "+" exp .  [$end, "+", "\342\212\225"]
+    2    | exp "+" exp .  [$end, "+", "⊕"]
     3    | exp . "+" exp
-    3    | exp "+" exp .  [$end, "+", "\342\212\225"]
+    3    | exp "+" exp .  [$end, "+", "⊕"]
 
-    "\342\212\225"  shift, and go to state 6
+    "⊕"  shift, and go to state 6
 
-    $end            reduce using rule 2 (exp)
-    $end            [reduce using rule 3 (exp)]
-    "+"             reduce using rule 2 (exp)
-    "+"             [reduce using rule 3 (exp)]
-    "\342\212\225"  [reduce using rule 2 (exp)]
-    "\342\212\225"  [reduce using rule 3 (exp)]
-    $default        reduce using rule 2 (exp)
+    $end      reduce using rule 2 (exp)
+    $end      [reduce using rule 3 (exp)]
+    "+"       reduce using rule 2 (exp)
+    "+"       [reduce using rule 3 (exp)]
+    "⊕"     [reduce using rule 2 (exp)]
+    "⊕"     [reduce using rule 3 (exp)]
+    $default  reduce using rule 2 (exp)
 
     Conflict between rule 2 and token "+" resolved as reduce (%left "+").
 
 
 State 8
 
-    1 exp: exp . "\342\212\225" exp
-    1    | exp "\342\212\225" exp .  [$end, "+", "\342\212\225"]
+    1 exp: exp . "⊕" exp
+    1    | exp "⊕" exp .  [$end, "+", "⊕"]
     2    | exp . "+" exp
     3    | exp . "+" exp
 
-    "+"             shift, and go to state 5
-    "\342\212\225"  shift, and go to state 6
+    "+"    shift, and go to state 5
+    "⊕"  shift, and go to state 6
 
-    "+"             [reduce using rule 1 (exp)]
-    "\342\212\225"  [reduce using rule 1 (exp)]
-    $default        reduce using rule 1 (exp)
+    "+"       [reduce using rule 1 (exp)]
+    "⊕"     [reduce using rule 1 (exp)]
+    $default  reduce using rule 1 (exp)
 ]])
 
 
@@ -1338,43 +1338,43 @@ digraph "input.y"
   node [fontname = courier, shape = box, colorscheme = paired6]
   edge [fontname = courier]
 
-  0 [label="State 0\n\l  0 $accept: . exp $end\l  1 exp: . exp 
\"\\342\\212\\225\" exp\l  2    | . exp \"+\" exp\l  3    | . exp \"+\" exp\l  
4    | . \"number\"\l  5    | . 
\"\\303\\221\\303\\271\\341\\271\\203\\303\\251\\342\\204\\235\\303\\264\"\l"]
+  0 [label="State 0\n\l  0 $accept: . exp $end\l  1 exp: . exp 
\"\342\212\225\" exp\l  2    | . exp \"+\" exp\l  3    | . exp \"+\" exp\l  4   
 | . \"number\"\l  5    | . 
\"\303\221\303\271\341\271\203\303\251\342\204\235\303\264\"\l"]
   0 -> 1 [style=solid label="\"number\""]
-  0 -> 2 [style=solid 
label="\"\\303\\221\\303\\271\\341\\271\\203\\303\\251\\342\\204\\235\\303\\264\""]
+  0 -> 2 [style=solid 
label="\"\303\221\303\271\341\271\203\303\251\342\204\235\303\264\""]
   0 -> 3 [style=dashed label="exp"]
   1 [label="State 1\n\l  4 exp: \"number\" .\l"]
   1 -> "1R4" [style=solid]
  "1R4" [label="R4", fillcolor=3, shape=diamond, style=filled]
-  2 [label="State 2\n\l  5 exp: 
\"\\303\\221\\303\\271\\341\\271\\203\\303\\251\\342\\204\\235\\303\\264\" .\l"]
+  2 [label="State 2\n\l  5 exp: 
\"\303\221\303\271\341\271\203\303\251\342\204\235\303\264\" .\l"]
   2 -> "2R5" [style=solid]
  "2R5" [label="R5", fillcolor=3, shape=diamond, style=filled]
-  3 [label="State 3\n\l  0 $accept: exp . $end\l  1 exp: exp . 
\"\\342\\212\\225\" exp\l  2    | exp . \"+\" exp\l  3    | exp . \"+\" exp\l"]
+  3 [label="State 3\n\l  0 $accept: exp . $end\l  1 exp: exp . 
\"\342\212\225\" exp\l  2    | exp . \"+\" exp\l  3    | exp . \"+\" exp\l"]
   3 -> 4 [style=solid label="$end"]
   3 -> 5 [style=solid label="\"+\""]
-  3 -> 6 [style=solid label="\"\\342\\212\\225\""]
+  3 -> 6 [style=solid label="\"\342\212\225\""]
   4 [label="State 4\n\l  0 $accept: exp $end .\l"]
   4 -> "4R0" [style=solid]
  "4R0" [label="Acc", fillcolor=1, shape=diamond, style=filled]
-  5 [label="State 5\n\l  1 exp: . exp \"\\342\\212\\225\" exp\l  2    | . exp 
\"+\" exp\l  2    | exp \"+\" . exp\l  3    | . exp \"+\" exp\l  3    | exp 
\"+\" . exp\l  4    | . \"number\"\l  5    | . 
\"\\303\\221\\303\\271\\341\\271\\203\\303\\251\\342\\204\\235\\303\\264\"\l"]
+  5 [label="State 5\n\l  1 exp: . exp \"\342\212\225\" exp\l  2    | . exp 
\"+\" exp\l  2    | exp \"+\" . exp\l  3    | . exp \"+\" exp\l  3    | exp 
\"+\" . exp\l  4    | . \"number\"\l  5    | . 
\"\303\221\303\271\341\271\203\303\251\342\204\235\303\264\"\l"]
   5 -> 1 [style=solid label="\"number\""]
-  5 -> 2 [style=solid 
label="\"\\303\\221\\303\\271\\341\\271\\203\\303\\251\\342\\204\\235\\303\\264\""]
+  5 -> 2 [style=solid 
label="\"\303\221\303\271\341\271\203\303\251\342\204\235\303\264\""]
   5 -> 7 [style=dashed label="exp"]
-  6 [label="State 6\n\l  1 exp: . exp \"\\342\\212\\225\" exp\l  1    | exp 
\"\\342\\212\\225\" . exp\l  2    | . exp \"+\" exp\l  3    | . exp \"+\" exp\l 
 4    | . \"number\"\l  5    | . 
\"\\303\\221\\303\\271\\341\\271\\203\\303\\251\\342\\204\\235\\303\\264\"\l"]
+  6 [label="State 6\n\l  1 exp: . exp \"\342\212\225\" exp\l  1    | exp 
\"\342\212\225\" . exp\l  2    | . exp \"+\" exp\l  3    | . exp \"+\" exp\l  4 
   | . \"number\"\l  5    | . 
\"\303\221\303\271\341\271\203\303\251\342\204\235\303\264\"\l"]
   6 -> 1 [style=solid label="\"number\""]
-  6 -> 2 [style=solid 
label="\"\\303\\221\\303\\271\\341\\271\\203\\303\\251\\342\\204\\235\\303\\264\""]
+  6 -> 2 [style=solid 
label="\"\303\221\303\271\341\271\203\303\251\342\204\235\303\264\""]
   6 -> 8 [style=dashed label="exp"]
-  7 [label="State 7\n\l  1 exp: exp . \"\\342\\212\\225\" exp\l  2    | exp . 
\"+\" exp\l  2    | exp \"+\" exp .  [$end, \"+\", \"\\342\\212\\225\"]\l  3    
| exp . \"+\" exp\l  3    | exp \"+\" exp .  [$end, \"+\", 
\"\\342\\212\\225\"]\l"]
-  7 -> 6 [style=solid label="\"\\342\\212\\225\""]
-  7 -> "7R2d" [label="[\"\\342\\212\\225\"]", style=solid]
+  7 [label="State 7\n\l  1 exp: exp . \"\342\212\225\" exp\l  2    | exp . 
\"+\" exp\l  2    | exp \"+\" exp .  [$end, \"+\", \"\342\212\225\"]\l  3    | 
exp . \"+\" exp\l  3    | exp \"+\" exp .  [$end, \"+\", \"\342\212\225\"]\l"]
+  7 -> 6 [style=solid label="\"\342\212\225\""]
+  7 -> "7R2d" [label="[\"\342\212\225\"]", style=solid]
  "7R2d" [label="R2", fillcolor=5, shape=diamond, style=filled]
   7 -> "7R2" [style=solid]
  "7R2" [label="R2", fillcolor=3, shape=diamond, style=filled]
-  7 -> "7R3d" [label="[$end, \"+\", \"\\342\\212\\225\"]", style=solid]
+  7 -> "7R3d" [label="[$end, \"+\", \"\342\212\225\"]", style=solid]
  "7R3d" [label="R3", fillcolor=5, shape=diamond, style=filled]
-  8 [label="State 8\n\l  1 exp: exp . \"\\342\\212\\225\" exp\l  1    | exp 
\"\\342\\212\\225\" exp .  [$end, \"+\", \"\\342\\212\\225\"]\l  2    | exp . 
\"+\" exp\l  3    | exp . \"+\" exp\l"]
+  8 [label="State 8\n\l  1 exp: exp . \"\342\212\225\" exp\l  1    | exp 
\"\342\212\225\" exp .  [$end, \"+\", \"\342\212\225\"]\l  2    | exp . \"+\" 
exp\l  3    | exp . \"+\" exp\l"]
   8 -> 5 [style=solid label="\"+\""]
-  8 -> 6 [style=solid label="\"\\342\\212\\225\""]
-  8 -> "8R1d" [label="[\"+\", \"\\342\\212\\225\"]", style=solid]
+  8 -> 6 [style=solid label="\"\342\212\225\""]
+  8 -> "8R1d" [label="[\"+\", \"\342\212\225\"]", style=solid]
  "8R1d" [label="R1", fillcolor=5, shape=diamond, style=filled]
   8 -> "8R1" [style=solid]
  "8R1" [label="R1", fillcolor=3, shape=diamond, style=filled]
@@ -1402,7 +1402,7 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
         <lhs>exp</lhs>
         <rhs>
           <symbol>exp</symbol>
-          <symbol>&quot;\342\212\225&quot;</symbol>
+          <symbol>&quot;⊕&quot;</symbol>
           <symbol>exp</symbol>
         </rhs>
       </rule>
@@ -1431,7 +1431,7 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
       <rule number="5" usefulness="useful">
         <lhs>exp</lhs>
         <rhs>
-          
<symbol>&quot;\303\221\303\271\341\271\203\303\251\342\204\235\303\264&quot;</symbol>
+          <symbol>&quot;Ñùṃéℝô&quot;</symbol>
         </rhs>
       </rule>
     </rules>
@@ -1439,9 +1439,9 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
       <terminal symbol-number="0" token-number="0" name="$end" 
usefulness="useful"/>
       <terminal symbol-number="1" token-number="256" name="error" 
usefulness="useful"/>
       <terminal symbol-number="3" token-number="258" name="&quot;+&quot;" 
usefulness="useful" prec="1" assoc="left"/>
-      <terminal symbol-number="4" token-number="259" 
name="&quot;\342\212\225&quot;" usefulness="useful"/>
+      <terminal symbol-number="4" token-number="259" name="&quot;⊕&quot;" 
usefulness="useful"/>
       <terminal symbol-number="5" token-number="260" name="&quot;number&quot;" 
usefulness="useful"/>
-      <terminal symbol-number="6" token-number="261" 
name="&quot;\303\221\303\271\341\271\203\303\251\342\204\235\303\264&quot;" 
usefulness="useful"/>
+      <terminal symbol-number="6" token-number="261" name="&quot;Ñùṃéℝô&quot;" 
usefulness="useful"/>
     </terminals>
     <nonterminals>
       <nonterminal symbol-number="7" name="$accept" usefulness="useful"/>
@@ -1463,7 +1463,7 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
       <actions>
         <transitions>
           <transition type="shift" symbol="&quot;number&quot;" state="1"/>
-          <transition type="shift" 
symbol="&quot;\303\221\303\271\341\271\203\303\251\342\204\235\303\264&quot;" 
state="2"/>
+          <transition type="shift" symbol="&quot;Ñùṃéℝô&quot;" state="2"/>
           <transition type="goto" symbol="exp" state="3"/>
         </transitions>
         <errors/>
@@ -1511,7 +1511,7 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
         <transitions>
           <transition type="shift" symbol="$end" state="4"/>
           <transition type="shift" symbol="&quot;+&quot;" state="5"/>
-          <transition type="shift" symbol="&quot;\342\212\225&quot;" 
state="6"/>
+          <transition type="shift" symbol="&quot;⊕&quot;" state="6"/>
         </transitions>
         <errors/>
         <reductions/>
@@ -1546,7 +1546,7 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
       <actions>
         <transitions>
           <transition type="shift" symbol="&quot;number&quot;" state="1"/>
-          <transition type="shift" 
symbol="&quot;\303\221\303\271\341\271\203\303\251\342\204\235\303\264&quot;" 
state="2"/>
+          <transition type="shift" symbol="&quot;Ñùṃéℝô&quot;" state="2"/>
           <transition type="goto" symbol="exp" state="7"/>
         </transitions>
         <errors/>
@@ -1567,7 +1567,7 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
       <actions>
         <transitions>
           <transition type="shift" symbol="&quot;number&quot;" state="1"/>
-          <transition type="shift" 
symbol="&quot;\303\221\303\271\341\271\203\303\251\342\204\235\303\264&quot;" 
state="2"/>
+          <transition type="shift" symbol="&quot;Ñùṃéℝô&quot;" state="2"/>
           <transition type="goto" symbol="exp" state="8"/>
         </transitions>
         <errors/>
@@ -1584,7 +1584,7 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
           <lookaheads>
             <symbol>$end</symbol>
             <symbol>&quot;+&quot;</symbol>
-            <symbol>&quot;\342\212\225&quot;</symbol>
+            <symbol>&quot;⊕&quot;</symbol>
           </lookaheads>
         </item>
         <item rule-number="3" point="1"/>
@@ -1592,13 +1592,13 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
           <lookaheads>
             <symbol>$end</symbol>
             <symbol>&quot;+&quot;</symbol>
-            <symbol>&quot;\342\212\225&quot;</symbol>
+            <symbol>&quot;⊕&quot;</symbol>
           </lookaheads>
         </item>
       </itemset>
       <actions>
         <transitions>
-          <transition type="shift" symbol="&quot;\342\212\225&quot;" 
state="6"/>
+          <transition type="shift" symbol="&quot;⊕&quot;" state="6"/>
         </transitions>
         <errors/>
         <reductions>
@@ -1606,8 +1606,8 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
           <reduction symbol="$end" rule="3" enabled="false"/>
           <reduction symbol="&quot;+&quot;" rule="2" enabled="true"/>
           <reduction symbol="&quot;+&quot;" rule="3" enabled="false"/>
-          <reduction symbol="&quot;\342\212\225&quot;" rule="2" 
enabled="false"/>
-          <reduction symbol="&quot;\342\212\225&quot;" rule="3" 
enabled="false"/>
+          <reduction symbol="&quot;⊕&quot;" rule="2" enabled="false"/>
+          <reduction symbol="&quot;⊕&quot;" rule="3" enabled="false"/>
           <reduction symbol="$default" rule="2" enabled="true"/>
         </reductions>
       </actions>
@@ -1623,7 +1623,7 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
           <lookaheads>
             <symbol>$end</symbol>
             <symbol>&quot;+&quot;</symbol>
-            <symbol>&quot;\342\212\225&quot;</symbol>
+            <symbol>&quot;⊕&quot;</symbol>
           </lookaheads>
         </item>
         <item rule-number="2" point="1"/>
@@ -1632,12 +1632,12 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
       <actions>
         <transitions>
           <transition type="shift" symbol="&quot;+&quot;" state="5"/>
-          <transition type="shift" symbol="&quot;\342\212\225&quot;" 
state="6"/>
+          <transition type="shift" symbol="&quot;⊕&quot;" state="6"/>
         </transitions>
         <errors/>
         <reductions>
           <reduction symbol="&quot;+&quot;" rule="1" enabled="false"/>
-          <reduction symbol="&quot;\342\212\225&quot;" rule="1" 
enabled="false"/>
+          <reduction symbol="&quot;⊕&quot;" rule="1" enabled="false"/>
           <reduction symbol="$default" rule="1" enabled="true"/>
         </reductions>
       </actions>
-- 
2.27.0




reply via email to

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