]> git.saurik.com Git - bison.git/blame - src/symtab.c
maint: rely on Automake for parsers.
[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>
25#include <quotearg.h>
26
2f1afb73 27#include "complain.h"
40675e7c 28#include "gram.h"
4c787a31 29#include "quote.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. */
d143e9c3 72 if (tag[0] != '\"' && tag[0] != '\'' && mbschr (tag, '-'))
663ce7bb
AD
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;
44536b35
AD
372 /* It is always mapped to 0, so it was already counted in
373 NTOKENS. */
9d6af153
JD
374 if (endtoken->number != NUMBER_UNDEFINED)
375 --ntokens;
376 endtoken->number = 0;
44536b35
AD
377 }
378}
379
380
17ee7397
PE
381/*----------------------------------------------------------.
382| If SYM is not defined, report an error, and consider it a |
383| nonterminal. |
384`----------------------------------------------------------*/
2f1afb73 385
0fb1efaf 386static inline bool
17ee7397 387symbol_check_defined (symbol *sym)
2f1afb73 388{
17ee7397 389 if (sym->class == unknown_sym)
2f1afb73 390 {
ee000ba4 391 complain_at
17ee7397 392 (sym->location,
ee000ba4 393 _("symbol %s is used, but is not defined as a token and has no rules"),
17ee7397
PE
394 sym->tag);
395 sym->class = nterm_sym;
396 sym->number = nvars++;
2f1afb73
AD
397 }
398
a3714bce 399 return true;
2f1afb73
AD
400}
401
0fb1efaf
PE
402static bool
403symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
404{
405 return symbol_check_defined (sym);
406}
407
2f1afb73 408
2f1afb73 409void
07c0db18 410symbol_make_alias (symbol *sym, symbol *str, location loc)
2f1afb73 411{
07c0db18 412 if (str->alias)
4c787a31 413 warn_at (loc, _("symbol %s used more than once as a literal string"),
9874f80b 414 str->tag);
17ee7397 415 else if (sym->alias)
4c787a31 416 warn_at (loc, _("symbol %s given more than one literal string"),
9874f80b 417 sym->tag);
2f1afb73
AD
418 else
419 {
07c0db18
JD
420 str->class = token_sym;
421 str->user_token_number = sym->user_token_number;
422 sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
423 str->alias = sym;
424 sym->alias = str;
425 str->number = sym->number;
426 symbol_type_set (str, sym->type_name, loc);
2f1afb73
AD
427 }
428}
429
430
431/*---------------------------------------------------------.
432| Check that THIS, and its alias, have same precedence and |
433| associativity. |
434`---------------------------------------------------------*/
435
df09ef2e 436static inline void
0fb1efaf 437symbol_check_alias_consistency (symbol *this)
2f1afb73 438{
07c0db18 439 symbol *sym = this;
42ec0ae1 440 symbol *str = this->alias;
df09ef2e 441
07c0db18
JD
442 /* Check only the symbol in the symbol-string pair. */
443 if (!(this->alias
444 && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
df09ef2e
AD
445 return;
446
07c0db18 447 if (str->type_name != sym->type_name)
2f1afb73 448 {
07c0db18
JD
449 if (str->type_name)
450 symbol_type_set (sym, str->type_name, str->type_location);
df09ef2e 451 else
07c0db18 452 symbol_type_set (str, sym->type_name, sym->type_location);
df09ef2e 453 }
2f1afb73 454
df09ef2e 455
07c0db18 456 if (str->destructor.code || sym->destructor.code)
df09ef2e 457 {
07c0db18
JD
458 if (str->destructor.code)
459 symbol_destructor_set (sym, &str->destructor);
df09ef2e 460 else
07c0db18 461 symbol_destructor_set (str, &sym->destructor);
df09ef2e
AD
462 }
463
07c0db18 464 if (str->printer.code || sym->printer.code)
df09ef2e 465 {
07c0db18
JD
466 if (str->printer.code)
467 symbol_printer_set (sym, &str->printer);
df09ef2e 468 else
07c0db18 469 symbol_printer_set (str, &sym->printer);
df09ef2e
AD
470 }
471
07c0db18 472 if (sym->prec || str->prec)
df09ef2e 473 {
07c0db18
JD
474 if (str->prec)
475 symbol_precedence_set (sym, str->prec, str->assoc,
476 str->prec_location);
df09ef2e 477 else
07c0db18
JD
478 symbol_precedence_set (str, sym->prec, sym->assoc,
479 sym->prec_location);
2f1afb73 480 }
2f1afb73
AD
481}
482
0fb1efaf
PE
483static bool
484symbol_check_alias_consistency_processor (void *this,
485 void *null ATTRIBUTE_UNUSED)
486{
df09ef2e
AD
487 symbol_check_alias_consistency (this);
488 return true;
0fb1efaf
PE
489}
490
2f1afb73
AD
491
492/*-------------------------------------------------------------------.
493| Assign a symbol number, and write the definition of the token name |
494| into FDEFINES. Put in SYMBOLS. |
495`-------------------------------------------------------------------*/
496
0fb1efaf 497static inline bool
17ee7397 498symbol_pack (symbol *this)
2f1afb73 499{
4c6b13f3 500 aver (this->number != NUMBER_UNDEFINED);
2f1afb73 501 if (this->class == nterm_sym)
4c6b13f3
JD
502 this->number += ntokens;
503 else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
504 return true;
2f1afb73
AD
505
506 symbols[this->number] = this;
a3714bce 507 return true;
2f1afb73
AD
508}
509
0fb1efaf
PE
510static bool
511symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
512{
513 return symbol_pack (this);
514}
515
2f1afb73 516
95d176ff
AD
517static void
518user_token_number_redeclaration (int num, symbol *first, symbol *second)
519{
520 /* User token numbers are not assigned during the parsing, but in a
24985964 521 second step, via a traversal of the symbol table sorted on tag.
2f1afb73 522
24985964
JD
523 However, error messages make more sense if we keep the first
524 declaration first. */
95d176ff
AD
525 if (location_cmp (first->location, second->location) > 0)
526 {
527 symbol* tmp = first;
528 first = second;
529 second = tmp;
530 }
531 complain_at (second->location,
532 _("user token number %d redeclaration for %s"),
533 num, second->tag);
534 complain_at (first->location, _("previous declaration for %s"),
535 first->tag);
536}
2f1afb73
AD
537
538/*--------------------------------------------------.
539| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
540`--------------------------------------------------*/
541
0fb1efaf 542static inline bool
17ee7397 543symbol_translation (symbol *this)
2f1afb73
AD
544{
545 /* Non-terminal? */
546 if (this->class == token_sym
07c0db18 547 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
2f1afb73
AD
548 {
549 /* A token which translation has already been set? */
550 if (token_translations[this->user_token_number] != undeftoken->number)
95d176ff
AD
551 user_token_number_redeclaration
552 (this->user_token_number,
553 symbols[token_translations[this->user_token_number]],
554 this);
2f1afb73
AD
555
556 token_translations[this->user_token_number] = this->number;
557 }
558
a3714bce 559 return true;
2f1afb73
AD
560}
561
0fb1efaf
PE
562static bool
563symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
564{
565 return symbol_translation (this);
566}
567
72a23c97 568
b2a0b7ca
JD
569/*---------------------------------------.
570| Symbol and semantic type hash tables. |
571`---------------------------------------*/
40675e7c 572
b2a0b7ca 573/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
574#define HT_INITIAL_CAPACITY 257
575
db8837cb 576static struct hash_table *symbol_table = NULL;
b2a0b7ca 577static struct hash_table *semantic_type_table = NULL;
72a23c97 578
0fb1efaf 579static inline bool
17ee7397 580hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 581{
95612cfa 582 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 583 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
584}
585
b2a0b7ca
JD
586static inline bool
587hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
588{
589 /* Since names are unique, we can compare the pointers themselves. */
590 return UNIQSTR_EQ (m1->tag, m2->tag);
591}
592
0fb1efaf
PE
593static bool
594hash_symbol_comparator (void const *m1, void const *m2)
595{
596 return hash_compare_symbol (m1, m2);
597}
598
b2a0b7ca
JD
599static bool
600hash_semantic_type_comparator (void const *m1, void const *m2)
601{
602 return hash_compare_semantic_type (m1, m2);
603}
604
233a88ad
PE
605static inline size_t
606hash_symbol (const symbol *m, size_t tablesize)
72a23c97 607{
95612cfa 608 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
609 return ((uintptr_t) m->tag) % tablesize;
610}
611
b2a0b7ca
JD
612static inline size_t
613hash_semantic_type (const semantic_type *m, size_t tablesize)
614{
615 /* Since names are unique, we can hash the pointer itself. */
616 return ((uintptr_t) m->tag) % tablesize;
617}
618
233a88ad
PE
619static size_t
620hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
621{
622 return hash_symbol (m, tablesize);
72a23c97
AD
623}
624
b2a0b7ca
JD
625static size_t
626hash_semantic_type_hasher (void const *m, size_t tablesize)
627{
628 return hash_semantic_type (m, tablesize);
629}
72a23c97
AD
630
631/*-------------------------------.
2f1afb73 632| Create the symbol hash table. |
72a23c97
AD
633`-------------------------------*/
634
635void
db8837cb 636symbols_new (void)
72a23c97 637{
db8837cb 638 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
72a23c97 639 NULL,
0fb1efaf
PE
640 hash_symbol_hasher,
641 hash_symbol_comparator,
642 free);
b2a0b7ca
JD
643 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
644 NULL,
645 hash_semantic_type_hasher,
646 hash_semantic_type_comparator,
647 free);
40675e7c
DM
648}
649
650
1e9798d5
AD
651/*----------------------------------------------------------------.
652| Find the symbol named KEY, and return it. If it does not exist |
653| yet, create it. |
654`----------------------------------------------------------------*/
655
17ee7397 656symbol *
203b9274 657symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 658{
17ee7397
PE
659 symbol probe;
660 symbol *entry;
40675e7c 661
0fb1efaf 662 probe.tag = key;
db8837cb 663 entry = hash_lookup (symbol_table, &probe);
40675e7c 664
72a23c97 665 if (!entry)
40675e7c 666 {
72a23c97 667 /* First insertion in the hash. */
24985964 668 aver (!symbols_sorted);
17ee7397 669 entry = symbol_new (key, loc);
ed15d907
AD
670 if (!hash_insert (symbol_table, entry))
671 xalloc_die ();
40675e7c 672 }
72a23c97
AD
673 return entry;
674}
40675e7c 675
40675e7c 676
b2a0b7ca
JD
677/*-----------------------------------------------------------------------.
678| Find the semantic type named KEY, and return it. If it does not exist |
679| yet, create it. |
680`-----------------------------------------------------------------------*/
681
682semantic_type *
683semantic_type_from_uniqstr (const uniqstr key)
684{
685 semantic_type probe;
686 semantic_type *entry;
687
688 probe.tag = key;
689 entry = hash_lookup (semantic_type_table, &probe);
690
691 if (!entry)
692 {
693 /* First insertion in the hash. */
694 entry = semantic_type_new (key);
ed15d907
AD
695 if (!hash_insert (semantic_type_table, entry))
696 xalloc_die ();
b2a0b7ca
JD
697 }
698 return entry;
699}
700
701
203b9274
AD
702/*----------------------------------------------------------------.
703| Find the symbol named KEY, and return it. If it does not exist |
704| yet, create it. |
705`----------------------------------------------------------------*/
706
707symbol *
708symbol_get (const char *key, location loc)
709{
710 return symbol_from_uniqstr (uniqstr_new (key), loc);
711}
712
713
b2a0b7ca
JD
714/*-----------------------------------------------------------------------.
715| Find the semantic type named KEY, and return it. If it does not exist |
716| yet, create it. |
717`-----------------------------------------------------------------------*/
718
719semantic_type *
720semantic_type_get (const char *key)
721{
722 return semantic_type_from_uniqstr (uniqstr_new (key));
723}
724
725
39f41916
AD
726/*------------------------------------------------------------------.
727| Generate a dummy nonterminal, whose name cannot conflict with the |
728| user's names. |
729`------------------------------------------------------------------*/
730
17ee7397
PE
731symbol *
732dummy_symbol_get (location loc)
39f41916
AD
733{
734 /* Incremented for each generated symbol. */
735 static int dummy_count = 0;
736 static char buf[256];
737
17ee7397 738 symbol *sym;
39f41916 739
f91b1629 740 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 741 sym = symbol_get (buf, loc);
39f41916
AD
742 sym->class = nterm_sym;
743 sym->number = nvars++;
744 return sym;
745}
746
4d7370cb
JD
747bool
748symbol_is_dummy (const symbol *sym)
749{
f91b1629 750 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 751}
39f41916 752
72a23c97 753/*-------------------.
db8837cb 754| Free the symbols. |
72a23c97
AD
755`-------------------*/
756
757void
db8837cb 758symbols_free (void)
72a23c97 759{
db8837cb 760 hash_free (symbol_table);
b2a0b7ca 761 hash_free (semantic_type_table);
536545f3 762 free (symbols);
24985964 763 free (symbols_sorted);
40675e7c
DM
764}
765
766
72a23c97 767/*---------------------------------------------------------------.
db8837cb 768| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
769| terminals. |
770`---------------------------------------------------------------*/
771
24985964
JD
772static int
773symbols_cmp (symbol const *a, symbol const *b)
774{
775 return strcmp (a->tag, b->tag);
776}
777
778static int
779symbols_cmp_qsort (void const *a, void const *b)
780{
781 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
782}
783
0fb1efaf
PE
784static void
785symbols_do (Hash_processor processor, void *processor_data)
40675e7c 786{
24985964
JD
787 size_t count = hash_get_n_entries (symbol_table);
788 if (!symbols_sorted)
789 {
790 symbols_sorted = xnmalloc (count, sizeof *symbols_sorted);
791 hash_get_entries (symbol_table, (void**)symbols_sorted, count);
792 qsort (symbols_sorted, count, sizeof *symbols_sorted,
793 symbols_cmp_qsort);
794 }
795 {
796 size_t i;
797 for (i = 0; i < count; ++i)
798 processor (symbols_sorted[i], processor_data);
799 }
40675e7c 800}
2f1afb73 801
2f1afb73
AD
802/*--------------------------------------------------------------.
803| Check that all the symbols are defined. Report any undefined |
804| symbols and consider them nonterminals. |
805`--------------------------------------------------------------*/
806
807void
808symbols_check_defined (void)
809{
0fb1efaf 810 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
811}
812
813/*------------------------------------------------------------------.
814| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
815| number. |
816`------------------------------------------------------------------*/
817
818static void
819symbols_token_translations_init (void)
820{
a3714bce 821 bool num_256_available_p = true;
2f1afb73
AD
822 int i;
823
824 /* Find the highest user token number, and whether 256, the POSIX
825 preferred user token number for the error token, is used. */
826 max_user_token_number = 0;
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 {
832 if (this->user_token_number > max_user_token_number)
833 max_user_token_number = this->user_token_number;
834 if (this->user_token_number == 256)
a3714bce 835 num_256_available_p = false;
2f1afb73
AD
836 }
837 }
838
839 /* If 256 is not used, assign it to error, to follow POSIX. */
840 if (num_256_available_p
841 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
842 errtoken->user_token_number = 256;
843
844 /* Set the missing user numbers. */
845 if (max_user_token_number < 256)
846 max_user_token_number = 256;
847
848 for (i = 0; i < ntokens; ++i)
849 {
17ee7397 850 symbol *this = symbols[i];
2f1afb73
AD
851 if (this->user_token_number == USER_NUMBER_UNDEFINED)
852 this->user_token_number = ++max_user_token_number;
853 if (this->user_token_number > max_user_token_number)
854 max_user_token_number = this->user_token_number;
855 }
856
da2a7671
PE
857 token_translations = xnmalloc (max_user_token_number + 1,
858 sizeof *token_translations);
2f1afb73
AD
859
860 /* Initialize all entries for literal tokens to 2, the internal
88bce5a2
AD
861 token number for $undefined, which represents all invalid inputs.
862 */
2f1afb73
AD
863 for (i = 0; i < max_user_token_number + 1; i++)
864 token_translations[i] = undeftoken->number;
0fb1efaf 865 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
866}
867
868
869/*----------------------------------------------------------------.
870| Assign symbol numbers, and write definition of token names into |
871| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
872`----------------------------------------------------------------*/
873
874void
875symbols_pack (void)
876{
0fb1efaf 877 symbols_do (symbol_check_alias_consistency_processor, NULL);
6d0ef4ec
JD
878
879 symbols = xcalloc (nsyms, sizeof *symbols);
0fb1efaf 880 symbols_do (symbol_pack_processor, NULL);
2f1afb73 881
6d0ef4ec
JD
882 /* Aliases leave empty slots in symbols, so remove them. */
883 {
884 int writei;
885 int readi;
886 int nsyms_old = nsyms;
887 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
888 {
889 if (symbols[readi] == NULL)
890 {
891 nsyms -= 1;
892 ntokens -= 1;
893 }
894 else
895 {
896 symbols[writei] = symbols[readi];
897 symbols[writei]->number = writei;
898 if (symbols[writei]->alias)
899 symbols[writei]->alias->number = writei;
900 writei += 1;
901 }
902 }
903 }
904 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
905
2f1afb73
AD
906 symbols_token_translations_init ();
907
908 if (startsymbol->class == unknown_sym)
ee000ba4 909 fatal_at (startsymbol_location,
dafdc66f 910 _("the start symbol %s is undefined"),
97650f4e 911 startsymbol->tag);
2f1afb73 912 else if (startsymbol->class == token_sym)
ee000ba4 913 fatal_at (startsymbol_location,
dafdc66f 914 _("the start symbol %s is a token"),
97650f4e 915 startsymbol->tag);
2f1afb73 916}
ec5479ce
JD
917
918
12e35840
JD
919/*--------------------------------------------------.
920| Set default tagged/tagless %destructor/%printer. |
921`--------------------------------------------------*/
922
923void
95021767 924default_tagged_destructor_set (code_props const *destructor)
12e35840 925{
95021767 926 if (default_tagged_destructor.code)
12e35840 927 {
95021767
JD
928 complain_at (destructor->location,
929 _("redeclaration for default tagged %%destructor"));
930 complain_at (default_tagged_destructor.location,
12e35840
JD
931 _("previous declaration"));
932 }
95021767 933 default_tagged_destructor = *destructor;
12e35840
JD
934}
935
936void
95021767 937default_tagless_destructor_set (code_props const *destructor)
12e35840 938{
95021767 939 if (default_tagless_destructor.code)
12e35840 940 {
95021767
JD
941 complain_at (destructor->location,
942 _("redeclaration for default tagless %%destructor"));
943 complain_at (default_tagless_destructor.location,
12e35840
JD
944 _("previous declaration"));
945 }
95021767 946 default_tagless_destructor = *destructor;
12e35840 947}
ec5479ce
JD
948
949void
95021767 950default_tagged_printer_set (code_props const *printer)
ec5479ce 951{
95021767 952 if (default_tagged_printer.code)
ec5479ce 953 {
95021767
JD
954 complain_at (printer->location,
955 _("redeclaration for default tagged %%printer"));
956 complain_at (default_tagged_printer.location,
12e35840 957 _("previous declaration"));
ec5479ce 958 }
95021767 959 default_tagged_printer = *printer;
ec5479ce
JD
960}
961
962void
95021767 963default_tagless_printer_set (code_props const *printer)
ec5479ce 964{
95021767 965 if (default_tagless_printer.code)
ec5479ce 966 {
95021767
JD
967 complain_at (printer->location,
968 _("redeclaration for default tagless %%printer"));
969 complain_at (default_tagless_printer.location,
12e35840 970 _("previous declaration"));
ec5479ce 971 }
95021767 972 default_tagless_printer = *printer;
ec5479ce 973}