X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/83b60c97ee1f98bb1f15ffa38acdc4cc765515f5..9fd33c2b6ef5d98ac14ac7d83bc453b148fda768:/src/symtab.c diff --git a/src/symtab.c b/src/symtab.c index cac9f80f..ad8820f4 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -1,8 +1,7 @@ /* Symbol table manager for Bison. - Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2006, 2007, - 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 2000-2002, 2004-2012 Free Software + Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -23,7 +22,6 @@ #include "system.h" #include -#include #include "complain.h" #include "gram.h" @@ -87,11 +85,11 @@ symbol_new (uniqstr tag, location loc) res->alias = NULL; res->class = unknown_sym; - res->declared = false; + res->status = undeclared; if (nsyms == SYMBOL_NUMBER_MAXIMUM) fatal (_("too many symbols in input grammar (limit is %d)"), - SYMBOL_NUMBER_MAXIMUM); + SYMBOL_NUMBER_MAXIMUM); nsyms++; return res; } @@ -118,8 +116,8 @@ semantic_type_new (uniqstr tag) | Print a symbol. | `-----------------*/ -#define SYMBOL_ATTR_PRINT(Attr) \ - if (s->Attr) \ +#define SYMBOL_ATTR_PRINT(Attr) \ + if (s->Attr) \ fprintf (f, " %s { %s }", #Attr, s->Attr) #define SYMBOL_CODE_PRINT(Attr) \ @@ -212,31 +210,13 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc) if (type_name) { if (sym->type_name) - symbol_redeclaration (sym, "%type", sym->type_location, loc); + symbol_redeclaration (sym, "%type", sym->type_location, loc); uniqstr_assert (type_name); sym->type_name = type_name; sym->type_location = loc; } } -/*-----------------------------------. -| Get the CLASS associated with SYM. | -`-----------------------------------*/ - -const char * -symbol_class_get_string (symbol *sym) -{ - if (sym->class) - { - if (sym->class == token_sym) - return "terminal"; - else if (sym->class == nterm_sym) - return "nonterminal"; - } - return "unknown"; -} - - /*-----------------------------------------. | Set the DESTRUCTOR associated with SYM. | `-----------------------------------------*/ @@ -359,7 +339,7 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc) if (a != undef_assoc) { if (sym->prec != 0) - symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location, + symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location, loc); sym->prec = prec; sym->assoc = a; @@ -378,10 +358,12 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc) void symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring) { + bool warned = false; if (sym->class != unknown_sym && sym->class != class) { complain_at (loc, _("symbol %s redefined"), sym->tag); - sym->declared = false; + // Don't report both "redefined" and "redeclared". + warned = true; } if (class == nterm_sym && sym->class != nterm_sym) @@ -393,9 +375,9 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring) if (declaring) { - if (sym->declared) - warn_at (loc, _("symbol %s redeclared"), sym->tag); - sym->declared = true; + if (sym->status == declared && !warned) + warn_at (loc, _("symbol %s redeclared"), sym->tag); + sym->status = declared; } } @@ -422,10 +404,11 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc) if (user_token_number == 0) { endtoken = sym; - endtoken->number = 0; /* It is always mapped to 0, so it was already counted in - NTOKENS. */ - --ntokens; + NTOKENS. */ + if (endtoken->number != NUMBER_UNDEFINED) + --ntokens; + endtoken->number = 0; } } @@ -440,10 +423,26 @@ symbol_check_defined (symbol *sym) { if (sym->class == unknown_sym) { - complain_at - (sym->location, - _("symbol %s is used, but is not defined as a token and has no rules"), - sym->tag); + switch (sym->status) + { + case used: + warn_at (sym->location, + _("symbol %s is used, but is not defined as a token" + " and has no rules"), + sym->tag); + break; + case undeclared: + case needed: + complain_at (sym->location, + _("symbol %s is used, but is not defined as a token" + " and has no rules"), + sym->tag); + break; + case declared: + /* If declared, then sym->class != unknown_sym. */ + assert (0); + } + sym->class = nterm_sym; sym->number = nvars++; } @@ -462,11 +461,11 @@ void symbol_make_alias (symbol *sym, symbol *str, location loc) { if (str->alias) - warn_at (loc, _("symbol `%s' used more than once as a literal string"), - str->tag); + warn_at (loc, _("symbol %s used more than once as a literal string"), + str->tag); else if (sym->alias) - warn_at (loc, _("symbol `%s' given more than one literal string"), - sym->tag); + warn_at (loc, _("symbol %s given more than one literal string"), + sym->tag); else { str->class = token_sym; @@ -489,7 +488,7 @@ static inline void symbol_check_alias_consistency (symbol *this) { symbol *sym = this; - symbol *str = this->alias; + symbol *str = this->alias; /* Check only the symbol in the symbol-string pair. */ if (!(this->alias @@ -499,42 +498,42 @@ symbol_check_alias_consistency (symbol *this) if (str->type_name != sym->type_name) { if (str->type_name) - symbol_type_set (sym, str->type_name, str->type_location); + symbol_type_set (sym, str->type_name, str->type_location); else - symbol_type_set (str, sym->type_name, sym->type_location); + symbol_type_set (str, sym->type_name, sym->type_location); } if (str->destructor.code || sym->destructor.code) { if (str->destructor.code) - symbol_destructor_set (sym, &str->destructor); + symbol_destructor_set (sym, &str->destructor); else - symbol_destructor_set (str, &sym->destructor); + symbol_destructor_set (str, &sym->destructor); } if (str->printer.code || sym->printer.code) { if (str->printer.code) - symbol_printer_set (sym, &str->printer); + symbol_printer_set (sym, &str->printer); else - symbol_printer_set (str, &sym->printer); + symbol_printer_set (str, &sym->printer); } if (sym->prec || str->prec) { if (str->prec) - symbol_precedence_set (sym, str->prec, str->assoc, - str->prec_location); + symbol_precedence_set (sym, str->prec, str->assoc, + str->prec_location); else - symbol_precedence_set (str, sym->prec, sym->assoc, - sym->prec_location); + symbol_precedence_set (str, sym->prec, sym->assoc, + sym->prec_location); } } static bool symbol_check_alias_consistency_processor (void *this, - void *null ATTRIBUTE_UNUSED) + void *null ATTRIBUTE_UNUSED) { symbol_check_alias_consistency (this); return true; @@ -549,31 +548,11 @@ symbol_check_alias_consistency_processor (void *this, static inline bool symbol_pack (symbol *this) { + aver (this->number != NUMBER_UNDEFINED); if (this->class == nterm_sym) - { - this->number += ntokens; - } - else if (this->alias) - { - /* This symbol and its alias are a single token defn. - Allocate a tokno, and assign to both check agreement of - prec and assoc fields and make both the same */ - if (this->number == NUMBER_UNDEFINED) - { - if (this == endtoken || this->alias == endtoken) - this->number = this->alias->number = 0; - else - { - aver (this->alias->number != NUMBER_UNDEFINED); - this->number = this->alias->number; - } - } - /* Do not do processing below for USER_NUMBER_HAS_STRING_ALIASes. */ - if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS) - return true; - } - else /* this->class == token_sym */ - aver (this->number != NUMBER_UNDEFINED); + this->number += ntokens; + else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS) + return true; symbols[this->number] = this; return true; @@ -620,7 +599,7 @@ symbol_translation (symbol *this) { /* A token which translation has already been set? */ if (token_translations[this->user_token_number] != undeftoken->number) - user_token_number_redeclaration + user_token_number_redeclaration (this->user_token_number, symbols[token_translations[this->user_token_number]], this); @@ -708,15 +687,15 @@ void symbols_new (void) { symbol_table = hash_initialize (HT_INITIAL_CAPACITY, - NULL, - hash_symbol_hasher, - hash_symbol_comparator, - free); + NULL, + hash_symbol_hasher, + hash_symbol_comparator, + free); semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY, - NULL, - hash_semantic_type_hasher, - hash_semantic_type_comparator, - free); + NULL, + hash_semantic_type_hasher, + hash_semantic_type_comparator, + free); } @@ -900,12 +879,12 @@ symbols_token_translations_init (void) { symbol *this = symbols[i]; if (this->user_token_number != USER_NUMBER_UNDEFINED) - { - if (this->user_token_number > max_user_token_number) - max_user_token_number = this->user_token_number; - if (this->user_token_number == 256) - num_256_available_p = false; - } + { + if (this->user_token_number > max_user_token_number) + max_user_token_number = this->user_token_number; + if (this->user_token_number == 256) + num_256_available_p = false; + } } /* If 256 is not used, assign it to error, to follow POSIX. */ @@ -921,13 +900,13 @@ symbols_token_translations_init (void) { symbol *this = symbols[i]; if (this->user_token_number == USER_NUMBER_UNDEFINED) - this->user_token_number = ++max_user_token_number; + this->user_token_number = ++max_user_token_number; if (this->user_token_number > max_user_token_number) - max_user_token_number = this->user_token_number; + max_user_token_number = this->user_token_number; } token_translations = xnmalloc (max_user_token_number + 1, - sizeof *token_translations); + sizeof *token_translations); /* Initialize all entries for literal tokens to the internal token number for $undefined, which represents all invalid inputs. */ @@ -978,12 +957,12 @@ symbols_pack (void) if (startsymbol->class == unknown_sym) fatal_at (startsymbol_location, - _("the start symbol %s is undefined"), - startsymbol->tag); + _("the start symbol %s is undefined"), + startsymbol->tag); else if (startsymbol->class == token_sym) fatal_at (startsymbol_location, - _("the start symbol %s is a token"), - startsymbol->tag); + _("the start symbol %s is a token"), + startsymbol->tag); } @@ -999,7 +978,7 @@ default_tagged_destructor_set (code_props const *destructor) complain_at (destructor->location, _("redeclaration for default tagged %%destructor")); complain_at (default_tagged_destructor.location, - _("previous declaration")); + _("previous declaration")); } default_tagged_destructor = *destructor; } @@ -1012,7 +991,7 @@ default_tagless_destructor_set (code_props const *destructor) complain_at (destructor->location, _("redeclaration for default tagless %%destructor")); complain_at (default_tagless_destructor.location, - _("previous declaration")); + _("previous declaration")); } default_tagless_destructor = *destructor; } @@ -1025,7 +1004,7 @@ default_tagged_printer_set (code_props const *printer) complain_at (printer->location, _("redeclaration for default tagged %%printer")); complain_at (default_tagged_printer.location, - _("previous declaration")); + _("previous declaration")); } default_tagged_printer = *printer; } @@ -1038,7 +1017,7 @@ default_tagless_printer_set (code_props const *printer) complain_at (printer->location, _("redeclaration for default tagless %%printer")); complain_at (default_tagless_printer.location, - _("previous declaration")); + _("previous declaration")); } default_tagless_printer = *printer; }