parser: move checks inside the called functions

Revamping the handling of the symbols is the grammar is much more
delicate than I anticipated.  Let's first move things around for
clarity.

* src/symtab.c (symbol_make_alias): Don't accept to alias
non-terminals.
(symbol_user_token_number_set): Don't accept user token numbers
for non-terminals.
Don't do anything in case of redefinition, instead of trying to
update.  The flow is eaier to follow this way.
This commit is contained in:
Akim Demaille
2018-11-30 06:11:00 +01:00
parent e1a843cc69
commit 157f12c483
3 changed files with 32 additions and 31 deletions

View File

@@ -466,8 +466,8 @@ symbol.prec:
| symbol INT
{
$$ = $1;
symbol_user_token_number_set ($1, $2, @2);
symbol_class_set ($1, token_sym, @1, false);
symbol_user_token_number_set ($1, $2, @2);
}
;
@@ -507,23 +507,9 @@ symbol_def:
symbol_class_set ($id, current_class, @id, true);
symbol_type_set ($id, current_type, @id);
if (0 <= $num)
{
if (current_class != token_sym)
gram_error (&@num,
_("non-terminals cannot be given an explicit number"));
else
symbol_user_token_number_set ($id, $num, @num);
}
symbol_user_token_number_set ($id, $num, @num);
if ($alias)
{
if (current_class != token_sym)
gram_error (&@alias,
_("non-terminals cannot be given a string alias"));
else
symbol_make_alias ($id, $alias, @alias);
}
if (current_class != token_sym && (0 <= $num || $alias))
YYERROR;
symbol_make_alias ($id, $alias, @alias);
}
;

View File

@@ -463,21 +463,26 @@ void
symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
{
int *user_token_numberp = &sym->content->user_token_number;
if (*user_token_numberp != USER_NUMBER_UNDEFINED
&& *user_token_numberp != user_token_number)
if (sym->content->class != token_sym)
complain (&loc, complaint,
_("non-terminals cannot be given an explicit number"));
else if (*user_token_numberp != USER_NUMBER_UNDEFINED
&& *user_token_numberp != user_token_number)
complain (&loc, complaint, _("redefining user token number of %s"),
sym->tag);
*user_token_numberp = user_token_number;
/* User defined $end token? */
if (user_token_number == 0)
else
{
endtoken = sym->content->symbol;
/* It is always mapped to 0, so it was already counted in
NTOKENS. */
if (endtoken->content->number != NUMBER_UNDEFINED)
--ntokens;
endtoken->content->number = 0;
*user_token_numberp = user_token_number;
/* User defined $end token? */
if (user_token_number == 0)
{
endtoken = sym->content->symbol;
/* It is always mapped to 0, so it was already counted in
NTOKENS. */
if (endtoken->content->number != NUMBER_UNDEFINED)
--ntokens;
endtoken->content->number = 0;
}
}
}
@@ -594,7 +599,10 @@ symbol_merge_properties (symbol *sym, symbol *str)
void
symbol_make_alias (symbol *sym, symbol *str, location loc)
{
if (str->alias)
if (sym->content->class != token_sym)
complain (&loc, complaint,
_("non-terminals cannot be given a string alias"));
else if (str->alias)
complain (&loc, Wother,
_("symbol %s used more than once as a literal string"), str->tag);
else if (sym->alias)

View File

@@ -137,6 +137,10 @@ struct sym_content
location prec_location;
int prec;
assoc assoc;
/** The user specified token number.
E.g., %token FOO 42.*/
int user_token_number;
symbol_class class;
@@ -212,7 +216,10 @@ code_props *symbol_code_props_get (symbol *sym, code_props_type kind);
Do nothing if invoked with \c undef_assoc as \c assoc. */
void symbol_precedence_set (symbol *sym, int prec, assoc a, location loc);
/** Set the \c class associated with \c sym. */
/** Set the \c class associated with \c sym.
Whether \c declaring means whether this class definition comes
from %nterm or %token. */
void symbol_class_set (symbol *sym, symbol_class class, location loc,
bool declaring);