/[bison]/bison/src/symtab.c
ViewVC logotype

Diff of /bison/src/symtab.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.19 by akim, Sun Apr 7 15:29:56 2002 UTC revision 1.20 by akim, Sun Apr 7 17:43:21 2002 UTC
# Line 1  Line 1 
1  /* Symbol table manager for Bison,  /* Symbol table manager for Bison,
2     Copyright 1984, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.     Copyright (C) 1984, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
3    
4     This file is part of Bison, the GNU Compiler Compiler.     This file is part of Bison, the GNU Compiler Compiler.
5    
# Line 20  Line 20 
20    
21    
22  #include "system.h"  #include "system.h"
23    #include "hash.h"
24  #include "symtab.h"  #include "symtab.h"
25  #include "gram.h"  #include "gram.h"
26    
27    /*---------------------------------.
28  bucket *firstsymbol;  | Create a new symbol, named TAG.  |
29  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.  |  
 `--------------------------------------------------------------*/  
30    
31  static bucket *  static bucket *
32  bucket_new (const char *tag, int hashval)  bucket_new (const char *tag)
33  {  {
34    bucket *res = XMALLOC (bucket, 1);    bucket *res = XMALLOC (bucket, 1);
35    
   res->link = symtab[hashval];  
   res->next = NULL;  
36    res->tag = xstrdup (tag);    res->tag = xstrdup (tag);
37    res->type_name = NULL;    res->type_name = NULL;
38    res->number = -1;    res->number = -1;
# Line 62  bucket_new (const char *tag, int hashval Line 42  bucket_new (const char *tag, int hashval
42    res->alias = NULL;    res->alias = NULL;
43    res->class = unknown_sym;    res->class = unknown_sym;
44    
45      if (getenv ("DEBUG"))
46        fprintf (stderr, "Creating: nsyms = %d, ntokens = %d: %s\n",
47                 nsyms, ntokens, tag);
48    nsyms++;    nsyms++;
49    
50    return res;    return res;
51  }  }
52    
53    
54  void  /*------------.
55  tabinit (void)  | Free THIS.  |
56    `------------*/
57    
58    static void
59    bucket_free (bucket *this)
60  {  {
61    symtab = XCALLOC (bucket *, TABSIZE);  #if 0
62      /* This causes crashes because one string can appear more
63         than once.  */
64      XFREE (this->type_name);
65    #endif
66      XFREE (this->tag);
67      XFREE (this);
68    }
69    
70    
71    
72    /*----------------------.
73    | A bucket hash table.  |
74    `----------------------*/
75    
76    firstsymbol = NULL;  /* Initial capacity of buckets hash table.  */
77    lastsymbol = NULL;  #define HT_INITIAL_CAPACITY 257
78    
79    static struct hash_table *bucket_table = NULL;
80    
81    static bool
82    hash_compare_bucket (const bucket *m1, const bucket *m2)
83    {
84      return strcmp (m1->tag, m2->tag) ? FALSE : TRUE;
85    }
86    
87    static unsigned int
88    hash_bucket (const bucket *m, unsigned int tablesize)
89    {
90      return hash_string (m->tag, tablesize);
91    }
92    
93    
94    /*-------------------------------.
95    | Create the bucket hash table.  |
96    `-------------------------------*/
97    
98    void
99    buckets_new (void)
100    {
101      bucket_table = hash_initialize (HT_INITIAL_CAPACITY,
102                                      NULL,
103                                      (Hash_hasher) hash_bucket,
104                                      (Hash_comparator) hash_compare_bucket,
105                                      (Hash_data_freer) bucket_free);
106  }  }
107    
108    
# Line 86  tabinit (void) Line 114  tabinit (void)
114  bucket *  bucket *
115  getsym (const char *key)  getsym (const char *key)
116  {  {
117    int hashval;    bucket probe;
118    bucket *bp;    bucket *entry;
   int found;  
119    
120    hashval = hash (key);    (const char *) probe.tag = key;
121    bp = symtab[hashval];    entry = hash_lookup (bucket_table, &probe);
122    
123    found = 0;    if (!entry)
   while (bp != NULL && found == 0)  
124      {      {
125        if (strcmp (key, bp->tag) == 0)        /* First insertion in the hash. */
126          found = 1;        entry = bucket_new (key);
127        else        hash_insert (bucket_table, entry);
         bp = bp->link;  
128      }      }
129      return entry;
130    }
131    
   if (found == 0)  
     {  
       bp = bucket_new (key, hashval);  
132    
133        if (firstsymbol == NULL)  /*-------------------.
134          {  | Free the buckets.  |
135            firstsymbol = bp;  `-------------------*/
           lastsymbol = bp;  
         }  
       else  
         {  
           lastsymbol->next = bp;  
           lastsymbol = bp;  
         }  
136    
137        symtab[hashval] = bp;  void
138      }  buckets_free (void)
139    {
140    return bp;    hash_free (bucket_table);
141  }  }
142    
143    
144    /*---------------------------------------------------------------.
145    | Look for undefined buckets, report an error, and consider them |
146    | terminals.                                                     |
147    `---------------------------------------------------------------*/
148    
149  void  void
150  free_symtab (void)  buckets_do (bucket_processor processor, void *processor_data)
151  {  {
152    int i;    hash_do_for_each (bucket_table,
153    bucket *bp, *bptmp;           /* JF don't use ptr after free */                      (Hash_processor) processor,
154                        processor_data);
   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);  
155  }  }

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.20

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26