From: Akim Demaille Date: Sat, 15 Dec 2001 14:14:30 +0000 (+0000) Subject: Attach actions to rules, instead of pre-outputting them to X-Git-Tag: before-m4-back-end~135 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/3f96f4dc41e366349d61f8918d8d6e9406da933d?ds=sidebyside;hp=51576fb3c661cec97bb58e503351e7ad75053f6d Attach actions to rules, instead of pre-outputting them to actions_obstack. * src/gram.h (rule_t): action and action_line are new members. * src/reader.c (symbol_list): Likewise. (copy_action): Save the actions within the rule. (packgram): Save them in rule_table. * src/output.c (actions_output): New. (output_parser): Use it on `%%actions'. (output_rule_data): Don't free rule_table. (output): Do it. (prepare): Don't save the `action' muscle. * src/bison.simple: s/%%action/%%actions/. --- diff --git a/ChangeLog b/ChangeLog index d1f758fb..b256520e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2001-12-15 Akim Demaille + + Attach actions to rules, instead of pre-outputting them to + actions_obstack. + + * src/gram.h (rule_t): action and action_line are new members. + * src/reader.c (symbol_list): Likewise. + (copy_action): Save the actions within the rule. + (packgram): Save them in rule_table. + * src/output.c (actions_output): New. + (output_parser): Use it on `%%actions'. + (output_rule_data): Don't free rule_table. + (output): Do it. + (prepare): Don't save the `action' muscle. + * src/bison.simple: s/%%action/%%actions/. + 2001-12-15 Akim Demaille * src/reader.c (copy_action): When --yacc, don't append a `;' diff --git a/src/bison.simple b/src/bison.simple index c7b56562..3ca6833e 100644 --- a/src/bison.simple +++ b/src/bison.simple @@ -891,7 +891,7 @@ yyreduce: #endif switch (yyn) { - %%action +%%actions } #line %%line "%%skeleton" diff --git a/src/gram.h b/src/gram.h index e26582fe..fc860386 100644 --- a/src/gram.h +++ b/src/gram.h @@ -122,6 +122,8 @@ typedef struct rule_s short assoc; short line; bool useful; + const char *action; + short action_line; } rule_t; extern struct rule_s *rule_table; diff --git a/src/output.c b/src/output.c index f38d63ba..7c2d0136 100644 --- a/src/output.c +++ b/src/output.c @@ -285,8 +285,6 @@ output_rule_data (void) 0, 1, nrules + 1); muscle_insert ("r2", obstack_finish (&output_obstack)); XFREE (short_tab); - - XFREE (rule_table + 1); } /*------------------------------------------------------------------. @@ -512,6 +510,34 @@ token_actions (void) } +/*-----------------------------. +| Output the actions to OOUT. | +`-----------------------------*/ + +static void +actions_output (struct obstack *oout) +{ + int rule; + for (rule = 1; rule < nrules + 1; ++rule) + if (rule_table[rule].action) + { + obstack_fgrow1 (oout, " case %d:\n", rule); + + if (!no_lines_flag) + obstack_fgrow2 (oout, muscle_find ("linef"), + rule_table[rule].action_line, + quotearg_style (c_quoting_style, + muscle_find ("filename"))); + obstack_1grow (oout, '{'); + obstack_sgrow (oout, rule_table[rule].action); + /* As a Bison extension, add the ending semicolon. Since some + Yacc don't do that, help people using bison as a Yacc + finding their missing semicolons. */ + obstack_fgrow1 (oout, "%s}\n break;\n\n", yacc_flag ? ";" : ""); + } +} + + static void save_column (int symbol, int default_state) { @@ -931,10 +957,12 @@ output_parser (const char *skel_filename, struct obstack *oout) /* Output the right value, or see if it's something special. */ muscle_key = obstack_finish (&muscle_obstack); muscle_value = muscle_find (muscle_key); - if (muscle_value) - obstack_sgrow (oout, muscle_value); + if (!strcmp (muscle_key, "actions")) + actions_output (oout); else if (!strcmp (muscle_key, "line")) obstack_fgrow1 (oout, "%d", line + 1); + else if (muscle_value) + obstack_sgrow (oout, muscle_value); else { obstack_sgrow (oout, "%%"); @@ -1011,11 +1039,6 @@ prepare (void) MUSCLE_INSERT_INT ("ntokens", ntokens); MUSCLE_INSERT_INT ("locations-flag", locations_flag); - - /* We need to save the actions in the muscle %%action. */ - obstack_1grow (&action_obstack, 0); - muscle_insert ("action", obstack_finish (&action_obstack)); - } /*----------------------------------------------------------. @@ -1044,6 +1067,7 @@ output (void) output_master_parser (); + free (rule_table + 1); obstack_free (&muscle_obstack, 0); obstack_free (&output_obstack, 0); obstack_free (&action_obstack, 0); diff --git a/src/reader.c b/src/reader.c index cfcab068..d4046ed9 100644 --- a/src/reader.c +++ b/src/reader.c @@ -41,6 +41,9 @@ typedef struct symbol_list struct symbol_list *next; bucket *sym; int line; + /* The action is attached to the LHS of a rule. */ + const char *action; + int action_line; bucket *ruleprec; } symbol_list; @@ -1131,16 +1134,6 @@ copy_action (symbol_list *rule, int stack_offset) if (semantic_parser) stack_offset = 0; - obstack_fgrow1 (&action_obstack, "\ncase %d:\n", nrules); - - if (!no_lines_flag) - { - obstack_fgrow2 (&action_obstack, muscle_find ("linef"), - lineno, quotearg_style (c_quoting_style, - muscle_find ("filename"))); - } - obstack_1grow (&action_obstack, '{'); - count = 1; c = getc (finput); @@ -1198,13 +1191,9 @@ copy_action (symbol_list *rule, int stack_offset) } } - /* As a Bison extension, add the ending semicolon. Since some Yacc - don't do that, help people using bison as a Yacc finding their - missing semicolons. */ - if (yacc_flag) - obstack_sgrow (&action_obstack, "}\n break;"); - else - obstack_sgrow (&action_obstack, ";\n break;}"); + obstack_1grow (&action_obstack, '\0'); + rule->action = obstack_finish (&action_obstack); + rule->action_line = lineno; } /*-------------------------------------------------------------------. @@ -1879,6 +1868,8 @@ packgram (void) rule_table[ruleno].rhs = itemno; rule_table[ruleno].line = p->line; rule_table[ruleno].useful = TRUE; + rule_table[ruleno].action = p->action; + rule_table[ruleno].action_line = p->action_line; p = p->next; while (p && p->sym) diff --git a/src/symtab.h b/src/symtab.h index b98902e1..c64e4079 100644 --- a/src/symtab.h +++ b/src/symtab.h @@ -50,13 +50,13 @@ typedef struct bucket short prec; associativity assoc; short user_token_number; + /* Points to the other in the identifier-symbol pair for an alias. Special value SALIAS in the identifier half of the identifier-symbol pair for an alias. */ struct bucket *alias; symbol_class class; -} -bucket; +} bucket; extern bucket *firstsymbol;