X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/7612000cb004ae5b8516e3a34a79ab32050d688e..0164db681e22e56db4b01990e72b335b66f48197:/src/symtab.c diff --git a/src/symtab.c b/src/symtab.c index 6f325fc3..598f8ee2 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -1,150 +1,152 @@ /* Symbol table manager for Bison, - Copyright (C) 1984, 1989 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. + This file is part of Bison, the GNU Compiler Compiler. -Bison is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. + Bison is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. -Bison is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + Bison is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with Bison; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + You should have received a copy of the GNU General Public License + along with Bison; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ -#include #include "system.h" -#include "alloc.h" +#include "hash.h" #include "symtab.h" #include "gram.h" +/*---------------------------------. +| Create a new symbol, named TAG. | +`---------------------------------*/ -bucket **symtab; -bucket *firstsymbol; -bucket *lastsymbol; +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 = SUNDEF; + res->alias = NULL; + res->class = unknown_sym; + nsyms++; + + return res; +} -int -hash(key) -char *key; -{ - register char *cp; - register int k; - cp = key; - k = 0; - while (*cp) - k = ((k << 1) ^ (*cp++)) & 0x3fff; +/*------------. +| Free THIS. | +`------------*/ - return (k % TABSIZE); +static void +symbol_free (symbol_t *this) +{ +#if 0 + /* This causes crashes because one string can appear more + than once. */ + XFREE (this->type_name); +#endif + XFREE (this->tag); + XFREE (this); } -char * -copys(s) -char *s; -{ - register int i; - register char *cp; - register char *result; +/*----------------------. +| A symbol_t hash table. | +`----------------------*/ - i = 1; - for (cp = s; *cp; cp++) - i++; +/* Initial capacity of symbols hash table. */ +#define HT_INITIAL_CAPACITY 257 - result = xmalloc((unsigned int)i); - strcpy(result, s); - return (result); -} +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; +} -void -tabinit() +static unsigned int +hash_symbol_t (const symbol_t *m, unsigned int tablesize) { -/* register int i; JF unused */ + return hash_string (m->tag, tablesize); +} + - symtab = NEW2(TABSIZE, bucket *); +/*-------------------------------. +| Create the symbol_t hash table. | +`-------------------------------*/ - firstsymbol = NULL; - lastsymbol = NULL; +void +symbols_new (void) +{ + 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 * -getsym(key) -char *key; +/*----------------------------------------------------------------. +| Find the symbol named KEY, and return it. If it does not exist | +| yet, create it. | +`----------------------------------------------------------------*/ + +symbol_t * +getsym (const char *key) { - register int hashval; - register bucket *bp; - register 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 = NEW(bucket); - bp->link = symtab[hashval]; - bp->next = NULL; - bp->tag = copys(key); - bp->class = SUNKNOWN; - - 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() +symbols_do (symbol_processor processor, void *processor_data) { - register int i; - register 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) - FREE(bp->type_name); -#endif - FREE(bp); - bp = bptmp; - } - } - FREE(symtab); + hash_do_for_each (symbol_table, + (Hash_processor) processor, + processor_data); }