]> git.saurik.com Git - bison.git/blame - src/symtab.c
Merge remote-tracking branch 'origin/maint'
[bison.git] / src / symtab.c
CommitLineData
0fb1efaf
PE
1/* Symbol table manager for Bison.
2
34136e65 3 Copyright (C) 1984, 1989, 2000-2002, 2004-2012 Free Software
575619af 4 Foundation, Inc.
40675e7c 5
95e36146 6 This file is part of Bison, the GNU Compiler Compiler.
40675e7c 7
f16b0819 8 This program is free software: you can redistribute it and/or modify
95e36146 9 it under the terms of the GNU General Public License as published by
f16b0819
PE
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
40675e7c 12
f16b0819 13 This program is distributed in the hope that it will be useful,
95e36146
AD
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
40675e7c 17
95e36146 18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
40675e7c 20
2cec9080 21#include <config.h>
40675e7c 22#include "system.h"
17ee7397
PE
23
24#include <hash.h>
17ee7397 25
2f1afb73 26#include "complain.h"
40675e7c 27#include "gram.h"
17ee7397 28#include "symtab.h"
40675e7c 29
83b60c97
JD
30/*-------------------------------------------------------------------.
31| Symbols sorted by tag. Allocated by the first invocation of |
32| symbols_do, after which no more symbols should be created. |
33`-------------------------------------------------------------------*/
34
35static symbol **symbols_sorted = NULL;
9641b918 36static symbol **semantic_types_sorted = NULL;
83b60c97 37
2f1afb73
AD
38/*------------------------.
39| Distinguished symbols. |
40`------------------------*/
41
17ee7397
PE
42symbol *errtoken = NULL;
43symbol *undeftoken = NULL;
44symbol *endtoken = NULL;
45symbol *accept = NULL;
46symbol *startsymbol = NULL;
47location startsymbol_location;
2f1afb73 48
ec5479ce 49
72a23c97
AD
50/*---------------------------------.
51| Create a new symbol, named TAG. |
52`---------------------------------*/
1e9798d5 53
17ee7397
PE
54static symbol *
55symbol_new (uniqstr tag, location loc)
1e9798d5 56{
da2a7671 57 symbol *res = xmalloc (sizeof *res);
1e9798d5 58
17ee7397 59 uniqstr_assert (tag);
4f646c37
AD
60
61 /* If the tag is not a string (starts with a double quote), check
62 that it is valid for Yacc. */
84526bf3 63 if (tag[0] != '\"' && tag[0] != '\'' && strchr (tag, '-'))
6fb8b256
VS
64 complain_at (loc, Wyacc,
65 _("POSIX Yacc forbids dashes in symbol names: %s"), tag);
4f646c37 66
95612cfa 67 res->tag = tag;
17ee7397 68 res->location = loc;
24c0aad7 69
1e9798d5 70 res->type_name = NULL;
71da68b3
VS
71 for (int i = 0; i < CODE_PROPS_SIZE; ++i)
72 code_props_none_init (&res->props[i]);
24c0aad7 73
5fbb0954 74 res->number = NUMBER_UNDEFINED;
1e9798d5 75 res->prec = 0;
a945ec39 76 res->assoc = undef_assoc;
b87f8b21 77 res->user_token_number = USER_NUMBER_UNDEFINED;
260008e5 78
1e9798d5
AD
79 res->alias = NULL;
80 res->class = unknown_sym;
3b0b682f 81 res->status = undeclared;
1e9798d5 82
3239db74 83 if (nsyms == SYMBOL_NUMBER_MAXIMUM)
6fb8b256
VS
84 complain (fatal, _("too many symbols in input grammar (limit is %d)"),
85 SYMBOL_NUMBER_MAXIMUM);
6d0ef4ec 86 nsyms++;
1e9798d5
AD
87 return res;
88}
89
6a0655d9 90char const *
71da68b3
VS
91code_props_type_string (code_props_type kind)
92{
93 switch (kind)
94 {
95 case destructor:
96 return "%destructor";
97 case printer:
98 return "%printer";
99 }
100 assert (0);
101}
102
b2a0b7ca
JD
103/*----------------------------------------.
104| Create a new semantic type, named TAG. |
105`----------------------------------------*/
106
107static semantic_type *
9641b918 108semantic_type_new (uniqstr tag, const location *loc)
b2a0b7ca
JD
109{
110 semantic_type *res = xmalloc (sizeof *res);
111
112 uniqstr_assert (tag);
113 res->tag = tag;
9641b918
VS
114 if (loc)
115 res->location = *loc;
71da68b3
VS
116 for (int i = 0; i < CODE_PROPS_SIZE; ++i)
117 code_props_none_init (&res->props[i]);
b2a0b7ca
JD
118
119 return res;
120}
121
40675e7c 122
867a3e00
AD
123/*-----------------.
124| Print a symbol. |
125`-----------------*/
126
e9690142
JD
127#define SYMBOL_ATTR_PRINT(Attr) \
128 if (s->Attr) \
ab703f2c 129 fprintf (f, " %s { %s }", #Attr, s->Attr)
867a3e00 130
71da68b3
VS
131#define SYMBOL_CODE_PRINT(Attr) \
132 if (s->props[Attr].code) \
133 fprintf (f, " %s { %s }", #Attr, s->props[Attr].code)
95021767 134
867a3e00 135void
c5289832 136symbol_print (symbol const *s, FILE *f)
867a3e00 137{
affac613
AD
138 if (s)
139 {
140 fprintf (f, "\"%s\"", s->tag);
141 SYMBOL_ATTR_PRINT (type_name);
95021767
JD
142 SYMBOL_CODE_PRINT (destructor);
143 SYMBOL_CODE_PRINT (printer);
affac613
AD
144 }
145 else
146 fprintf (f, "<NULL>");
867a3e00
AD
147}
148
149#undef SYMBOL_ATTR_PRINT
95021767 150#undef SYMBOL_CODE_PRINT
867a3e00 151
aea10ef4
AD
152
153/*----------------------------------.
154| Whether S is a valid identifier. |
155`----------------------------------*/
156
157static bool
158is_identifier (uniqstr s)
159{
160 static char const alphanum[26 + 26 + 1 + 10] =
161 "abcdefghijklmnopqrstuvwxyz"
162 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
163 "_"
164 "0123456789";
165 if (!s || ! memchr (alphanum, *s, sizeof alphanum - 10))
166 return false;
167 for (++s; *s; ++s)
168 if (! memchr (alphanum, *s, sizeof alphanum))
169 return false;
170 return true;
171}
172
173
174/*-----------------------------------------------.
175| Get the identifier associated to this symbol. |
176`-----------------------------------------------*/
177uniqstr
178symbol_id_get (symbol const *sym)
179{
dfaa4860 180 aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
aea10ef4
AD
181 if (sym->alias)
182 sym = sym->alias;
183 return is_identifier (sym->tag) ? sym->tag : 0;
184}
185
186
df09ef2e
AD
187/*------------------------------------------------------------------.
188| Complain that S's WHAT is redeclared at SECOND, and was first set |
189| at FIRST. |
190`------------------------------------------------------------------*/
191
192static void
b2a0b7ca
JD
193symbol_redeclaration (symbol *s, const char *what, location first,
194 location second)
df09ef2e 195{
6fb8b256
VS
196 complain_at (second, complaint, _("%s redeclaration for %s"), what, s->tag);
197 complain_at (first, complaint, _("previous declaration"));
df09ef2e
AD
198}
199
b2a0b7ca
JD
200static void
201semantic_type_redeclaration (semantic_type *s, const char *what, location first,
202 location second)
203{
6fb8b256
VS
204 complain_at (second, complaint, _("%s redeclaration for <%s>"), what, s->tag);
205 complain_at (first, complaint, _("previous declaration"));
b2a0b7ca
JD
206}
207
df09ef2e 208
12cf133f 209
17ee7397
PE
210/*-----------------------------------------------------------------.
211| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
212| as TYPE_NAME. |
213`-----------------------------------------------------------------*/
3ae2b51f
AD
214
215void
17ee7397 216symbol_type_set (symbol *sym, uniqstr type_name, location loc)
3ae2b51f 217{
e9955c83
AD
218 if (type_name)
219 {
17ee7397 220 if (sym->type_name)
e9690142 221 symbol_redeclaration (sym, "%type", sym->type_location, loc);
17ee7397
PE
222 uniqstr_assert (type_name);
223 sym->type_name = type_name;
df09ef2e 224 sym->type_location = loc;
e9955c83 225 }
3ae2b51f
AD
226}
227
71da68b3
VS
228/*--------------------------------------------------------.
229| Set the DESTRUCTOR or PRINTER associated with the SYM. |
230`--------------------------------------------------------*/
366eea36
AD
231
232void
71da68b3
VS
233symbol_code_props_set (symbol *sym, code_props_type kind,
234 code_props const *code)
366eea36 235{
71da68b3
VS
236 if (sym->props[kind].code)
237 symbol_redeclaration (sym, code_props_type_string (kind),
238 sym->props[kind].location,
239 code->location);
240 sym->props[kind] = *code;
366eea36
AD
241}
242
71da68b3
VS
243/*-----------------------------------------------------.
244| Set the DESTRUCTOR or PRINTER associated with TYPE. |
245`-----------------------------------------------------*/
b2a0b7ca
JD
246
247void
71da68b3
VS
248semantic_type_code_props_set (semantic_type *type,
249 code_props_type kind,
250 code_props const *code)
b2a0b7ca 251{
71da68b3
VS
252 if (type->props[kind].code)
253 semantic_type_redeclaration (type, code_props_type_string (kind),
254 type->props[kind].location,
255 code->location);
256 type->props[kind] = *code;
b2a0b7ca
JD
257}
258
71da68b3
VS
259/*---------------------------------------------------.
260| Get the computed %destructor or %printer for SYM. |
261`---------------------------------------------------*/
ec5479ce 262
70946cff
AD
263code_props *
264symbol_code_props_get (symbol *sym, code_props_type kind)
ec5479ce 265{
71da68b3
VS
266 /* Per-symbol code props. */
267 if (sym->props[kind].code)
268 return &sym->props[kind];
9350499c 269
71da68b3 270 /* Per-type code props. */
b2a0b7ca
JD
271 if (sym->type_name)
272 {
70946cff 273 code_props *code =
9641b918 274 &semantic_type_get (sym->type_name, NULL)->props[kind];
71da68b3
VS
275 if (code->code)
276 return code;
b2a0b7ca
JD
277 }
278
71da68b3 279 /* Apply default code props's only to user-defined symbols. */
9534d2be
AD
280 if (sym->tag[0] != '$' && sym != errtoken)
281 {
282 code_props *code =
283 &semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind];
284 if (code->code)
285 return code;
286 }
287 return &code_props_none;
ec5479ce
JD
288}
289
17ee7397
PE
290/*-----------------------------------------------------------------.
291| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
292| with UNDEF_ASSOC as ASSOC. |
293`-----------------------------------------------------------------*/
3ae2b51f
AD
294
295void
17ee7397 296symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
3ae2b51f 297{
17ee7397 298 if (a != undef_assoc)
e9955c83 299 {
17ee7397 300 if (sym->prec != 0)
e9690142 301 symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
b2a0b7ca 302 loc);
17ee7397
PE
303 sym->prec = prec;
304 sym->assoc = a;
df09ef2e 305 sym->prec_location = loc;
e9955c83
AD
306 }
307
308 /* Only terminals have a precedence. */
073f9288 309 symbol_class_set (sym, token_sym, loc, false);
3ae2b51f
AD
310}
311
312
17ee7397
PE
313/*------------------------------------.
314| Set the CLASS associated with SYM. |
315`------------------------------------*/
44536b35
AD
316
317void
073f9288 318symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
44536b35 319{
3b0b682f 320 bool warned = false;
17ee7397 321 if (sym->class != unknown_sym && sym->class != class)
073f9288 322 {
6fb8b256 323 complain_at (loc, complaint, _("symbol %s redefined"), sym->tag);
3b0b682f
AD
324 // Don't report both "redefined" and "redeclared".
325 warned = true;
073f9288 326 }
44536b35 327
17ee7397
PE
328 if (class == nterm_sym && sym->class != nterm_sym)
329 sym->number = nvars++;
6d0ef4ec 330 else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
17ee7397 331 sym->number = ntokens++;
44536b35 332
17ee7397 333 sym->class = class;
073f9288
PE
334
335 if (declaring)
336 {
3b0b682f 337 if (sym->status == declared && !warned)
6fb8b256 338 complain_at (loc, Wother, _("symbol %s redeclared"), sym->tag);
b921d92f 339 sym->status = declared;
073f9288 340 }
44536b35
AD
341}
342
343
17ee7397
PE
344/*------------------------------------------------.
345| Set the USER_TOKEN_NUMBER associated with SYM. |
346`------------------------------------------------*/
44536b35
AD
347
348void
17ee7397 349symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
44536b35 350{
1f6b3679
JD
351 int *user_token_numberp;
352
dfaa4860 353 if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
1f6b3679
JD
354 user_token_numberp = &sym->user_token_number;
355 else
356 user_token_numberp = &sym->alias->user_token_number;
357 if (*user_token_numberp != USER_NUMBER_UNDEFINED
358 && *user_token_numberp != user_token_number)
6fb8b256
VS
359 complain_at (loc, complaint, _("redefining user token number of %s"),
360 sym->tag);
44536b35 361
1f6b3679 362 *user_token_numberp = user_token_number;
88bce5a2 363 /* User defined $end token? */
44536b35
AD
364 if (user_token_number == 0)
365 {
17ee7397 366 endtoken = sym;
44536b35 367 /* It is always mapped to 0, so it was already counted in
e9690142 368 NTOKENS. */
1f36f544
JD
369 if (endtoken->number != NUMBER_UNDEFINED)
370 --ntokens;
371 endtoken->number = 0;
44536b35
AD
372 }
373}
374
375
17ee7397
PE
376/*----------------------------------------------------------.
377| If SYM is not defined, report an error, and consider it a |
378| nonterminal. |
379`----------------------------------------------------------*/
2f1afb73 380
0fb1efaf 381static inline bool
17ee7397 382symbol_check_defined (symbol *sym)
2f1afb73 383{
17ee7397 384 if (sym->class == unknown_sym)
2f1afb73 385 {
31557b9e
AD
386 assert (sym->status != declared);
387 complain_at (sym->location,
388 sym->status == needed ? complaint : Wother,
389 _("symbol %s is used, but is not defined as a token"
390 " and has no rules"),
391 sym->tag);
17ee7397
PE
392 sym->class = nterm_sym;
393 sym->number = nvars++;
2f1afb73
AD
394 }
395
ea9a35c6 396 for (int i = 0; i < 2; ++i)
70946cff 397 symbol_code_props_get (sym, i)->is_used = true;
ea9a35c6 398
9641b918
VS
399 /* Set the semantic type status associated to the current symbol to
400 'declared' so that we could check semantic types unnecessary uses. */
401 if (sym->type_name)
402 {
403 semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
404 if (sem_type)
405 sem_type->status = declared;
406 }
407
408 return true;
409}
410
411static inline bool
412semantic_type_check_defined (semantic_type *sem_type)
413{
9534d2be
AD
414 // <*> and <> do not have to be "declared".
415 if (sem_type->status == declared
416 || !*sem_type->tag
417 || STREQ(sem_type->tag, "*"))
ea9a35c6
VS
418 {
419 for (int i = 0; i < 2; ++i)
420 if (sem_type->props[i].kind != CODE_PROPS_NONE
421 && ! sem_type->props[i].is_used)
6fb8b256 422 complain_at (sem_type->location, Wother,
0560fa24
AD
423 _("useless %s for type <%s>"),
424 code_props_type_string (i), sem_type->tag);
ea9a35c6
VS
425 }
426 else
6fb8b256
VS
427 complain_at (sem_type->location, Wother,
428 _("type <%s> is used, but is not associated to any symbol"),
429 sem_type->tag);
9641b918 430
a3714bce 431 return true;
2f1afb73
AD
432}
433
0fb1efaf
PE
434static bool
435symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
436{
437 return symbol_check_defined (sym);
438}
439
9641b918
VS
440static bool
441semantic_type_check_defined_processor (void *sem_type,
442 void *null ATTRIBUTE_UNUSED)
443{
444 return semantic_type_check_defined (sem_type);
445}
446
2f1afb73 447
2f1afb73 448void
dfaa4860 449symbol_make_alias (symbol *sym, symbol *str, location loc)
2f1afb73 450{
dfaa4860 451 if (str->alias)
6fb8b256
VS
452 complain_at (loc, Wother,
453 _("symbol %s used more than once as a literal string"), str->tag);
17ee7397 454 else if (sym->alias)
6fb8b256
VS
455 complain_at (loc, Wother,
456 _("symbol %s given more than one literal string"), sym->tag);
2f1afb73
AD
457 else
458 {
dfaa4860
JD
459 str->class = token_sym;
460 str->user_token_number = sym->user_token_number;
461 sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
462 str->alias = sym;
463 sym->alias = str;
464 str->number = sym->number;
465 symbol_type_set (str, sym->type_name, loc);
2f1afb73
AD
466 }
467}
468
469
470/*---------------------------------------------------------.
471| Check that THIS, and its alias, have same precedence and |
472| associativity. |
473`---------------------------------------------------------*/
474
df09ef2e 475static inline void
0fb1efaf 476symbol_check_alias_consistency (symbol *this)
2f1afb73 477{
dfaa4860 478 symbol *sym = this;
b143f404 479 symbol *str = this->alias;
df09ef2e 480
dfaa4860
JD
481 /* Check only the symbol in the symbol-string pair. */
482 if (!(this->alias
483 && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
df09ef2e
AD
484 return;
485
dfaa4860 486 if (str->type_name != sym->type_name)
2f1afb73 487 {
dfaa4860 488 if (str->type_name)
e9690142 489 symbol_type_set (sym, str->type_name, str->type_location);
df09ef2e 490 else
e9690142 491 symbol_type_set (str, sym->type_name, sym->type_location);
df09ef2e 492 }
2f1afb73 493
df09ef2e 494
71da68b3
VS
495 for (int i = 0; i < CODE_PROPS_SIZE; ++i)
496 if (str->props[i].code)
497 symbol_code_props_set (sym, i, &str->props[i]);
498 else if (sym->props[i].code)
499 symbol_code_props_set (str, i, &sym->props[i]);
df09ef2e 500
dfaa4860 501 if (sym->prec || str->prec)
df09ef2e 502 {
dfaa4860 503 if (str->prec)
e9690142
JD
504 symbol_precedence_set (sym, str->prec, str->assoc,
505 str->prec_location);
df09ef2e 506 else
e9690142
JD
507 symbol_precedence_set (str, sym->prec, sym->assoc,
508 sym->prec_location);
2f1afb73 509 }
2f1afb73
AD
510}
511
0fb1efaf
PE
512static bool
513symbol_check_alias_consistency_processor (void *this,
e9690142 514 void *null ATTRIBUTE_UNUSED)
0fb1efaf 515{
df09ef2e
AD
516 symbol_check_alias_consistency (this);
517 return true;
0fb1efaf
PE
518}
519
2f1afb73
AD
520
521/*-------------------------------------------------------------------.
522| Assign a symbol number, and write the definition of the token name |
523| into FDEFINES. Put in SYMBOLS. |
524`-------------------------------------------------------------------*/
525
0fb1efaf 526static inline bool
17ee7397 527symbol_pack (symbol *this)
2f1afb73 528{
f74d6d25 529 aver (this->number != NUMBER_UNDEFINED);
2f1afb73 530 if (this->class == nterm_sym)
f74d6d25
JD
531 this->number += ntokens;
532 else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
533 return true;
2f1afb73
AD
534
535 symbols[this->number] = this;
a3714bce 536 return true;
2f1afb73
AD
537}
538
0fb1efaf
PE
539static bool
540symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
541{
542 return symbol_pack (this);
543}
544
2f1afb73 545
12cf133f
AD
546static void
547user_token_number_redeclaration (int num, symbol *first, symbol *second)
548{
549 /* User token numbers are not assigned during the parsing, but in a
83b60c97 550 second step, via a traversal of the symbol table sorted on tag.
2f1afb73 551
83b60c97
JD
552 However, error messages make more sense if we keep the first
553 declaration first. */
12cf133f
AD
554 if (location_cmp (first->location, second->location) > 0)
555 {
556 symbol* tmp = first;
557 first = second;
558 second = tmp;
559 }
6fb8b256 560 complain_at (second->location, complaint,
12cf133f
AD
561 _("user token number %d redeclaration for %s"),
562 num, second->tag);
6fb8b256 563 complain_at (first->location, complaint, _("previous declaration for %s"),
12cf133f
AD
564 first->tag);
565}
2f1afb73
AD
566
567/*--------------------------------------------------.
568| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
569`--------------------------------------------------*/
570
0fb1efaf 571static inline bool
17ee7397 572symbol_translation (symbol *this)
2f1afb73
AD
573{
574 /* Non-terminal? */
575 if (this->class == token_sym
dfaa4860 576 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
2f1afb73
AD
577 {
578 /* A token which translation has already been set? */
579 if (token_translations[this->user_token_number] != undeftoken->number)
e9690142 580 user_token_number_redeclaration
12cf133f
AD
581 (this->user_token_number,
582 symbols[token_translations[this->user_token_number]],
583 this);
9553083c 584
2f1afb73
AD
585 token_translations[this->user_token_number] = this->number;
586 }
9553083c 587
a3714bce 588 return true;
2f1afb73
AD
589}
590
0fb1efaf
PE
591static bool
592symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
593{
594 return symbol_translation (this);
595}
596
72a23c97 597
b2a0b7ca
JD
598/*---------------------------------------.
599| Symbol and semantic type hash tables. |
600`---------------------------------------*/
40675e7c 601
b2a0b7ca 602/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
603#define HT_INITIAL_CAPACITY 257
604
db8837cb 605static struct hash_table *symbol_table = NULL;
b2a0b7ca 606static struct hash_table *semantic_type_table = NULL;
72a23c97 607
0fb1efaf 608static inline bool
17ee7397 609hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 610{
95612cfa 611 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 612 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
613}
614
b2a0b7ca
JD
615static inline bool
616hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
617{
618 /* Since names are unique, we can compare the pointers themselves. */
619 return UNIQSTR_EQ (m1->tag, m2->tag);
620}
621
0fb1efaf
PE
622static bool
623hash_symbol_comparator (void const *m1, void const *m2)
624{
625 return hash_compare_symbol (m1, m2);
626}
627
b2a0b7ca
JD
628static bool
629hash_semantic_type_comparator (void const *m1, void const *m2)
630{
631 return hash_compare_semantic_type (m1, m2);
632}
633
233a88ad
PE
634static inline size_t
635hash_symbol (const symbol *m, size_t tablesize)
72a23c97 636{
95612cfa 637 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
638 return ((uintptr_t) m->tag) % tablesize;
639}
640
b2a0b7ca
JD
641static inline size_t
642hash_semantic_type (const semantic_type *m, size_t tablesize)
643{
644 /* Since names are unique, we can hash the pointer itself. */
645 return ((uintptr_t) m->tag) % tablesize;
646}
647
233a88ad
PE
648static size_t
649hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
650{
651 return hash_symbol (m, tablesize);
72a23c97
AD
652}
653
b2a0b7ca
JD
654static size_t
655hash_semantic_type_hasher (void const *m, size_t tablesize)
656{
657 return hash_semantic_type (m, tablesize);
658}
72a23c97
AD
659
660/*-------------------------------.
2f1afb73 661| Create the symbol hash table. |
72a23c97
AD
662`-------------------------------*/
663
664void
db8837cb 665symbols_new (void)
72a23c97 666{
db8837cb 667 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
668 NULL,
669 hash_symbol_hasher,
670 hash_symbol_comparator,
671 free);
b2a0b7ca 672 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
673 NULL,
674 hash_semantic_type_hasher,
675 hash_semantic_type_comparator,
676 free);
40675e7c
DM
677}
678
679
1e9798d5
AD
680/*----------------------------------------------------------------.
681| Find the symbol named KEY, and return it. If it does not exist |
682| yet, create it. |
683`----------------------------------------------------------------*/
684
17ee7397 685symbol *
203b9274 686symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 687{
17ee7397
PE
688 symbol probe;
689 symbol *entry;
40675e7c 690
0fb1efaf 691 probe.tag = key;
db8837cb 692 entry = hash_lookup (symbol_table, &probe);
40675e7c 693
72a23c97 694 if (!entry)
40675e7c 695 {
72a23c97 696 /* First insertion in the hash. */
83b60c97 697 aver (!symbols_sorted);
17ee7397 698 entry = symbol_new (key, loc);
92d7a23a
AD
699 if (!hash_insert (symbol_table, entry))
700 xalloc_die ();
40675e7c 701 }
72a23c97
AD
702 return entry;
703}
40675e7c 704
40675e7c 705
b2a0b7ca
JD
706/*-----------------------------------------------------------------------.
707| Find the semantic type named KEY, and return it. If it does not exist |
708| yet, create it. |
709`-----------------------------------------------------------------------*/
710
711semantic_type *
9641b918 712semantic_type_from_uniqstr (const uniqstr key, const location *loc)
b2a0b7ca
JD
713{
714 semantic_type probe;
715 semantic_type *entry;
716
717 probe.tag = key;
718 entry = hash_lookup (semantic_type_table, &probe);
719
720 if (!entry)
721 {
722 /* First insertion in the hash. */
9641b918 723 entry = semantic_type_new (key, loc);
92d7a23a
AD
724 if (!hash_insert (semantic_type_table, entry))
725 xalloc_die ();
b2a0b7ca
JD
726 }
727 return entry;
728}
729
730
203b9274
AD
731/*----------------------------------------------------------------.
732| Find the symbol named KEY, and return it. If it does not exist |
733| yet, create it. |
734`----------------------------------------------------------------*/
735
736symbol *
737symbol_get (const char *key, location loc)
738{
739 return symbol_from_uniqstr (uniqstr_new (key), loc);
740}
741
742
b2a0b7ca
JD
743/*-----------------------------------------------------------------------.
744| Find the semantic type named KEY, and return it. If it does not exist |
745| yet, create it. |
746`-----------------------------------------------------------------------*/
747
748semantic_type *
9641b918 749semantic_type_get (const char *key, const location *loc)
b2a0b7ca 750{
9641b918 751 return semantic_type_from_uniqstr (uniqstr_new (key), loc);
b2a0b7ca
JD
752}
753
754
39f41916
AD
755/*------------------------------------------------------------------.
756| Generate a dummy nonterminal, whose name cannot conflict with the |
757| user's names. |
758`------------------------------------------------------------------*/
759
17ee7397
PE
760symbol *
761dummy_symbol_get (location loc)
39f41916
AD
762{
763 /* Incremented for each generated symbol. */
764 static int dummy_count = 0;
765 static char buf[256];
766
17ee7397 767 symbol *sym;
39f41916 768
f91b1629 769 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 770 sym = symbol_get (buf, loc);
39f41916
AD
771 sym->class = nterm_sym;
772 sym->number = nvars++;
773 return sym;
774}
775
4d7370cb
JD
776bool
777symbol_is_dummy (const symbol *sym)
778{
f91b1629 779 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 780}
39f41916 781
72a23c97 782/*-------------------.
db8837cb 783| Free the symbols. |
72a23c97
AD
784`-------------------*/
785
786void
db8837cb 787symbols_free (void)
72a23c97 788{
db8837cb 789 hash_free (symbol_table);
b2a0b7ca 790 hash_free (semantic_type_table);
536545f3 791 free (symbols);
83b60c97 792 free (symbols_sorted);
40675e7c
DM
793}
794
795
72a23c97 796/*---------------------------------------------------------------.
db8837cb 797| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
798| terminals. |
799`---------------------------------------------------------------*/
800
83b60c97
JD
801static int
802symbols_cmp (symbol const *a, symbol const *b)
803{
804 return strcmp (a->tag, b->tag);
805}
806
807static int
808symbols_cmp_qsort (void const *a, void const *b)
809{
810 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
811}
812
0fb1efaf 813static void
dfe292c6
VS
814symbols_do (Hash_processor processor, void *processor_data,
815 struct hash_table *table, symbol **sorted)
40675e7c 816{
dfe292c6
VS
817 size_t count = hash_get_n_entries (table);
818 if (!sorted)
83b60c97 819 {
dfe292c6
VS
820 sorted = xnmalloc (count, sizeof *sorted);
821 hash_get_entries (table, (void**)sorted, count);
822 qsort (sorted, count, sizeof *sorted, symbols_cmp_qsort);
83b60c97
JD
823 }
824 {
825 size_t i;
826 for (i = 0; i < count; ++i)
dfe292c6 827 processor (sorted[i], processor_data);
83b60c97 828 }
40675e7c 829}
2f1afb73 830
2f1afb73
AD
831/*--------------------------------------------------------------.
832| Check that all the symbols are defined. Report any undefined |
833| symbols and consider them nonterminals. |
834`--------------------------------------------------------------*/
835
836void
837symbols_check_defined (void)
838{
dfe292c6
VS
839 symbols_do (symbol_check_defined_processor, NULL,
840 symbol_table, symbols_sorted);
9641b918
VS
841 symbols_do (semantic_type_check_defined_processor, NULL,
842 semantic_type_table, semantic_types_sorted);
2f1afb73
AD
843}
844
845/*------------------------------------------------------------------.
846| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
847| number. |
848`------------------------------------------------------------------*/
849
850static void
851symbols_token_translations_init (void)
852{
a3714bce 853 bool num_256_available_p = true;
2f1afb73
AD
854 int i;
855
856 /* Find the highest user token number, and whether 256, the POSIX
857 preferred user token number for the error token, is used. */
858 max_user_token_number = 0;
859 for (i = 0; i < ntokens; ++i)
860 {
17ee7397 861 symbol *this = symbols[i];
2f1afb73 862 if (this->user_token_number != USER_NUMBER_UNDEFINED)
e9690142
JD
863 {
864 if (this->user_token_number > max_user_token_number)
865 max_user_token_number = this->user_token_number;
866 if (this->user_token_number == 256)
867 num_256_available_p = false;
868 }
2f1afb73
AD
869 }
870
871 /* If 256 is not used, assign it to error, to follow POSIX. */
872 if (num_256_available_p
873 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
874 errtoken->user_token_number = 256;
875
876 /* Set the missing user numbers. */
877 if (max_user_token_number < 256)
878 max_user_token_number = 256;
879
880 for (i = 0; i < ntokens; ++i)
881 {
17ee7397 882 symbol *this = symbols[i];
2f1afb73 883 if (this->user_token_number == USER_NUMBER_UNDEFINED)
e9690142 884 this->user_token_number = ++max_user_token_number;
2f1afb73 885 if (this->user_token_number > max_user_token_number)
e9690142 886 max_user_token_number = this->user_token_number;
2f1afb73
AD
887 }
888
da2a7671 889 token_translations = xnmalloc (max_user_token_number + 1,
e9690142 890 sizeof *token_translations);
2f1afb73 891
b3a28fd4
AD
892 /* Initialize all entries for literal tokens to the internal token
893 number for $undefined, which represents all invalid inputs. */
2f1afb73
AD
894 for (i = 0; i < max_user_token_number + 1; i++)
895 token_translations[i] = undeftoken->number;
dfe292c6
VS
896 symbols_do (symbol_translation_processor, NULL,
897 symbol_table, symbols_sorted);
2f1afb73
AD
898}
899
900
901/*----------------------------------------------------------------.
902| Assign symbol numbers, and write definition of token names into |
903| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
904`----------------------------------------------------------------*/
905
906void
907symbols_pack (void)
908{
dfe292c6
VS
909 symbols_do (symbol_check_alias_consistency_processor, NULL,
910 symbol_table, symbols_sorted);
6d0ef4ec
JD
911
912 symbols = xcalloc (nsyms, sizeof *symbols);
dfe292c6 913 symbols_do (symbol_pack_processor, NULL, symbol_table, symbols_sorted);
2f1afb73 914
6d0ef4ec
JD
915 /* Aliases leave empty slots in symbols, so remove them. */
916 {
917 int writei;
918 int readi;
919 int nsyms_old = nsyms;
920 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
921 {
922 if (symbols[readi] == NULL)
923 {
924 nsyms -= 1;
925 ntokens -= 1;
926 }
927 else
928 {
929 symbols[writei] = symbols[readi];
930 symbols[writei]->number = writei;
931 if (symbols[writei]->alias)
932 symbols[writei]->alias->number = writei;
933 writei += 1;
934 }
935 }
936 }
937 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
938
2f1afb73
AD
939 symbols_token_translations_init ();
940
941 if (startsymbol->class == unknown_sym)
6fb8b256
VS
942 complain_at (startsymbol_location, fatal,
943 _("the start symbol %s is undefined"),
944 startsymbol->tag);
2f1afb73 945 else if (startsymbol->class == token_sym)
6fb8b256
VS
946 complain_at (startsymbol_location, fatal,
947 _("the start symbol %s is a token"),
948 startsymbol->tag);
2f1afb73 949}