From 7b24c424b5413a8790a983bb7027fe2de37b9d82 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 17 Jun 2018 18:15:05 +0200 Subject: [PATCH] add support for typed mid-rule actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prompted on Piotr Marcińczyk's message: http://lists.gnu.org/archive/html/bug-bison/2017-06/msg00000.html. See also http://lists.gnu.org/archive/html/bug-bison/2018-06/msg00001.html. Because their type is unknown to Bison, the values of midrule actions are not treated like the others: they don't have %printer and %destructor support. In addition, in C++, (Bison) variants cannot work properly. Typed midrule actions address these issues. Instead of: exp: { $$ = 1; } { $$ = 2; } { $$ = $1 + $2; } write: exp: { $$ = 1; } { $$ = 2; } { $$ = $1 + $2; } * src/scan-code.h, src/scan-code.l (code_props): Add a `type` field to record the declared type of an action. (code_props_rule_action_init): Add a type argument. * src/parse-gram.y: Accept an optional type tag for actions. * src/reader.h, src/reader.c (grammar_current_rule_action_append): Add a type argument. (grammar_midrule_action): When a mid-rule is typed, pass its type to the defined dummy non terminal symbol. --- THANKS | 1 + src/parse-gram.y | 4 ++-- src/reader.c | 16 +++++++++++----- src/reader.h | 2 +- src/scan-code.h | 12 +++++++++--- src/scan-code.l | 4 +++- 6 files changed, 27 insertions(+), 12 deletions(-) diff --git a/THANKS b/THANKS index c609d158..9d37dc84 100644 --- a/THANKS +++ b/THANKS @@ -121,6 +121,7 @@ Peter Simons simons@cryp.to Petr Machata pmachata@redhat.com Pho pho@cielonegro.org Piotr Gackiewicz gacek@intertel.com.pl +Piotr Marcińczyk piomar123@gmail.com Quentin Hocquet hocquet@gostai.com Quoc Peyrot chojin@lrde.epita.fr R Blake blakers@mac.com diff --git a/src/parse-gram.y b/src/parse-gram.y index be597ae2..cf3be6d6 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -613,8 +613,8 @@ rhs: current_lhs_named_ref); } | rhs symbol named_ref.opt { grammar_current_rule_symbol_append ($2, @2, $3); } -| rhs "{...}" named_ref.opt - { grammar_current_rule_action_append ($2, @2, $3); } +| rhs tag.opt "{...}"[act] named_ref.opt[name] + { grammar_current_rule_action_append ($act, @act, $name, current_type); } | rhs "%?{...}" { grammar_current_rule_predicate_append ($2, @2); } | rhs "%empty" diff --git a/src/reader.c b/src/reader.c index dcdcb45e..52cff91b 100644 --- a/src/reader.c +++ b/src/reader.c @@ -368,7 +368,7 @@ grammar_current_rule_end (location loc) /*-------------------------------------------------------------------. -| The previous action turns out the be a mid-rule action. Attach it | +| The previous action turns out to be a mid-rule action. Attach it | | to the current rule, i.e., create a dummy symbol, attach it this | | mid-rule action, and append this dummy nonterminal to the current | | rule. | @@ -385,6 +385,8 @@ grammar_midrule_action (void) action. Create the MIDRULE. */ location dummy_location = current_rule->action_props.location; symbol *dummy = dummy_symbol_get (dummy_location); + symbol_type_set(dummy, + current_rule->action_props.type, current_rule->action_props.location); symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location); /* Remember named_ref of previous action. */ @@ -399,7 +401,9 @@ grammar_midrule_action (void) code_props_rule_action_init (&midrule->action_props, current_rule->action_props.code, current_rule->action_props.location, - midrule, 0, + midrule, + /* name_ref */ NULL, + /* type */ NULL, current_rule->action_props.is_predicate); code_props_none_init (¤t_rule->action_props); @@ -520,14 +524,15 @@ grammar_current_rule_symbol_append (symbol *sym, location loc, void grammar_current_rule_action_append (const char *action, location loc, - named_ref *name) + named_ref *name, uniqstr type) { if (current_rule->action_props.code) grammar_midrule_action (); /* After all symbol declarations have been parsed, packgram invokes code_props_translate_code. */ code_props_rule_action_init (¤t_rule->action_props, action, loc, - current_rule, name, + current_rule, + name, type, /* is_predicate */ false); } @@ -537,7 +542,8 @@ grammar_current_rule_predicate_append (const char *pred, location loc) if (current_rule->action_props.code) grammar_midrule_action (); code_props_rule_action_init (¤t_rule->action_props, pred, loc, - current_rule, NULL, + current_rule, + NULL, NULL, /* is_predicate */ true); } diff --git a/src/reader.h b/src/reader.h index 404262ac..70128be0 100644 --- a/src/reader.h +++ b/src/reader.h @@ -56,7 +56,7 @@ void grammar_current_rule_symbol_append (symbol *sym, location loc, named_ref *nref); /* Attach an ACTION to the current rule. */ void grammar_current_rule_action_append (const char *action, location loc, - named_ref *nref); + named_ref *nref, uniqstr tag); /* Attach a PREDICATE to the current rule. */ void grammar_current_rule_predicate_append (const char *predicate, location loc); void reader (void); diff --git a/src/scan-code.h b/src/scan-code.h index ed70d25b..fb8b4a27 100644 --- a/src/scan-code.h +++ b/src/scan-code.h @@ -23,6 +23,7 @@ # include "location.h" # include "named-ref.h" +# include "uniqstr.h" struct symbol_list; @@ -81,8 +82,11 @@ typedef struct code_props { /** \c NULL iff \c code_props::kind is not \c CODE_PROPS_RULE_ACTION. */ struct symbol_list *rule; - /* Named reference. */ + /** Named reference. */ named_ref *named_ref; + + /** Type, for mid-rule actions. */ + uniqstr type; } code_props; /** @@ -103,7 +107,8 @@ void code_props_none_init (code_props *self); /* .is_predicate = */ false, \ /* .is_used = */ false, \ /* .rule = */ NULL, \ - /* .named_ref = */ NULL \ + /* .named_ref = */ NULL, \ + /* .type = */ NULL, \ } /** Initialized by \c CODE_PROPS_NONE_INIT with no further modification. */ @@ -158,7 +163,8 @@ void code_props_symbol_action_init (code_props *self, char const *code, */ void code_props_rule_action_init (code_props *self, char const *code, location code_loc, struct symbol_list *rule, - named_ref *name, bool is_predicate); + named_ref *name, uniqstr type, + bool is_predicate); /** * \pre diff --git a/src/scan-code.l b/src/scan-code.l index e79e8859..0723224d 100644 --- a/src/scan-code.l +++ b/src/scan-code.l @@ -825,7 +825,8 @@ code_props_symbol_action_init (code_props *self, char const *code, void code_props_rule_action_init (code_props *self, char const *code, location code_loc, symbol_list *rule, - named_ref *name, bool is_predicate) + named_ref *name, uniqstr type, + bool is_predicate) { code_props_none_init (self); self->kind = CODE_PROPS_RULE_ACTION; @@ -833,6 +834,7 @@ code_props_rule_action_init (code_props *self, char const *code, self->location = code_loc; self->rule = rule; self->named_ref = name; + self->type = type; self->is_predicate = is_predicate; }