X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/3f21a394f481c829831592adcf3ea040f87805ee..aa94def12d5256d2bd3d5ed49d905f00372a0111:/src/parse-gram.y diff --git a/src/parse-gram.y b/src/parse-gram.y index 8b57ce80..1ec4b4dc 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -23,9 +23,14 @@ #include "symtab.h" } +%code top +{ + /* On column 0 to please syntax-check. */ +#include +} + %code { - #include #include "system.h" #include "c-ctype.h" @@ -60,6 +65,22 @@ #define YY_LOCATION_PRINT(File, Loc) \ location_print (Loc, File) + /* Strip initial '{' and final '}' (must be first and last characters). + Return the result. */ + static char *strip_braces (char *code); + + /* Convert CODE by calling code_props_plain_init if PLAIN, otherwise + code_props_symbol_action_init. Call + 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 + string from the scanner (should be CODE). */ + static char const *translate_code_braceless (char *code, location loc); + static void version_check (location const *loc, char const *version); static void gram_error (location const *, char const *); @@ -162,19 +183,10 @@ %type CHAR %printer { fputs (char_name ($$), yyo); } CHAR -/* braceless is not to be used for rule or symbol actions, as it - calls code_props_plain_init. */ -%union -{ - char *code; - char const *chars; -}; -%type STRING "%{...%}" EPILOGUE braceless -%type "{...}" "%?{...}" -%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); } - STRING -%printer { fprintf (yyo, "{\n%s\n}", $$); } - braceless "{...}" "%{...%}" EPILOGUE +%union {char *code;}; +%type "{...}" "%?{...}" "%{...%}" EPILOGUE STRING +%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); } STRING +%printer { fprintf (yyo, "{\n%s\n}", $$); } %union {uniqstr uniqstr;} %type BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable @@ -266,12 +278,8 @@ prologue_declaration: grammar_declaration | "%{...%}" { - code_props plain_code; - code_props_plain_init (&plain_code, $1, @1); - code_props_translate_code (&plain_code); - gram_scanner_last_string_free (); muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue", - plain_code.code, @1); + translate_code ($1, @1, true), @1); code_scanner_last_string_free (); } | "%" @@ -305,11 +313,7 @@ prologue_declaration: } | "%initial-action" "{...}" { - code_props action; - code_props_symbol_action_init (&action, $2, @2); - code_props_translate_code (&action); - gram_scanner_last_string_free (); - muscle_code_grow ("initial_action", action.code, @2); + muscle_code_grow ("initial_action", translate_code ($2, @2, false), @2); code_scanner_last_string_free (); } | "%language" STRING { language_argmatch ($2, grammar_prio, @1); } @@ -386,16 +390,17 @@ grammar_declaration: { default_prec = false; } -| "%code" braceless +| "%code" "{...}" { /* Do not invoke muscle_percent_code_grow here since it invokes muscle_user_name_list_grow. */ - muscle_code_grow ("percent_code()", $2, @2); + muscle_code_grow ("percent_code()", + translate_code_braceless ($2, @2), @2); code_scanner_last_string_free (); } -| "%code" ID braceless +| "%code" ID "{...}" { - muscle_percent_code_grow ($2, @2, $3, @3); + muscle_percent_code_grow ($2, @2, translate_code_braceless ($3, @3), @3); code_scanner_last_string_free (); } ; @@ -420,10 +425,10 @@ union_name: ; grammar_declaration: - "%union" union_name braceless + "%union" union_name "{...}" { union_seen = true; - muscle_code_grow ("union_members", $3, @3); + muscle_code_grow ("union_members", translate_code_braceless ($3, @3), @3); code_scanner_last_string_free (); } ; @@ -622,7 +627,7 @@ rhs: named_ref.opt: %empty { $$ = 0; } -| BRACKETED_ID { $$ = named_ref_new($1, @1); } +| BRACKETED_ID { $$ = named_ref_new ($1, @1); } ; /*---------------------. @@ -658,27 +663,10 @@ variable: } ; value: - %empty { $$.kind = muscle_keyword; $$.chars = ""; } -| ID { $$.kind = muscle_keyword; $$.chars = $1; } -| STRING { $$.kind = muscle_string; $$.chars = $1; } -| braceless { $$.kind = muscle_code; $$.chars = $1; } -; - - -/*------------. -| braceless. | -`------------*/ - -braceless: - "{...}" - { - code_props plain_code; - $1[strlen ($1) - 1] = '\0'; - code_props_plain_init (&plain_code, $1+1, @1); - code_props_translate_code (&plain_code); - gram_scanner_last_string_free (); - $$ = plain_code.code; - } + %empty { $$.kind = muscle_keyword; $$.chars = ""; } +| ID { $$.kind = muscle_keyword; $$.chars = $1; } +| STRING { $$.kind = muscle_string; $$.chars = $1; } +| "{...}" { $$.kind = muscle_code; $$.chars = strip_braces ($1); } ; @@ -723,11 +711,7 @@ epilogue.opt: %empty | "%%" EPILOGUE { - code_props plain_code; - code_props_plain_init (&plain_code, $2, @2); - code_props_translate_code (&plain_code); - gram_scanner_last_string_free (); - muscle_code_grow ("epilogue", plain_code.code, @2); + muscle_code_grow ("epilogue", translate_code ($2, @2, true), @2); code_scanner_last_string_free (); } ; @@ -763,6 +747,33 @@ lloc_default (YYLTYPE const *rhs, int n) return loc; } +static +char *strip_braces (char *code) +{ + code[strlen (code) - 1] = 0; + return code + 1; +} + +static +char const * +translate_code (char *code, location loc, bool plain) +{ + code_props plain_code; + if (plain) + code_props_plain_init (&plain_code, code, loc); + else + code_props_symbol_action_init (&plain_code, code, loc); + code_props_translate_code (&plain_code); + gram_scanner_last_string_free (); + return plain_code.code; +} + +static +char const * +translate_code_braceless (char *code, location loc) +{ + return translate_code (strip_braces (code), loc, true); +} static void add_param (param_type type, char *decl, location loc)