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