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