xref: /original-bsd/usr.bin/yacc/symtab.c (revision 23c6a147)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Robert Paul Corbett.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the University of California, Berkeley.  The name of the
14  * University may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  */
20 
21 #ifndef lint
22 static char sccsid[] = "@(#)symtab.c	5.2 (Berkeley) 02/15/90";
23 #endif /* not lint */
24 
25 #include "defs.h"
26 
27 /* TABLE_SIZE is the number of entries in the symbol table. */
28 /* TABLE_SIZE must be a power of two.			    */
29 
30 #define	TABLE_SIZE 1024
31 
32 
33 bucket **symbol_table;
34 bucket *first_symbol;
35 bucket *last_symbol;
36 
37 
38 int
39 hash(name)
40 char *name;
41 {
42     register char *s;
43     register int c, k;
44 
45     assert(name && *name);
46     s = name;
47     k = *s;
48     while (c = *++s)
49 	k = (31*k + c) & (TABLE_SIZE - 1);
50 
51     return (k);
52 }
53 
54 
55 bucket *
56 make_bucket(name)
57 char *name;
58 {
59     register bucket *bp;
60 
61     assert(name);
62     bp = (bucket *) MALLOC(sizeof(bucket));
63     if (bp == 0) no_space();
64     bp->link = 0;
65     bp->next = 0;
66     bp->name = MALLOC(strlen(name) + 1);
67     if (bp->name == 0) no_space();
68     bp->tag = 0;
69     bp->value = UNDEFINED;
70     bp->index = 0;
71     bp->prec = 0;
72     bp-> class = UNKNOWN;
73     bp->assoc = TOKEN;
74 
75     if (bp->name == 0) no_space();
76     strcpy(bp->name, name);
77 
78     return (bp);
79 }
80 
81 
82 bucket *
83 lookup(name)
84 char *name;
85 {
86     register bucket *bp, **bpp;
87 
88     bpp = symbol_table + hash(name);
89     bp = *bpp;
90 
91     while (bp)
92     {
93 	if (strcmp(name, bp->name) == 0) return (bp);
94 	bpp = &bp->link;
95 	bp = *bpp;
96     }
97 
98     *bpp = bp = make_bucket(name);
99     last_symbol->next = bp;
100     last_symbol = bp;
101 
102     return (bp);
103 }
104 
105 
106 create_symbol_table()
107 {
108     register int i;
109     register bucket *bp;
110 
111     symbol_table = (bucket **) MALLOC(TABLE_SIZE*sizeof(bucket *));
112     if (symbol_table == 0) no_space();
113     for (i = 0; i < TABLE_SIZE; i++)
114 	symbol_table[i] = 0;
115 
116     bp = make_bucket("error");
117     bp->index = 1;
118     bp->class = TERM;
119 
120     first_symbol = bp;
121     last_symbol = bp;
122     symbol_table[hash("error")] = bp;
123 }
124 
125 
126 free_symbol_table()
127 {
128     FREE(symbol_table);
129     symbol_table = 0;
130 }
131 
132 
133 free_symbols()
134 {
135     register bucket *p, *q;
136 
137     for (p = first_symbol; p; p = q)
138     {
139 	q = p->next;
140 	FREE(p);
141     }
142 }
143