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