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 | symbol INT
{ {
$$ = $1; $$ = $1;
symbol_user_token_number_set ($1, $2, @2);
symbol_class_set ($1, token_sym, @1, false); 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_class_set ($id, current_class, @id, true);
symbol_type_set ($id, current_type, @id); symbol_type_set ($id, current_type, @id);
if (0 <= $num) if (0 <= $num)
{ symbol_user_token_number_set ($id, $num, @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);
}
if ($alias) if ($alias)
{ symbol_make_alias ($id, $alias, @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;
} }
; ;

View File

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

View File

@@ -137,6 +137,10 @@ struct sym_content
location prec_location; location prec_location;
int prec; int prec;
assoc assoc; assoc assoc;
/** The user specified token number.
E.g., %token FOO 42.*/
int user_token_number; int user_token_number;
symbol_class class; 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. */ Do nothing if invoked with \c undef_assoc as \c assoc. */
void symbol_precedence_set (symbol *sym, int prec, assoc a, location loc); 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, void symbol_class_set (symbol *sym, symbol_class class, location loc,
bool declaring); bool declaring);