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