xref: /netbsd/external/bsd/byacc/dist/symtab.c (revision 6550d01e)
1 /*	$NetBSD: symtab.c,v 1.5 2010/12/25 23:43:30 christos Exp $	*/
2 /* Id: symtab.c,v 1.9 2010/11/24 15:12:29 tom Exp */
3 
4 #include "defs.h"
5 
6 #include <sys/cdefs.h>
7 __RCSID("$NetBSD: symtab.c,v 1.5 2010/12/25 23:43:30 christos Exp $");
8 
9 /* TABLE_SIZE is the number of entries in the symbol table. */
10 /* TABLE_SIZE must be a power of two.			    */
11 
12 #define	TABLE_SIZE 1024
13 
14 static bucket **symbol_table = 0;
15 bucket *first_symbol;
16 bucket *last_symbol;
17 
18 static int
19 hash(const char *name)
20 {
21     const char *s;
22     int c, k;
23 
24     assert(name && *name);
25     s = name;
26     k = *s;
27     while ((c = *++s) != 0)
28 	k = (31 * k + c) & (TABLE_SIZE - 1);
29 
30     return (k);
31 }
32 
33 bucket *
34 make_bucket(const char *name)
35 {
36     bucket *bp;
37 
38     assert(name != 0);
39 
40     bp = (bucket *)MALLOC(sizeof(bucket));
41     NO_SPACE(bp);
42 
43     bp->link = 0;
44     bp->next = 0;
45 
46     bp->name = MALLOC(strlen(name) + 1);
47     NO_SPACE(bp->name);
48 
49     bp->tag = 0;
50     bp->value = UNDEFINED;
51     bp->index = 0;
52     bp->prec = 0;
53     bp->class = UNKNOWN;
54     bp->assoc = TOKEN;
55     strcpy(bp->name, name);
56 
57     return (bp);
58 }
59 
60 bucket *
61 lookup(const char *name)
62 {
63     bucket *bp, **bpp;
64 
65     bpp = symbol_table + hash(name);
66     bp = *bpp;
67 
68     while (bp)
69     {
70 	if (strcmp(name, bp->name) == 0)
71 	    return (bp);
72 	bpp = &bp->link;
73 	bp = *bpp;
74     }
75 
76     *bpp = bp = make_bucket(name);
77     last_symbol->next = bp;
78     last_symbol = bp;
79 
80     return (bp);
81 }
82 
83 void
84 create_symbol_table(void)
85 {
86     int i;
87     bucket *bp;
88 
89     symbol_table = (bucket **)MALLOC(TABLE_SIZE * sizeof(bucket *));
90     NO_SPACE(symbol_table);
91 
92     for (i = 0; i < TABLE_SIZE; i++)
93 	symbol_table[i] = 0;
94 
95     bp = make_bucket("error");
96     bp->index = 1;
97     bp->class = TERM;
98 
99     first_symbol = bp;
100     last_symbol = bp;
101     symbol_table[hash("error")] = bp;
102 }
103 
104 void
105 free_symbol_table(void)
106 {
107     FREE(symbol_table);
108     symbol_table = 0;
109 }
110 
111 void
112 free_symbols(void)
113 {
114     bucket *p, *q;
115 
116     for (p = first_symbol; p; p = q)
117     {
118 	q = p->next;
119 	FREE(p);
120     }
121 }
122