From 157f12c483783315a4b9a6f9ffa7731d532e1de5 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 30 Nov 2018 06:11:00 +0100 Subject: [PATCH] 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. --- src/parse-gram.y | 20 +++----------------- src/symtab.c | 34 +++++++++++++++++++++------------- src/symtab.h | 9 ++++++++- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/parse-gram.y b/src/parse-gram.y index bfb0f351..e9aee7dd 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -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); } ; diff --git a/src/symtab.c b/src/symtab.c index 9a062aaf..5a9c7ac6 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -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) diff --git a/src/symtab.h b/src/symtab.h index 71ade8a7..23806b5f 100644 --- a/src/symtab.h +++ b/src/symtab.h @@ -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);