]> git.saurik.com Git - bison.git/blame - src/symtab.c
xml: match DOT output and xml2dot.xsl processing
[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);
b506d9bf 537 i += SUB_INDENT;
cbaea010
TR
538 complain_at_indent (first->location, &i,
539 _("previous declaration for %s"),
540 first->tag);
95d176ff 541}
2f1afb73
AD
542
543/*--------------------------------------------------.
544| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
545`--------------------------------------------------*/
546
0fb1efaf 547static inline bool
17ee7397 548symbol_translation (symbol *this)
2f1afb73
AD
549{
550 /* Non-terminal? */
551 if (this->class == token_sym
07c0db18 552 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
2f1afb73
AD
553 {
554 /* A token which translation has already been set? */
555 if (token_translations[this->user_token_number] != undeftoken->number)
95d176ff
AD
556 user_token_number_redeclaration
557 (this->user_token_number,
558 symbols[token_translations[this->user_token_number]],
559 this);
2f1afb73
AD
560
561 token_translations[this->user_token_number] = this->number;
562 }
563
a3714bce 564 return true;
2f1afb73
AD
565}
566
0fb1efaf
PE
567static bool
568symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
569{
570 return symbol_translation (this);
571}
572
72a23c97 573
b2a0b7ca
JD
574/*---------------------------------------.
575| Symbol and semantic type hash tables. |
576`---------------------------------------*/
40675e7c 577
b2a0b7ca 578/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
579#define HT_INITIAL_CAPACITY 257
580
db8837cb 581static struct hash_table *symbol_table = NULL;
b2a0b7ca 582static struct hash_table *semantic_type_table = NULL;
72a23c97 583
0fb1efaf 584static inline bool
17ee7397 585hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 586{
95612cfa 587 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 588 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
589}
590
b2a0b7ca
JD
591static inline bool
592hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
593{
594 /* Since names are unique, we can compare the pointers themselves. */
595 return UNIQSTR_EQ (m1->tag, m2->tag);
596}
597
0fb1efaf
PE
598static bool
599hash_symbol_comparator (void const *m1, void const *m2)
600{
601 return hash_compare_symbol (m1, m2);
602}
603
b2a0b7ca
JD
604static bool
605hash_semantic_type_comparator (void const *m1, void const *m2)
606{
607 return hash_compare_semantic_type (m1, m2);
608}
609
233a88ad
PE
610static inline size_t
611hash_symbol (const symbol *m, size_t tablesize)
72a23c97 612{
95612cfa 613 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
614 return ((uintptr_t) m->tag) % tablesize;
615}
616
b2a0b7ca
JD
617static inline size_t
618hash_semantic_type (const semantic_type *m, size_t tablesize)
619{
620 /* Since names are unique, we can hash the pointer itself. */
621 return ((uintptr_t) m->tag) % tablesize;
622}
623
233a88ad
PE
624static size_t
625hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
626{
627 return hash_symbol (m, tablesize);
72a23c97
AD
628}
629
b2a0b7ca
JD
630static size_t
631hash_semantic_type_hasher (void const *m, size_t tablesize)
632{
633 return hash_semantic_type (m, tablesize);
634}
72a23c97
AD
635
636/*-------------------------------.
2f1afb73 637| Create the symbol hash table. |
72a23c97
AD
638`-------------------------------*/
639
640void
db8837cb 641symbols_new (void)
72a23c97 642{
db8837cb 643 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
72a23c97 644 NULL,
0fb1efaf
PE
645 hash_symbol_hasher,
646 hash_symbol_comparator,
647 free);
b2a0b7ca
JD
648 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
649 NULL,
650 hash_semantic_type_hasher,
651 hash_semantic_type_comparator,
652 free);
40675e7c
DM
653}
654
655
1e9798d5
AD
656/*----------------------------------------------------------------.
657| Find the symbol named KEY, and return it. If it does not exist |
658| yet, create it. |
659`----------------------------------------------------------------*/
660
17ee7397 661symbol *
203b9274 662symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 663{
17ee7397
PE
664 symbol probe;
665 symbol *entry;
40675e7c 666
0fb1efaf 667 probe.tag = key;
db8837cb 668 entry = hash_lookup (symbol_table, &probe);
40675e7c 669
72a23c97 670 if (!entry)
40675e7c 671 {
72a23c97 672 /* First insertion in the hash. */
24985964 673 aver (!symbols_sorted);
17ee7397 674 entry = symbol_new (key, loc);
ed15d907
AD
675 if (!hash_insert (symbol_table, entry))
676 xalloc_die ();
40675e7c 677 }
72a23c97
AD
678 return entry;
679}
40675e7c 680
40675e7c 681
b2a0b7ca
JD
682/*-----------------------------------------------------------------------.
683| Find the semantic type named KEY, and return it. If it does not exist |
684| yet, create it. |
685`-----------------------------------------------------------------------*/
686
687semantic_type *
688semantic_type_from_uniqstr (const uniqstr key)
689{
690 semantic_type probe;
691 semantic_type *entry;
692
693 probe.tag = key;
694 entry = hash_lookup (semantic_type_table, &probe);
695
696 if (!entry)
697 {
698 /* First insertion in the hash. */
699 entry = semantic_type_new (key);
ed15d907
AD
700 if (!hash_insert (semantic_type_table, entry))
701 xalloc_die ();
b2a0b7ca
JD
702 }
703 return entry;
704}
705
706
203b9274
AD
707/*----------------------------------------------------------------.
708| Find the symbol named KEY, and return it. If it does not exist |
709| yet, create it. |
710`----------------------------------------------------------------*/
711
712symbol *
713symbol_get (const char *key, location loc)
714{
715 return symbol_from_uniqstr (uniqstr_new (key), loc);
716}
717
718
b2a0b7ca
JD
719/*-----------------------------------------------------------------------.
720| Find the semantic type named KEY, and return it. If it does not exist |
721| yet, create it. |
722`-----------------------------------------------------------------------*/
723
724semantic_type *
725semantic_type_get (const char *key)
726{
727 return semantic_type_from_uniqstr (uniqstr_new (key));
728}
729
730
39f41916
AD
731/*------------------------------------------------------------------.
732| Generate a dummy nonterminal, whose name cannot conflict with the |
733| user's names. |
734`------------------------------------------------------------------*/
735
17ee7397
PE
736symbol *
737dummy_symbol_get (location loc)
39f41916
AD
738{
739 /* Incremented for each generated symbol. */
740 static int dummy_count = 0;
741 static char buf[256];
742
17ee7397 743 symbol *sym;
39f41916 744
f91b1629 745 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 746 sym = symbol_get (buf, loc);
39f41916
AD
747 sym->class = nterm_sym;
748 sym->number = nvars++;
749 return sym;
750}
751
4d7370cb
JD
752bool
753symbol_is_dummy (const symbol *sym)
754{
f91b1629 755 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 756}
39f41916 757
72a23c97 758/*-------------------.
db8837cb 759| Free the symbols. |
72a23c97
AD
760`-------------------*/
761
762void
db8837cb 763symbols_free (void)
72a23c97 764{
db8837cb 765 hash_free (symbol_table);
b2a0b7ca 766 hash_free (semantic_type_table);
536545f3 767 free (symbols);
24985964 768 free (symbols_sorted);
40675e7c
DM
769}
770
771
72a23c97 772/*---------------------------------------------------------------.
db8837cb 773| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
774| terminals. |
775`---------------------------------------------------------------*/
776
24985964
JD
777static int
778symbols_cmp (symbol const *a, symbol const *b)
779{
780 return strcmp (a->tag, b->tag);
781}
782
783static int
784symbols_cmp_qsort (void const *a, void const *b)
785{
786 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
787}
788
0fb1efaf
PE
789static void
790symbols_do (Hash_processor processor, void *processor_data)
40675e7c 791{
24985964
JD
792 size_t count = hash_get_n_entries (symbol_table);
793 if (!symbols_sorted)
794 {
795 symbols_sorted = xnmalloc (count, sizeof *symbols_sorted);
796 hash_get_entries (symbol_table, (void**)symbols_sorted, count);
797 qsort (symbols_sorted, count, sizeof *symbols_sorted,
798 symbols_cmp_qsort);
799 }
800 {
801 size_t i;
802 for (i = 0; i < count; ++i)
803 processor (symbols_sorted[i], processor_data);
804 }
40675e7c 805}
2f1afb73 806
2f1afb73
AD
807/*--------------------------------------------------------------.
808| Check that all the symbols are defined. Report any undefined |
809| symbols and consider them nonterminals. |
810`--------------------------------------------------------------*/
811
812void
813symbols_check_defined (void)
814{
0fb1efaf 815 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
816}
817
818/*------------------------------------------------------------------.
819| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
820| number. |
821`------------------------------------------------------------------*/
822
823static void
824symbols_token_translations_init (void)
825{
a3714bce 826 bool num_256_available_p = true;
2f1afb73
AD
827 int i;
828
829 /* Find the highest user token number, and whether 256, the POSIX
830 preferred user token number for the error token, is used. */
831 max_user_token_number = 0;
832 for (i = 0; i < ntokens; ++i)
833 {
17ee7397 834 symbol *this = symbols[i];
2f1afb73
AD
835 if (this->user_token_number != USER_NUMBER_UNDEFINED)
836 {
837 if (this->user_token_number > max_user_token_number)
838 max_user_token_number = this->user_token_number;
839 if (this->user_token_number == 256)
a3714bce 840 num_256_available_p = false;
2f1afb73
AD
841 }
842 }
843
844 /* If 256 is not used, assign it to error, to follow POSIX. */
845 if (num_256_available_p
846 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
847 errtoken->user_token_number = 256;
848
849 /* Set the missing user numbers. */
850 if (max_user_token_number < 256)
851 max_user_token_number = 256;
852
853 for (i = 0; i < ntokens; ++i)
854 {
17ee7397 855 symbol *this = symbols[i];
2f1afb73
AD
856 if (this->user_token_number == USER_NUMBER_UNDEFINED)
857 this->user_token_number = ++max_user_token_number;
858 if (this->user_token_number > max_user_token_number)
859 max_user_token_number = this->user_token_number;
860 }
861
da2a7671
PE
862 token_translations = xnmalloc (max_user_token_number + 1,
863 sizeof *token_translations);
2f1afb73
AD
864
865 /* Initialize all entries for literal tokens to 2, the internal
88bce5a2
AD
866 token number for $undefined, which represents all invalid inputs.
867 */
2f1afb73
AD
868 for (i = 0; i < max_user_token_number + 1; i++)
869 token_translations[i] = undeftoken->number;
0fb1efaf 870 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
871}
872
873
874/*----------------------------------------------------------------.
875| Assign symbol numbers, and write definition of token names into |
876| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
877`----------------------------------------------------------------*/
878
879void
880symbols_pack (void)
881{
0fb1efaf 882 symbols_do (symbol_check_alias_consistency_processor, NULL);
6d0ef4ec
JD
883
884 symbols = xcalloc (nsyms, sizeof *symbols);
0fb1efaf 885 symbols_do (symbol_pack_processor, NULL);
2f1afb73 886
6d0ef4ec
JD
887 /* Aliases leave empty slots in symbols, so remove them. */
888 {
889 int writei;
890 int readi;
891 int nsyms_old = nsyms;
892 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
893 {
894 if (symbols[readi] == NULL)
895 {
896 nsyms -= 1;
897 ntokens -= 1;
898 }
899 else
900 {
901 symbols[writei] = symbols[readi];
902 symbols[writei]->number = writei;
903 if (symbols[writei]->alias)
904 symbols[writei]->alias->number = writei;
905 writei += 1;
906 }
907 }
908 }
909 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
910
2f1afb73
AD
911 symbols_token_translations_init ();
912
913 if (startsymbol->class == unknown_sym)
ee000ba4 914 fatal_at (startsymbol_location,
dafdc66f 915 _("the start symbol %s is undefined"),
97650f4e 916 startsymbol->tag);
2f1afb73 917 else if (startsymbol->class == token_sym)
ee000ba4 918 fatal_at (startsymbol_location,
dafdc66f 919 _("the start symbol %s is a token"),
97650f4e 920 startsymbol->tag);
2f1afb73 921}
ec5479ce
JD
922
923
12e35840
JD
924/*--------------------------------------------------.
925| Set default tagged/tagless %destructor/%printer. |
926`--------------------------------------------------*/
927
928void
95021767 929default_tagged_destructor_set (code_props const *destructor)
12e35840 930{
95021767 931 if (default_tagged_destructor.code)
12e35840 932 {
cbaea010
TR
933 unsigned i = 0;
934 complain_at_indent (destructor->location, &i,
935 _("redeclaration for default tagged %%destructor"));
936 i += SUB_INDENT;
937 complain_at_indent (default_tagged_destructor.location, &i,
938 _("previous declaration"));
12e35840 939 }
95021767 940 default_tagged_destructor = *destructor;
12e35840
JD
941}
942
943void
95021767 944default_tagless_destructor_set (code_props const *destructor)
12e35840 945{
95021767 946 if (default_tagless_destructor.code)
12e35840 947 {
cbaea010
TR
948 unsigned i = 0;
949 complain_at_indent (destructor->location, &i,
950 _("redeclaration for default tagless %%destructor"));
951 i += SUB_INDENT;
952 complain_at_indent (default_tagless_destructor.location, &i,
953 _("previous declaration"));
12e35840 954 }
95021767 955 default_tagless_destructor = *destructor;
12e35840 956}
ec5479ce
JD
957
958void
95021767 959default_tagged_printer_set (code_props const *printer)
ec5479ce 960{
95021767 961 if (default_tagged_printer.code)
ec5479ce 962 {
cbaea010
TR
963 unsigned i = 0;
964 complain_at_indent (printer->location, &i,
965 _("redeclaration for default tagged %%printer"));
966 i += SUB_INDENT;
967 complain_at_indent (default_tagged_printer.location, &i,
968 _("previous declaration"));
ec5479ce 969 }
95021767 970 default_tagged_printer = *printer;
ec5479ce
JD
971}
972
973void
95021767 974default_tagless_printer_set (code_props const *printer)
ec5479ce 975{
95021767 976 if (default_tagless_printer.code)
ec5479ce 977 {
cbaea010
TR
978 unsigned i = 0;
979 complain_at_indent (printer->location, &i,
980 _("redeclaration for default tagless %%printer"));
981 i += SUB_INDENT;
982 complain_at_indent (default_tagless_printer.location, &i,
983 _("previous declaration"));
ec5479ce 984 }
95021767 985 default_tagless_printer = *printer;
ec5479ce 986}