mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-11 21:33:04 +00:00
symbols: properly fuse the properties of two symbol aliases
This completes and fixesa728075710. Reported by Valentin Tolmer. Before it Bison used to put the properties of the symbols (associativity, printer, etc.) in the 'symbol' structure. An identifier-named token (FOO) and its string-named alias ("foo") duplicated these properties, and symbol_check_alias_consistency() checked that both had compatible properties and fused them, at the end of the parsing of the grammar. The commita728075710introduces a sym_content structure that keeps all these properties, and ensures that both aliases point to the same sym_content (instead of duplicating). However, it removed symbol_check_alias_consistency, which resulted in the non-fusion of *existing* properties: %token FOO "foo" %left FOO %left "foo" was properly diagnosed as a redeclaration, but %left FOO %left "foo" %token FOO "foo" was not, as the properties of FOO and "foo" were not checked before fusion. It certainly also means that %left "foo" %token FOO "foo" did not transfer properly the associativity to FOO. The fix is simple: reintroduce symbol_check_alias_consistency (under a better name, symbol_merge_properties) and call it where appropriate. Also, that commit made USER_NUMBER_HAS_STRING_ALIAS useless, but left it. * src/symtab.h (USER_NUMBER_HAS_STRING_ALIAS): Remove, unused. Adjust dependencies. * src/symtab.c (symbol_merge_properties): New, based on the former symbol_check_alias_consistency. * tests/input.at: Re-enable tests that we now pass.
This commit is contained in:
43
src/symtab.c
43
src/symtab.c
@@ -269,7 +269,6 @@ is_identifier (uniqstr s)
|
||||
uniqstr
|
||||
symbol_id_get (symbol const *sym)
|
||||
{
|
||||
aver (sym->content->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
|
||||
if (sym->alias)
|
||||
sym = sym->alias;
|
||||
return is_identifier (sym->tag) ? sym->tag : 0;
|
||||
@@ -559,6 +558,45 @@ semantic_type_check_defined_processor (void *sem_type,
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------.
|
||||
| Merge the properties (precedence, associativity, etc.) of SYM, and |
|
||||
| its string-named alias STR; check consistency. |
|
||||
`-------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
symbol_merge_properties (symbol *sym, symbol *str)
|
||||
{
|
||||
if (str->content->type_name != sym->content->type_name)
|
||||
{
|
||||
if (str->content->type_name)
|
||||
symbol_type_set (sym,
|
||||
str->content->type_name, str->content->type_location);
|
||||
else
|
||||
symbol_type_set (str,
|
||||
sym->content->type_name, sym->content->type_location);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < CODE_PROPS_SIZE; ++i)
|
||||
if (str->content->props[i].code)
|
||||
symbol_code_props_set (sym, i, &str->content->props[i]);
|
||||
else if (sym->content->props[i].code)
|
||||
symbol_code_props_set (str, i, &sym->content->props[i]);
|
||||
}
|
||||
|
||||
if (sym->content->prec || str->content->prec)
|
||||
{
|
||||
if (str->content->prec)
|
||||
symbol_precedence_set (sym, str->content->prec, str->content->assoc,
|
||||
str->content->prec_location);
|
||||
else
|
||||
symbol_precedence_set (str, sym->content->prec, sym->content->assoc,
|
||||
sym->content->prec_location);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
symbol_make_alias (symbol *sym, symbol *str, location loc)
|
||||
{
|
||||
@@ -570,6 +608,7 @@ symbol_make_alias (symbol *sym, symbol *str, location loc)
|
||||
_("symbol %s given more than one literal string"), sym->tag);
|
||||
else
|
||||
{
|
||||
symbol_merge_properties (sym, str);
|
||||
sym_content_free (str->content);
|
||||
str->content = sym->content;
|
||||
str->content->symbol = str;
|
||||
@@ -591,8 +630,6 @@ symbol_pack (symbol *this)
|
||||
aver (this->content->number != NUMBER_UNDEFINED);
|
||||
if (this->content->class == nterm_sym)
|
||||
this->content->number += ntokens;
|
||||
else if (this->content->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
|
||||
return true;
|
||||
|
||||
symbols[this->content->number] = this->content->symbol;
|
||||
return true;
|
||||
|
||||
@@ -137,12 +137,6 @@ struct sym_content
|
||||
/** Undefined user number. */
|
||||
# define USER_NUMBER_UNDEFINED -1
|
||||
|
||||
/* 'symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
|
||||
this symbol has a literal string alias. For instance, '%token foo
|
||||
"foo"' has '"foo"' numbered regularly, and 'foo' numbered as
|
||||
USER_NUMBER_HAS_STRING_ALIAS. */
|
||||
# define USER_NUMBER_HAS_STRING_ALIAS -9991
|
||||
|
||||
/* Undefined internal token number. */
|
||||
# define NUMBER_UNDEFINED (-1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user