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