]> git.saurik.com Git - bison.git/blame - src/symtab.c
Avoid empty-if warnings.
[bison.git] / src / symtab.c
CommitLineData
0fb1efaf
PE
1/* Symbol table manager for Bison.
2
ab7f29f8
JD
3 Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
4 Free Software 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>
25#include <quotearg.h>
26
2f1afb73 27#include "complain.h"
40675e7c 28#include "gram.h"
17ee7397 29#include "symtab.h"
40675e7c 30
2f1afb73
AD
31/*------------------------.
32| Distinguished symbols. |
33`------------------------*/
34
17ee7397
PE
35symbol *errtoken = NULL;
36symbol *undeftoken = NULL;
37symbol *endtoken = NULL;
38symbol *accept = NULL;
39symbol *startsymbol = NULL;
40location startsymbol_location;
2f1afb73 41
12e35840
JD
42/*---------------------------------------.
43| Default %destructor's and %printer's. |
44`---------------------------------------*/
45
95021767
JD
46static code_props default_tagged_destructor = CODE_PROPS_NONE_INIT;
47static code_props default_tagless_destructor = CODE_PROPS_NONE_INIT;
48static code_props default_tagged_printer = CODE_PROPS_NONE_INIT;
49static code_props default_tagless_printer = CODE_PROPS_NONE_INIT;
ec5479ce 50
72a23c97
AD
51/*---------------------------------.
52| Create a new symbol, named TAG. |
53`---------------------------------*/
1e9798d5 54
17ee7397
PE
55static symbol *
56symbol_new (uniqstr tag, location loc)
1e9798d5 57{
da2a7671 58 symbol *res = xmalloc (sizeof *res);
1e9798d5 59
17ee7397 60 uniqstr_assert (tag);
95612cfa 61 res->tag = tag;
17ee7397 62 res->location = loc;
24c0aad7 63
1e9798d5 64 res->type_name = NULL;
95021767
JD
65 code_props_none_init (&res->destructor);
66 code_props_none_init (&res->printer);
24c0aad7 67
5fbb0954 68 res->number = NUMBER_UNDEFINED;
1e9798d5 69 res->prec = 0;
a945ec39 70 res->assoc = undef_assoc;
b87f8b21 71 res->user_token_number = USER_NUMBER_UNDEFINED;
260008e5 72
1e9798d5
AD
73 res->alias = NULL;
74 res->class = unknown_sym;
073f9288 75 res->declared = false;
1e9798d5 76
3239db74
PE
77 if (nsyms == SYMBOL_NUMBER_MAXIMUM)
78 fatal (_("too many symbols in input grammar (limit is %d)"),
79 SYMBOL_NUMBER_MAXIMUM);
6d0ef4ec 80 nsyms++;
1e9798d5
AD
81 return res;
82}
83
b2a0b7ca
JD
84/*----------------------------------------.
85| Create a new semantic type, named TAG. |
86`----------------------------------------*/
87
88static semantic_type *
89semantic_type_new (uniqstr tag)
90{
91 semantic_type *res = xmalloc (sizeof *res);
92
93 uniqstr_assert (tag);
94 res->tag = tag;
95021767
JD
95 code_props_none_init (&res->destructor);
96 code_props_none_init (&res->printer);
b2a0b7ca
JD
97
98 return res;
99}
100
40675e7c 101
867a3e00
AD
102/*-----------------.
103| Print a symbol. |
104`-----------------*/
105
106#define SYMBOL_ATTR_PRINT(Attr) \
107 if (s->Attr) \
ab703f2c 108 fprintf (f, " %s { %s }", #Attr, s->Attr)
867a3e00 109
95021767
JD
110#define SYMBOL_CODE_PRINT(Attr) \
111 if (s->Attr.code) \
112 fprintf (f, " %s { %s }", #Attr, s->Attr.code)
113
867a3e00 114void
22dda0f0 115symbol_print (symbol *s, FILE *f)
867a3e00 116{
affac613
AD
117 if (s)
118 {
119 fprintf (f, "\"%s\"", s->tag);
120 SYMBOL_ATTR_PRINT (type_name);
95021767
JD
121 SYMBOL_CODE_PRINT (destructor);
122 SYMBOL_CODE_PRINT (printer);
affac613
AD
123 }
124 else
125 fprintf (f, "<NULL>");
867a3e00
AD
126}
127
128#undef SYMBOL_ATTR_PRINT
95021767 129#undef SYMBOL_CODE_PRINT
867a3e00 130
df09ef2e
AD
131/*------------------------------------------------------------------.
132| Complain that S's WHAT is redeclared at SECOND, and was first set |
133| at FIRST. |
134`------------------------------------------------------------------*/
135
136static void
b2a0b7ca
JD
137symbol_redeclaration (symbol *s, const char *what, location first,
138 location second)
df09ef2e
AD
139{
140 complain_at (second, _("%s redeclaration for %s"), what, s->tag);
dd60572a 141 complain_at (first, _("previous declaration"));
df09ef2e
AD
142}
143
b2a0b7ca
JD
144static void
145semantic_type_redeclaration (semantic_type *s, const char *what, location first,
146 location second)
147{
148 complain_at (second, _("%s redeclaration for <%s>"), what, s->tag);
149 complain_at (first, _("previous declaration"));
150}
151
df09ef2e 152
17ee7397
PE
153/*-----------------------------------------------------------------.
154| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
155| as TYPE_NAME. |
156`-----------------------------------------------------------------*/
3ae2b51f
AD
157
158void
17ee7397 159symbol_type_set (symbol *sym, uniqstr type_name, location loc)
3ae2b51f 160{
e9955c83
AD
161 if (type_name)
162 {
17ee7397 163 if (sym->type_name)
b2a0b7ca 164 symbol_redeclaration (sym, "%type", sym->type_location, loc);
17ee7397
PE
165 uniqstr_assert (type_name);
166 sym->type_name = type_name;
df09ef2e 167 sym->type_location = loc;
e9955c83 168 }
3ae2b51f
AD
169}
170
41d7a5f2
PE
171/*-----------------------------------.
172| Get the CLASS associated with SYM. |
173`-----------------------------------*/
174
175const char *
176symbol_class_get_string (symbol *sym)
177{
178 if (sym->class)
179 {
180 if (sym->class == token_sym)
181 return "terminal";
182 else if (sym->class == nterm_sym)
183 return "nonterminal";
184 }
185 return "unknown";
186}
187
3ae2b51f 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
1f6b3679
JD
361 if (sym->user_token_number != USER_NUMBER_ALIAS)
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;
88bce5a2 374 endtoken->number = 0;
44536b35
AD
375 /* It is always mapped to 0, so it was already counted in
376 NTOKENS. */
377 --ntokens;
378 }
379}
380
381
17ee7397
PE
382/*----------------------------------------------------------.
383| If SYM is not defined, report an error, and consider it a |
384| nonterminal. |
385`----------------------------------------------------------*/
2f1afb73 386
0fb1efaf 387static inline bool
17ee7397 388symbol_check_defined (symbol *sym)
2f1afb73 389{
17ee7397 390 if (sym->class == unknown_sym)
2f1afb73 391 {
ee000ba4 392 complain_at
17ee7397 393 (sym->location,
ee000ba4 394 _("symbol %s is used, but is not defined as a token and has no rules"),
17ee7397
PE
395 sym->tag);
396 sym->class = nterm_sym;
397 sym->number = nvars++;
2f1afb73
AD
398 }
399
a3714bce 400 return true;
2f1afb73
AD
401}
402
0fb1efaf
PE
403static bool
404symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
405{
406 return symbol_check_defined (sym);
407}
408
2f1afb73 409
17ee7397
PE
410/*------------------------------------------------------------------.
411| Declare the new symbol SYM. Make it an alias of SYMVAL, and type |
527203e9 412| SYMVAL with SYM's type. |
17ee7397 413`------------------------------------------------------------------*/
2f1afb73
AD
414
415void
17ee7397 416symbol_make_alias (symbol *sym, symbol *symval, location loc)
2f1afb73
AD
417{
418 if (symval->alias)
a5d50994 419 warn_at (loc, _("symbol `%s' used more than once as a literal string"),
df09ef2e 420 symval->tag);
17ee7397 421 else if (sym->alias)
a5d50994 422 warn_at (loc, _("symbol `%s' given more than one literal string"),
df09ef2e 423 sym->tag);
2f1afb73
AD
424 else
425 {
426 symval->class = token_sym;
17ee7397
PE
427 symval->user_token_number = sym->user_token_number;
428 sym->user_token_number = USER_NUMBER_ALIAS;
429 symval->alias = sym;
430 sym->alias = symval;
965537bc 431 symval->number = sym->number;
e8fd72d5 432 symbol_type_set (symval, sym->type_name, loc);
2f1afb73
AD
433 }
434}
435
436
437/*---------------------------------------------------------.
438| Check that THIS, and its alias, have same precedence and |
439| associativity. |
440`---------------------------------------------------------*/
441
df09ef2e 442static inline void
0fb1efaf 443symbol_check_alias_consistency (symbol *this)
2f1afb73 444{
df09ef2e
AD
445 symbol *alias = this;
446 symbol *orig = this->alias;
447
448 /* Check only those that _are_ the aliases. */
449 if (!(this->alias && this->user_token_number == USER_NUMBER_ALIAS))
450 return;
451
e8fd72d5 452 if (orig->type_name != alias->type_name)
2f1afb73 453 {
df09ef2e
AD
454 if (orig->type_name)
455 symbol_type_set (alias, orig->type_name, orig->type_location);
456 else
457 symbol_type_set (orig, alias->type_name, alias->type_location);
458 }
2f1afb73 459
df09ef2e 460
95021767 461 if (orig->destructor.code || alias->destructor.code)
df09ef2e 462 {
95021767
JD
463 if (orig->destructor.code)
464 symbol_destructor_set (alias, &orig->destructor);
df09ef2e 465 else
95021767 466 symbol_destructor_set (orig, &alias->destructor);
df09ef2e
AD
467 }
468
95021767 469 if (orig->printer.code || alias->printer.code)
df09ef2e 470 {
95021767
JD
471 if (orig->printer.code)
472 symbol_printer_set (alias, &orig->printer);
df09ef2e 473 else
95021767 474 symbol_printer_set (orig, &alias->printer);
df09ef2e
AD
475 }
476
477 if (alias->prec || orig->prec)
478 {
479 if (orig->prec)
480 symbol_precedence_set (alias, orig->prec, orig->assoc,
481 orig->prec_location);
482 else
483 symbol_precedence_set (orig, alias->prec, alias->assoc,
484 alias->prec_location);
2f1afb73 485 }
2f1afb73
AD
486}
487
0fb1efaf
PE
488static bool
489symbol_check_alias_consistency_processor (void *this,
490 void *null ATTRIBUTE_UNUSED)
491{
df09ef2e
AD
492 symbol_check_alias_consistency (this);
493 return true;
0fb1efaf
PE
494}
495
2f1afb73
AD
496
497/*-------------------------------------------------------------------.
498| Assign a symbol number, and write the definition of the token name |
499| into FDEFINES. Put in SYMBOLS. |
500`-------------------------------------------------------------------*/
501
0fb1efaf 502static inline bool
17ee7397 503symbol_pack (symbol *this)
2f1afb73
AD
504{
505 if (this->class == nterm_sym)
506 {
507 this->number += ntokens;
508 }
509 else if (this->alias)
510 {
511 /* This symbol and its alias are a single token defn.
512 Allocate a tokno, and assign to both check agreement of
513 prec and assoc fields and make both the same */
514 if (this->number == NUMBER_UNDEFINED)
515 {
88bce5a2 516 if (this == endtoken || this->alias == endtoken)
2f1afb73
AD
517 this->number = this->alias->number = 0;
518 else
519 {
4f82b42a 520 aver (this->alias->number != NUMBER_UNDEFINED);
2f1afb73
AD
521 this->number = this->alias->number;
522 }
523 }
b9e00562 524 /* Do not do processing below for USER_NUMBER_ALIASes. */
2f1afb73 525 if (this->user_token_number == USER_NUMBER_ALIAS)
a3714bce 526 return true;
2f1afb73
AD
527 }
528 else /* this->class == token_sym */
4f82b42a 529 aver (this->number != NUMBER_UNDEFINED);
2f1afb73
AD
530
531 symbols[this->number] = this;
a3714bce 532 return true;
2f1afb73
AD
533}
534
0fb1efaf
PE
535static bool
536symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
537{
538 return symbol_pack (this);
539}
540
2f1afb73
AD
541
542
543
544/*--------------------------------------------------.
545| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
546`--------------------------------------------------*/
547
0fb1efaf 548static inline bool
17ee7397 549symbol_translation (symbol *this)
2f1afb73
AD
550{
551 /* Non-terminal? */
552 if (this->class == token_sym
553 && this->user_token_number != USER_NUMBER_ALIAS)
554 {
555 /* A token which translation has already been set? */
556 if (token_translations[this->user_token_number] != undeftoken->number)
a5d50994
AD
557 complain_at (this->location,
558 _("tokens %s and %s both assigned number %d"),
559 symbols[token_translations[this->user_token_number]]->tag,
560 this->tag, this->user_token_number);
2f1afb73
AD
561
562 token_translations[this->user_token_number] = this->number;
563 }
564
a3714bce 565 return true;
2f1afb73
AD
566}
567
0fb1efaf
PE
568static bool
569symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
570{
571 return symbol_translation (this);
572}
573
72a23c97 574
b2a0b7ca
JD
575/*---------------------------------------.
576| Symbol and semantic type hash tables. |
577`---------------------------------------*/
40675e7c 578
b2a0b7ca 579/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
580#define HT_INITIAL_CAPACITY 257
581
db8837cb 582static struct hash_table *symbol_table = NULL;
b2a0b7ca 583static struct hash_table *semantic_type_table = NULL;
72a23c97 584
0fb1efaf 585static inline bool
17ee7397 586hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 587{
95612cfa 588 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 589 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
590}
591
b2a0b7ca
JD
592static inline bool
593hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
594{
595 /* Since names are unique, we can compare the pointers themselves. */
596 return UNIQSTR_EQ (m1->tag, m2->tag);
597}
598
0fb1efaf
PE
599static bool
600hash_symbol_comparator (void const *m1, void const *m2)
601{
602 return hash_compare_symbol (m1, m2);
603}
604
b2a0b7ca
JD
605static bool
606hash_semantic_type_comparator (void const *m1, void const *m2)
607{
608 return hash_compare_semantic_type (m1, m2);
609}
610
233a88ad
PE
611static inline size_t
612hash_symbol (const symbol *m, size_t tablesize)
72a23c97 613{
95612cfa 614 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
615 return ((uintptr_t) m->tag) % tablesize;
616}
617
b2a0b7ca
JD
618static inline size_t
619hash_semantic_type (const semantic_type *m, size_t tablesize)
620{
621 /* Since names are unique, we can hash the pointer itself. */
622 return ((uintptr_t) m->tag) % tablesize;
623}
624
233a88ad
PE
625static size_t
626hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
627{
628 return hash_symbol (m, tablesize);
72a23c97
AD
629}
630
b2a0b7ca
JD
631static size_t
632hash_semantic_type_hasher (void const *m, size_t tablesize)
633{
634 return hash_semantic_type (m, tablesize);
635}
72a23c97
AD
636
637/*-------------------------------.
2f1afb73 638| Create the symbol hash table. |
72a23c97
AD
639`-------------------------------*/
640
641void
db8837cb 642symbols_new (void)
72a23c97 643{
db8837cb 644 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
72a23c97 645 NULL,
0fb1efaf
PE
646 hash_symbol_hasher,
647 hash_symbol_comparator,
648 free);
b2a0b7ca
JD
649 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
650 NULL,
651 hash_semantic_type_hasher,
652 hash_semantic_type_comparator,
653 free);
40675e7c
DM
654}
655
656
1e9798d5
AD
657/*----------------------------------------------------------------.
658| Find the symbol named KEY, and return it. If it does not exist |
659| yet, create it. |
660`----------------------------------------------------------------*/
661
17ee7397 662symbol *
203b9274 663symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 664{
17ee7397
PE
665 symbol probe;
666 symbol *entry;
40675e7c 667
0fb1efaf 668 probe.tag = key;
db8837cb 669 entry = hash_lookup (symbol_table, &probe);
40675e7c 670
72a23c97 671 if (!entry)
40675e7c 672 {
72a23c97 673 /* First insertion in the hash. */
17ee7397 674 entry = symbol_new (key, loc);
db8837cb 675 hash_insert (symbol_table, entry);
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);
699 hash_insert (semantic_type_table, entry);
700 }
701 return entry;
702}
703
704
203b9274
AD
705/*----------------------------------------------------------------.
706| Find the symbol named KEY, and return it. If it does not exist |
707| yet, create it. |
708`----------------------------------------------------------------*/
709
710symbol *
711symbol_get (const char *key, location loc)
712{
713 return symbol_from_uniqstr (uniqstr_new (key), loc);
714}
715
716
b2a0b7ca
JD
717/*-----------------------------------------------------------------------.
718| Find the semantic type named KEY, and return it. If it does not exist |
719| yet, create it. |
720`-----------------------------------------------------------------------*/
721
722semantic_type *
723semantic_type_get (const char *key)
724{
725 return semantic_type_from_uniqstr (uniqstr_new (key));
726}
727
728
39f41916
AD
729/*------------------------------------------------------------------.
730| Generate a dummy nonterminal, whose name cannot conflict with the |
731| user's names. |
732`------------------------------------------------------------------*/
733
17ee7397
PE
734symbol *
735dummy_symbol_get (location loc)
39f41916
AD
736{
737 /* Incremented for each generated symbol. */
738 static int dummy_count = 0;
739 static char buf[256];
740
17ee7397 741 symbol *sym;
39f41916 742
f91b1629 743 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 744 sym = symbol_get (buf, loc);
39f41916
AD
745 sym->class = nterm_sym;
746 sym->number = nvars++;
747 return sym;
748}
749
4d7370cb
JD
750bool
751symbol_is_dummy (const symbol *sym)
752{
f91b1629 753 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 754}
39f41916 755
72a23c97 756/*-------------------.
db8837cb 757| Free the symbols. |
72a23c97
AD
758`-------------------*/
759
760void
db8837cb 761symbols_free (void)
72a23c97 762{
db8837cb 763 hash_free (symbol_table);
b2a0b7ca 764 hash_free (semantic_type_table);
536545f3 765 free (symbols);
40675e7c
DM
766}
767
768
72a23c97 769/*---------------------------------------------------------------.
db8837cb 770| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
771| terminals. |
772`---------------------------------------------------------------*/
773
0fb1efaf
PE
774static void
775symbols_do (Hash_processor processor, void *processor_data)
40675e7c 776{
0fb1efaf 777 hash_do_for_each (symbol_table, processor, processor_data);
40675e7c 778}
2f1afb73
AD
779
780
781/*--------------------------------------------------------------.
782| Check that all the symbols are defined. Report any undefined |
783| symbols and consider them nonterminals. |
784`--------------------------------------------------------------*/
785
786void
787symbols_check_defined (void)
788{
0fb1efaf 789 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
790}
791
792/*------------------------------------------------------------------.
793| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
794| number. |
795`------------------------------------------------------------------*/
796
797static void
798symbols_token_translations_init (void)
799{
a3714bce 800 bool num_256_available_p = true;
2f1afb73
AD
801 int i;
802
803 /* Find the highest user token number, and whether 256, the POSIX
804 preferred user token number for the error token, is used. */
805 max_user_token_number = 0;
806 for (i = 0; i < ntokens; ++i)
807 {
17ee7397 808 symbol *this = symbols[i];
2f1afb73
AD
809 if (this->user_token_number != USER_NUMBER_UNDEFINED)
810 {
811 if (this->user_token_number > max_user_token_number)
812 max_user_token_number = this->user_token_number;
813 if (this->user_token_number == 256)
a3714bce 814 num_256_available_p = false;
2f1afb73
AD
815 }
816 }
817
818 /* If 256 is not used, assign it to error, to follow POSIX. */
819 if (num_256_available_p
820 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
821 errtoken->user_token_number = 256;
822
823 /* Set the missing user numbers. */
824 if (max_user_token_number < 256)
825 max_user_token_number = 256;
826
827 for (i = 0; i < ntokens; ++i)
828 {
17ee7397 829 symbol *this = symbols[i];
2f1afb73
AD
830 if (this->user_token_number == USER_NUMBER_UNDEFINED)
831 this->user_token_number = ++max_user_token_number;
832 if (this->user_token_number > max_user_token_number)
833 max_user_token_number = this->user_token_number;
834 }
835
da2a7671
PE
836 token_translations = xnmalloc (max_user_token_number + 1,
837 sizeof *token_translations);
2f1afb73
AD
838
839 /* Initialize all entries for literal tokens to 2, the internal
88bce5a2
AD
840 token number for $undefined, which represents all invalid inputs.
841 */
2f1afb73
AD
842 for (i = 0; i < max_user_token_number + 1; i++)
843 token_translations[i] = undeftoken->number;
0fb1efaf 844 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
845}
846
847
848/*----------------------------------------------------------------.
849| Assign symbol numbers, and write definition of token names into |
850| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
851`----------------------------------------------------------------*/
852
853void
854symbols_pack (void)
855{
0fb1efaf 856 symbols_do (symbol_check_alias_consistency_processor, NULL);
6d0ef4ec
JD
857
858 symbols = xcalloc (nsyms, sizeof *symbols);
0fb1efaf 859 symbols_do (symbol_pack_processor, NULL);
2f1afb73 860
6d0ef4ec
JD
861 /* Aliases leave empty slots in symbols, so remove them. */
862 {
863 int writei;
864 int readi;
865 int nsyms_old = nsyms;
866 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
867 {
868 if (symbols[readi] == NULL)
869 {
870 nsyms -= 1;
871 ntokens -= 1;
872 }
873 else
874 {
875 symbols[writei] = symbols[readi];
876 symbols[writei]->number = writei;
877 if (symbols[writei]->alias)
878 symbols[writei]->alias->number = writei;
879 writei += 1;
880 }
881 }
882 }
883 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
884
2f1afb73
AD
885 symbols_token_translations_init ();
886
887 if (startsymbol->class == unknown_sym)
ee000ba4 888 fatal_at (startsymbol_location,
dafdc66f 889 _("the start symbol %s is undefined"),
97650f4e 890 startsymbol->tag);
2f1afb73 891 else if (startsymbol->class == token_sym)
ee000ba4 892 fatal_at (startsymbol_location,
dafdc66f 893 _("the start symbol %s is a token"),
97650f4e 894 startsymbol->tag);
2f1afb73 895}
ec5479ce
JD
896
897
12e35840
JD
898/*--------------------------------------------------.
899| Set default tagged/tagless %destructor/%printer. |
900`--------------------------------------------------*/
901
902void
95021767 903default_tagged_destructor_set (code_props const *destructor)
12e35840 904{
95021767 905 if (default_tagged_destructor.code)
12e35840 906 {
95021767
JD
907 complain_at (destructor->location,
908 _("redeclaration for default tagged %%destructor"));
909 complain_at (default_tagged_destructor.location,
12e35840
JD
910 _("previous declaration"));
911 }
95021767 912 default_tagged_destructor = *destructor;
12e35840
JD
913}
914
915void
95021767 916default_tagless_destructor_set (code_props const *destructor)
12e35840 917{
95021767 918 if (default_tagless_destructor.code)
12e35840 919 {
95021767
JD
920 complain_at (destructor->location,
921 _("redeclaration for default tagless %%destructor"));
922 complain_at (default_tagless_destructor.location,
12e35840
JD
923 _("previous declaration"));
924 }
95021767 925 default_tagless_destructor = *destructor;
12e35840 926}
ec5479ce
JD
927
928void
95021767 929default_tagged_printer_set (code_props const *printer)
ec5479ce 930{
95021767 931 if (default_tagged_printer.code)
ec5479ce 932 {
95021767
JD
933 complain_at (printer->location,
934 _("redeclaration for default tagged %%printer"));
935 complain_at (default_tagged_printer.location,
12e35840 936 _("previous declaration"));
ec5479ce 937 }
95021767 938 default_tagged_printer = *printer;
ec5479ce
JD
939}
940
941void
95021767 942default_tagless_printer_set (code_props const *printer)
ec5479ce 943{
95021767 944 if (default_tagless_printer.code)
ec5479ce 945 {
95021767
JD
946 complain_at (printer->location,
947 _("redeclaration for default tagless %%printer"));
948 complain_at (default_tagless_printer.location,
12e35840 949 _("previous declaration"));
ec5479ce 950 }
95021767 951 default_tagless_printer = *printer;
ec5479ce 952}