mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
add support for typed mid-rule actions
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: { $<ival>$ = 1; } { $<ival>$ = 2; } { $$ = $<ival>1 + $<ival>2; } write: exp: <ival>{ $$ = 1; } <ival>{ $$ = 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.
This commit is contained in:
1
THANKS
1
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
|
||||
|
||||
@@ -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"
|
||||
|
||||
16
src/reader.c
16
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user