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}=)? { "\"" { + STRING_1GROW ('"'); STRING_FINISH (); BEGIN INITIAL; loc->start = token_start; @@ -571,6 +571,7 @@ eqopt ({sp}=)? { "\")" { + 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=" exp exp - "\342\212\225" + "⊕" exp @@ -1431,7 +1431,7 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" exp - "\303\221\303\271\341\271\203\303\251\342\204\235\303\264" + "Ñùṃéℝô" @@ -1439,9 +1439,9 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" - + - + @@ -1463,7 +1463,7 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" - + @@ -1511,7 +1511,7 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" - + @@ -1546,7 +1546,7 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" - + @@ -1567,7 +1567,7 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" - + @@ -1584,7 +1584,7 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" $end "+" - "\342\212\225" + "⊕" @@ -1592,13 +1592,13 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" $end "+" - "\342\212\225" + "⊕" - + @@ -1606,8 +1606,8 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" - - + + @@ -1623,7 +1623,7 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" $end "+" - "\342\212\225" + "⊕" @@ -1632,12 +1632,12 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version=" - + - +