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