X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/073f92889fed2bb511833920e841243a749223ca..ec5479ce351b0365549e9c7d570b0ee86a4a6589:/src/symtab.c?ds=inline diff --git a/src/symtab.c b/src/symtab.c index 1f2c17ee..821ad56c 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -41,6 +41,15 @@ symbol *accept = NULL; symbol *startsymbol = NULL; location startsymbol_location; +/*-----------------------------------. +| Default %destructor and %printer. | +`-----------------------------------*/ + +static const char *default_destructor = NULL; +static location default_destructor_location; +static const char *default_printer = NULL; +static location default_printer_location; + /*---------------------------------. | Create a new symbol, named TAG. | `---------------------------------*/ @@ -108,7 +117,7 @@ static void redeclaration (symbol* s, const char *what, location first, location second) { complain_at (second, _("%s redeclaration for %s"), what, s->tag); - complain_at (first, _("first declaration")); + complain_at (first, _("previous declaration")); } @@ -147,6 +156,33 @@ symbol_destructor_set (symbol *sym, const char *destructor, location loc) } } +/*---------------------------------------. +| Get the computed %destructor for SYM. | +`---------------------------------------*/ + +const char * +symbol_destructor_get (symbol *sym) +{ + /* Token 0 cannot have a %destructor unless the user renames it. */ + if (UNIQSTR_EQ (sym->tag, uniqstr_new ("$end"))) + return NULL; + + if (sym->destructor != NULL) + return sym->destructor; + return default_destructor; +} + +/*---------------------------------------------------------------. +| Get the grammar location of the %destructor computed for SYM. | +`---------------------------------------------------------------*/ + +location +symbol_destructor_location_get (symbol *sym) +{ + if (sym->destructor != NULL) + return sym->destructor_location; + return default_destructor_location; +} /*---------------------------------------------------------------. | Set the PRINTER associated with SYM. Do nothing if passed 0. | @@ -158,12 +194,40 @@ symbol_printer_set (symbol *sym, const char *printer, location loc) if (printer) { if (sym->printer) - redeclaration (sym, "%printer", sym->destructor_location, loc); + redeclaration (sym, "%printer", sym->printer_location, loc); sym->printer = printer; sym->printer_location = loc; } } +/*------------------------------------. +| Get the computed %printer for SYM. | +`------------------------------------*/ + +const char * +symbol_printer_get (symbol *sym) +{ + /* Token 0 cannot have a %printer unless the user renames it. */ + if (UNIQSTR_EQ (sym->tag, uniqstr_new ("$end"))) + return NULL; + + if (sym->printer != NULL) + return sym->printer; + return default_printer; +} + +/*------------------------------------------------------------. +| Get the grammar location of the %printer computed for SYM. | +`------------------------------------------------------------*/ + +location +symbol_printer_location_get (symbol *sym) +{ + if (sym->printer != NULL) + return sym->printer_location; + return default_printer_location; +} + /*-----------------------------------------------------------------. | Set the PRECEDENCE associated with SYM. Does nothing if invoked | @@ -223,8 +287,7 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring) void symbol_user_token_number_set (symbol *sym, int user_token_number, location loc) { - if (sym->class != token_sym) - abort (); + assert (sym->class == token_sym); if (sym->user_token_number != USER_NUMBER_UNDEFINED && sym->user_token_number != user_token_number) @@ -295,8 +358,7 @@ symbol_make_alias (symbol *sym, symbol *symval, location loc) /* sym and symval combined are only one symbol. */ nsyms--; ntokens--; - if (ntokens != sym->number && ntokens != symval->number) - abort (); + assert (ntokens == sym->number || ntokens == symval->number); sym->number = symval->number = (symval->number < sym->number) ? symval->number : sym->number; symbol_type_set (symval, sym->type_name, loc); @@ -389,8 +451,7 @@ symbol_pack (symbol *this) this->number = this->alias->number = 0; else { - if (this->alias->number == NUMBER_UNDEFINED) - abort (); + assert (this->alias->number != NUMBER_UNDEFINED); this->number = this->alias->number; } } @@ -399,10 +460,7 @@ symbol_pack (symbol *this) return true; } else /* this->class == token_sym */ - { - if (this->number == NUMBER_UNDEFINED) - abort (); - } + assert (this->number != NUMBER_UNDEFINED); symbols[this->number] = this; return true; @@ -505,12 +563,11 @@ symbols_new (void) `----------------------------------------------------------------*/ symbol * -symbol_get (const char *key, location loc) +symbol_from_uniqstr (const uniqstr key, location loc) { symbol probe; symbol *entry; - key = uniqstr_new (key); probe.tag = key; entry = hash_lookup (symbol_table, &probe); @@ -524,6 +581,18 @@ symbol_get (const char *key, location loc) } +/*----------------------------------------------------------------. +| Find the symbol named KEY, and return it. If it does not exist | +| yet, create it. | +`----------------------------------------------------------------*/ + +symbol * +symbol_get (const char *key, location loc) +{ + return symbol_from_uniqstr (uniqstr_new (key), loc); +} + + /*------------------------------------------------------------------. | Generate a dummy nonterminal, whose name cannot conflict with the | | user's names. | @@ -661,3 +730,32 @@ symbols_pack (void) _("the start symbol %s is a token"), startsymbol->tag); } + + +/*-----------------------------------. +| Set default %destructor/%printer. | +`-----------------------------------*/ + +void +default_destructor_set (const char *destructor, location loc) +{ + if (default_destructor != NULL) + { + complain_at (loc, _("redeclaration for default %%destructor")); + complain_at (default_destructor_location, _("previous declaration")); + } + default_destructor = destructor; + default_destructor_location = loc; +} + +void +default_printer_set (const char *printer, location loc) +{ + if (default_printer != NULL) + { + complain_at (loc, _("redeclaration for default %%printer")); + complain_at (default_printer_location, _("previous declaration")); + } + default_printer = printer; + default_printer_location = loc; +}