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