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