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