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