X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/95e36146a5be4c921c14f82ab80e3612866c4518..ec3bc39:/src/symtab.c diff --git a/src/symtab.c b/src/symtab.c index 08361539..c255a8f3 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -1,5 +1,5 @@ /* Symbol table manager for Bison, - Copyright (C) 1984, 1989, 2000 Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -20,108 +20,133 @@ #include "system.h" -#include "xalloc.h" +#include "hash.h" #include "symtab.h" #include "gram.h" +/*---------------------------------. +| Create a new symbol, named TAG. | +`---------------------------------*/ -bucket *firstsymbol; -static bucket *lastsymbol; -static bucket **symtab; +static symbol_t * +symbol_new (const char *tag) +{ + symbol_t *res = XMALLOC (symbol_t, 1); + + res->tag = xstrdup (tag); + res->type_name = 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; + + nsyms++; + + return res; +} -static int -hash (const char *key) + +/*------------. +| Free THIS. | +`------------*/ + +static void +symbol_free (symbol_t *this) { - const char *cp; - int k; +#if 0 + /* This causes crashes because one string can appear more + than once. */ + XFREE (this->type_name); +#endif + XFREE (this->tag); + XFREE (this); +} + + + +/*----------------------. +| A symbol_t hash table. | +`----------------------*/ - cp = key; - k = 0; - while (*cp) - k = ((k << 1) ^ (*cp++)) & 0x3fff; +/* Initial capacity of symbols hash table. */ +#define HT_INITIAL_CAPACITY 257 - return k % TABSIZE; +static struct hash_table *symbol_table = NULL; + +static bool +hash_compare_symbol_t (const symbol_t *m1, const symbol_t *m2) +{ + return strcmp (m1->tag, m2->tag) ? FALSE : TRUE; } +static unsigned int +hash_symbol_t (const symbol_t *m, unsigned int tablesize) +{ + return hash_string (m->tag, tablesize); +} + + +/*-------------------------------. +| Create the symbol_t hash table. | +`-------------------------------*/ void -tabinit (void) +symbols_new (void) { - symtab = XCALLOC (bucket *, TABSIZE); - - firstsymbol = NULL; - lastsymbol = NULL; + symbol_table = hash_initialize (HT_INITIAL_CAPACITY, + NULL, + (Hash_hasher) hash_symbol_t, + (Hash_comparator) hash_compare_symbol_t, + (Hash_data_freer) symbol_free); } -bucket * +/*----------------------------------------------------------------. +| Find the symbol named KEY, and return it. If it does not exist | +| yet, create it. | +`----------------------------------------------------------------*/ + +symbol_t * getsym (const char *key) { - int hashval; - bucket *bp; - int found; + symbol_t probe; + symbol_t *entry; - hashval = hash (key); - bp = symtab[hashval]; + (const char *) probe.tag = key; + entry = hash_lookup (symbol_table, &probe); - found = 0; - while (bp != NULL && found == 0) + if (!entry) { - if (strcmp (key, bp->tag) == 0) - found = 1; - else - bp = bp->link; + /* First insertion in the hash. */ + entry = symbol_new (key); + hash_insert (symbol_table, entry); } + return entry; +} - if (found == 0) - { - nsyms++; - - bp = XCALLOC (bucket, 1); - bp->link = symtab[hashval]; - bp->next = NULL; - bp->tag = xstrdup (key); - bp->class = unknown_sym; - - if (firstsymbol == NULL) - { - firstsymbol = bp; - lastsymbol = bp; - } - else - { - lastsymbol->next = bp; - lastsymbol = bp; - } - - symtab[hashval] = bp; - } - return bp; +/*-------------------. +| Free the symbols. | +`-------------------*/ + +void +symbols_free (void) +{ + hash_free (symbol_table); } +/*---------------------------------------------------------------. +| Look for undefined symbols, report an error, and consider them | +| terminals. | +`---------------------------------------------------------------*/ + void -free_symtab (void) +symbols_do (symbol_processor processor, void *processor_data) { - int i; - bucket *bp, *bptmp; /* JF don't use ptr after free */ - - for (i = 0; i < TABSIZE; i++) - { - bp = symtab[i]; - while (bp) - { - bptmp = bp->link; -#if 0 - /* This causes crashes because one string can appear more - than once. */ - if (bp->type_name) - XFREE (bp->type_name); -#endif - XFREE (bp); - bp = bptmp; - } - } - XFREE (symtab); + hash_do_for_each (symbol_table, + (Hash_processor) processor, + processor_data); }