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