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