/* Symbol table manager for Bison,
- Copyright 1984, 1989, 2000, 2001 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.
#include "system.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 int
-hash (const char *key)
-{
- const char *cp;
- int k;
-
- cp = key;
- k = 0;
- while (*cp)
- k = ((k << 1) ^ (*cp++)) & 0x3fff;
-
- return k % TABSIZE;
-}
-
-/*--------------------------------------------------------------.
-| Create a new symbol, named TAG, which hash value is HASHVAL. |
-`--------------------------------------------------------------*/
-
-static bucket *
-bucket_new (const char *tag, int hashval)
+static symbol_t *
+symbol_new (const char *tag)
{
- bucket *res = XMALLOC (bucket, 1);
+ symbol_t *res = XMALLOC (symbol_t, 1);
- res->link = symtab[hashval];
- res->next = NULL;
res->tag = xstrdup (tag);
res->type_name = NULL;
- res->value = 0;
+ res->number = NUMBER_UNDEFINED;
res->prec = 0;
res->assoc = right_assoc;
- res->user_token_number = SUNDEF;
+ res->user_token_number = USER_NUMBER_UNDEFINED;
res->alias = NULL;
res->class = unknown_sym;
}
-void
-tabinit (void)
+/*------------.
+| Free THIS. |
+`------------*/
+
+static void
+symbol_free (symbol_t *this)
{
- symtab = XCALLOC (bucket *, TABSIZE);
+#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. |
+`----------------------*/
- firstsymbol = NULL;
- lastsymbol = NULL;
+/* Initial capacity of symbols hash table. */
+#define HT_INITIAL_CAPACITY 257
+
+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
+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);
}
| yet, create it. |
`----------------------------------------------------------------*/
-bucket *
+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)
- {
- bp = bucket_new (key, hashval);
-
- 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->tag);
- XFREE (bp);
- bp = bptmp;
- }
- }
- XFREE (symtab);
+ hash_do_for_each (symbol_table,
+ (Hash_processor) processor,
+ processor_data);
}