X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/8efe435c059af57671105fd8671ba97bb8474264..536545f3a45d64cad0469efa125d3d96052e723c:/src/symtab.c diff --git a/src/symtab.c b/src/symtab.c index 0011006d..0a9d6baa 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -20,6 +20,7 @@ #include "system.h" +#include "quotearg.h" #include "hash.h" #include "complain.h" #include "symtab.h" @@ -41,16 +42,22 @@ location_t startsymbol_location; `---------------------------------*/ static symbol_t * -symbol_new (const char *tag) +symbol_new (const char *tag, location_t location) { symbol_t *res = XMALLOC (symbol_t, 1); res->tag = xstrdup (tag); + res->location = location; + res->type_name = NULL; + res->destructor = NULL; + res->printer = NULL; + res->number = NUMBER_UNDEFINED; res->prec = 0; res->assoc = right_assoc; res->user_token_number = USER_NUMBER_UNDEFINED; + res->alias = NULL; res->class = unknown_sym; @@ -65,17 +72,56 @@ symbol_new (const char *tag) `------------------------------------------------------------------*/ void -symbol_type_set (symbol_t *symbol, char *type_name) +symbol_type_set (symbol_t *symbol, char *type_name, location_t location) { if (type_name) { if (symbol->type_name) - complain (_("type redeclaration for %s"), symbol->tag); + complain_at (location, + _("type redeclaration for %s"), symbol->tag); symbol->type_name = type_name; } } +/*-------------------------------------------------------------------. +| Set the DESTRUCTOR associated to SYMBOL. Do nothing if passed 0. | +`-------------------------------------------------------------------*/ + +void +symbol_destructor_set (symbol_t *symbol, char *destructor, location_t location) +{ + if (destructor) + { + if (symbol->destructor) + complain_at (location, + _("%s redeclaration for %s"), + "%destructor", symbol->tag); + symbol->destructor = destructor; + symbol->destructor_location = location; + } +} + + +/*----------------------------------------------------------------. +| Set the PRITNER associated to SYMBOL. Do nothing if passed 0. | +`----------------------------------------------------------------*/ + +void +symbol_printer_set (symbol_t *symbol, char *printer, location_t location) +{ + if (printer) + { + if (symbol->printer) + complain_at (location, + _("%s redeclaration for %s"), + "%printer", symbol->tag); + symbol->printer = printer; + symbol->printer_location = location; + } +} + + /*------------------------------------------------------------------. | Set the PRECEDENCE associated to SYMBOL. Does nothing if invoked | | with UNDEF_ASSOC as ASSOC. | @@ -83,18 +129,20 @@ symbol_type_set (symbol_t *symbol, char *type_name) void symbol_precedence_set (symbol_t *symbol, - int prec, associativity assoc) + int prec, associativity assoc, location_t location) { if (assoc != undef_assoc) { if (symbol->prec != 0) - complain (_("redefining precedence of %s"), symbol->tag); + complain_at (location, + _("redefining precedence of %s"), + symbol->tag); symbol->prec = prec; symbol->assoc = assoc; } /* Only terminals have a precedence. */ - symbol_class_set (symbol, token_sym); + symbol_class_set (symbol, token_sym, location); } @@ -103,10 +151,10 @@ symbol_precedence_set (symbol_t *symbol, `-------------------------------------*/ void -symbol_class_set (symbol_t *symbol, symbol_class class) +symbol_class_set (symbol_t *symbol, symbol_class class, location_t location) { if (symbol->class != unknown_sym && symbol->class != class) - complain (_("symbol %s redefined"), symbol->tag); + complain_at (location, _("symbol %s redefined"), symbol->tag); if (class == nterm_sym && symbol->class != nterm_sym) symbol->number = nvars++; @@ -122,13 +170,15 @@ symbol_class_set (symbol_t *symbol, symbol_class class) `-------------------------------------------------*/ void -symbol_user_token_number_set (symbol_t *symbol, int user_token_number) +symbol_user_token_number_set (symbol_t *symbol, + int user_token_number, location_t location) { assert (symbol->class == token_sym); if (symbol->user_token_number != USER_NUMBER_UNDEFINED && symbol->user_token_number != user_token_number) - complain (_("redefining user token number of %s"), symbol->tag); + complain_at (location, _("redefining user token number of %s"), + symbol->tag); symbol->user_token_number = user_token_number; /* User defined EOF token? */ @@ -170,8 +220,9 @@ symbol_check_defined (symbol_t *this) { if (this->class == unknown_sym) { - complain - (_("symbol %s is used, but is not defined as a token and has no rules"), + complain_at + (this->location, + _("symbol %s is used, but is not defined as a token and has no rules"), this->tag); this->class = nterm_sym; this->number = nvars++; @@ -363,24 +414,48 @@ symbols_new (void) `----------------------------------------------------------------*/ symbol_t * -getsym (const char *key) +symbol_get (const char *key, location_t location) { symbol_t probe; symbol_t *entry; + /* Keep the symbol in a printable form. */ + key = quotearg_style (escape_quoting_style, key); (const char *) probe.tag = key; entry = hash_lookup (symbol_table, &probe); if (!entry) { /* First insertion in the hash. */ - entry = symbol_new (key); + entry = symbol_new (key, location); hash_insert (symbol_table, entry); } return entry; } +/*------------------------------------------------------------------. +| Generate a dummy nonterminal, whose name cannot conflict with the | +| user's names. | +`------------------------------------------------------------------*/ + +symbol_t * +dummy_symbol_get (location_t location) +{ + /* Incremented for each generated symbol. */ + static int dummy_count = 0; + static char buf[256]; + + symbol_t *sym; + + sprintf (buf, "@%d", ++dummy_count); + sym = symbol_get (buf, location); + sym->class = nterm_sym; + sym->number = nvars++; + return sym; +} + + /*-------------------. | Free the symbols. | `-------------------*/ @@ -389,6 +464,7 @@ void symbols_free (void) { hash_free (symbol_table); + free (symbols); } @@ -488,7 +564,11 @@ symbols_pack (void) symbols_token_translations_init (); if (startsymbol->class == unknown_sym) - fatal (_("the start symbol %s is undefined"), startsymbol->tag); + fatal_at (startsymbol_location, + _("the start symbol %s is undefined"), + startsymbol->tag); else if (startsymbol->class == token_sym) - fatal (_("the start symbol %s is a token"), startsymbol->tag); + fatal_at (startsymbol_location, + _("the start symbol %s is a token"), + startsymbol->tag); }