]> git.saurik.com Git - bison.git/blame - src/symtab.c
tests: enhance AT_SYNCLINES_COMPILE.
[bison.git] / src / symtab.c
CommitLineData
0fb1efaf
PE
1/* Symbol table manager for Bison.
2
e141f4d4
JD
3 Copyright (C) 1984, 1989, 2000-2002, 2004-2010 Free Software
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. */
71 if (tag[0] != '\"' && tag[0] != '\'' && strchr (tag, '-'))
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)"),
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
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)
b2a0b7ca 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)
b2a0b7ca
JD
343 symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
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)
378 warn_at (loc, _("symbol %s redeclared"), sym->tag);
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;
88bce5a2 406 endtoken->number = 0;
44536b35
AD
407 /* It is always mapped to 0, so it was already counted in
408 NTOKENS. */
409 --ntokens;
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
17ee7397 425 (sym->location,
ee000ba4 426 _("symbol %s is used, but is not defined as a token and has no rules"),
17ee7397
PE
427 sym->tag);
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)
a5d50994 446 warn_at (loc, _("symbol `%s' used more than once as a literal string"),
dfaa4860 447 str->tag);
17ee7397 448 else if (sym->alias)
a5d50994 449 warn_at (loc, _("symbol `%s' given more than one literal string"),
df09ef2e 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
JD
482 if (str->type_name)
483 symbol_type_set (sym, str->type_name, str->type_location);
df09ef2e 484 else
dfaa4860 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
JD
491 if (str->destructor.code)
492 symbol_destructor_set (sym, &str->destructor);
df09ef2e 493 else
dfaa4860 494 symbol_destructor_set (str, &sym->destructor);
df09ef2e
AD
495 }
496
dfaa4860 497 if (str->printer.code || sym->printer.code)
df09ef2e 498 {
dfaa4860
JD
499 if (str->printer.code)
500 symbol_printer_set (sym, &str->printer);
df09ef2e 501 else
dfaa4860 502 symbol_printer_set (str, &sym->printer);
df09ef2e
AD
503 }
504
dfaa4860 505 if (sym->prec || str->prec)
df09ef2e 506 {
dfaa4860
JD
507 if (str->prec)
508 symbol_precedence_set (sym, str->prec, str->assoc,
509 str->prec_location);
df09ef2e 510 else
dfaa4860
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,
518 void *null ATTRIBUTE_UNUSED)
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)
12cf133f
AD
584 user_token_number_redeclaration
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,
72a23c97 672 NULL,
0fb1efaf
PE
673 hash_symbol_hasher,
674 hash_symbol_comparator,
675 free);
b2a0b7ca
JD
676 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
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
AD
863 if (this->user_token_number != USER_NUMBER_UNDEFINED)
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)
a3714bce 868 num_256_available_p = false;
2f1afb73
AD
869 }
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
AD
884 if (this->user_token_number == USER_NUMBER_UNDEFINED)
885 this->user_token_number = ++max_user_token_number;
886 if (this->user_token_number > max_user_token_number)
887 max_user_token_number = this->user_token_number;
888 }
889
da2a7671
PE
890 token_translations = xnmalloc (max_user_token_number + 1,
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,
dafdc66f 942 _("the start symbol %s is undefined"),
97650f4e 943 startsymbol->tag);
2f1afb73 944 else if (startsymbol->class == token_sym)
ee000ba4 945 fatal_at (startsymbol_location,
dafdc66f 946 _("the start symbol %s is a token"),
97650f4e 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,
12e35840
JD
963 _("previous declaration"));
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,
12e35840
JD
976 _("previous declaration"));
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,
12e35840 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,
12e35840 1002 _("previous declaration"));
ec5479ce 1003 }
95021767 1004 default_tagless_printer = *printer;
ec5479ce 1005}