1 /* Copyright (c) 1991 by the Vrije Universiteit, Amsterdam, the Netherlands.
2 * For full copyright and restrictions on use see the file COPYING in the top
3 * level of the LLgen tree.
9 * An Extended LL(1) Parser Generator
11 * Author : Ceriel J.H. Jacobs
16 * Defines the symboltable search routine, a name store routine and an
17 * initialising routine.
26 static string rcsid7 = "$Id: name.c,v 2.11 1997/02/21 11:27:53 ceriel Exp $";
30 # define NMSIZ 2048 /* Room for names allocated NMSIZ bytes at a time */
32 static char *name, *maxname;
33 static p_entry h_root[HASHSIZE]; /* hash table */
34 static string e_literal = "Illegal literal";
35 static p_entry entries, maxentries;
36 static t_info token_info, nont_info;
38 /* Defined in this file are: */
39 extern string store();
42 STATIC p_entry newentry();
43 extern p_gram search();
49 token_info.i_esize = sizeof (t_token);
50 token_info.i_incr = 50;
51 nont_info.i_esize = sizeof (t_nont);
52 nont_info.i_incr = 50;
53 search(TERMINAL,"EOFILE",ENTERING);
55 illegal_gram = search(TERMINAL,"LLILLEGAL",ENTERING);
60 newentry(str, next) string str; p_entry next; {
63 if ((p = entries) == maxentries) {
64 p = (p_entry) alloc(50 * sizeof(t_entry));
70 p->h_type.g_lineno = linecount;
72 p->h_type.g_erroneous = 0;
80 * Store a string s in the name table
82 register string s1, t ,u;
101 hash(str) string str; {
103 * Compute the hash for string str
110 while (*l != '\0') i += *l++ & 0377;
116 search(type,str,option) register string str; {
118 * Search for object str.
119 * It has type UNKNOWN, LITERAL, TERMINAL or NONTERM.
120 * option can be ENTERING or BOTH (also looking).
122 register int val = 0;
131 for (p = h_root[i]; p != (p_entry) 0; p = p->h_next) {
132 if(!strcmp(p->h_name,str)) {
133 type1 = g_gettype(&(p->h_type));
135 if (type1 == LITERAL || type == LITERAL) {
138 if (type == TERMINAL) {
140 "%s: is already a nonterminal",
144 else if (type == NONTERM) {
146 "%s : is already a token",
151 if (option==ENTERING) {
153 "%s : is already defined",str);
155 p->h_type.g_lineno = linecount;
159 p = newentry(store(str), h_root[i]);
161 if (type == TERMINAL || type == LITERAL) {
164 pt = (p_token) new_mem(&token_info);
165 tokens = (p_token) token_info.i_ptr;
166 pt->t_string = p->h_name;
167 if (type == LITERAL) {
168 if (str[0] == '\\') {
170 * Handle escapes in literals
172 if (str[2] == '\0') {
196 error(linecount,e_literal);
200 * Here, str[2] != '\0'
202 if (str[1] > '3' || str[1] < '0' ||
203 str[2] > '7' || str[2] < '0' ||
204 str[3] > '7' || str[3] < '0' ||
205 str[4] != '\0') error(linecount,e_literal);
206 val = 64*str[1] - 73*'0' +
211 * No escape in literal
213 if (str[1] == '\0') val = str[0];
214 else error(linecount,e_literal);
217 g_settype(&(p->h_type), LITERAL);
220 * Here, type = TERMINAL
222 pt->t_tokno = assval++;
223 g_settype(&(p->h_type), TERMINAL);
225 g_setcont(&(p->h_type), ntokens);
230 * type == NONTERM || type == UNKNOWN
231 * UNKNOWN and not yet declared means : NONTERM
236 q = (p_nont) new_mem(&nont_info);
237 nonterms = (p_nont) nont_info.i_ptr;
238 q->n_name = p->h_name;
240 q->n_lineno = linecount;
241 q->n_string = f_input;
245 g_settype(&(p->h_type), NONTERM);
246 g_setcont(&(p->h_type), nnonterms);
247 g_setnpar(&(p->h_type), 0);