]> git.saurik.com Git - bison.git/blobdiff - src/symtab.c
* data/m4sugar/m4sugar.m4: Update from CVS Autoconf.
[bison.git] / src / symtab.c
index c701ccd673b6479f9ff8533305bcdc5db1a0e9c8..598f8ee2b415d46a2802856e194ab51732b39ebd 100644 (file)
@@ -1,5 +1,5 @@
 /* Symbol table manager for Bison,
 /* 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.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
 
 #include "system.h"
 
 
 #include "system.h"
+#include "hash.h"
 #include "symtab.h"
 #include "gram.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)
 {
 {
-  /* Hack, until we have a Bison parser. */
-  extern int lineno;
-
-  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->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->alias = NULL;
   res->class = unknown_sym;
   res->prec = 0;
   res->assoc = right_assoc;
   res->user_token_number = SUNDEF;
   res->alias = NULL;
   res->class = unknown_sym;
-  res->line = lineno;
 
   nsyms++;
 
 
   nsyms++;
 
@@ -72,13 +48,58 @@ bucket_new (const char *tag, int hashval)
 }
 
 
 }
 
 
-void
-tabinit (void)
+/*------------.
+| Free THIS.  |
+`------------*/
+
+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);
+}
+
+
+
+/*----------------------.
+| A symbol_t hash table.  |
+`----------------------*/
+
+/* 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)
 {
 {
-  symtab = XCALLOC (bucket *, TABSIZE);
+  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);
+}
+
 
 
-  firstsymbol = NULL;
-  lastsymbol = NULL;
+/*-------------------------------.
+| 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);
 }
 
 
 }
 
 
@@ -87,69 +108,45 @@ tabinit (void)
 | yet, create it.                                                 |
 `----------------------------------------------------------------*/
 
 | yet, create it.                                                 |
 `----------------------------------------------------------------*/
 
-bucket *
+symbol_t *
 getsym (const char *key)
 {
 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
 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);
 }
 }