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