mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-22 02:33:03 +00:00
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:
@@ -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;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
34
src/symtab.c
34
src/symtab.c
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user