]> git.saurik.com Git - bison.git/blame - src/symtab.c
* bootstrap: Comment out the AM_CPPFLAGS line, since we don't use
[bison.git] / src / symtab.c
CommitLineData
0fb1efaf
PE
1/* Symbol table manager for Bison.
2
073f9288
PE
3 Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2006 Free
4 Software Foundation, Inc.
40675e7c 5
95e36146 6 This file is part of Bison, the GNU Compiler Compiler.
40675e7c 7
95e36146
AD
8 Bison is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
40675e7c 12
95e36146
AD
13 Bison is distributed in the hope that it will be useful,
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
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to
0fb669f9
PE
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
40675e7c 22
2cec9080 23#include <config.h>
40675e7c 24#include "system.h"
17ee7397
PE
25
26#include <hash.h>
27#include <quotearg.h>
28
2f1afb73 29#include "complain.h"
40675e7c 30#include "gram.h"
17ee7397 31#include "symtab.h"
40675e7c 32
2f1afb73
AD
33/*------------------------.
34| Distinguished symbols. |
35`------------------------*/
36
17ee7397
PE
37symbol *errtoken = NULL;
38symbol *undeftoken = NULL;
39symbol *endtoken = NULL;
40symbol *accept = NULL;
41symbol *startsymbol = NULL;
42location startsymbol_location;
2f1afb73 43
72a23c97
AD
44/*---------------------------------.
45| Create a new symbol, named TAG. |
46`---------------------------------*/
1e9798d5 47
17ee7397
PE
48static symbol *
49symbol_new (uniqstr tag, location loc)
1e9798d5 50{
da2a7671 51 symbol *res = xmalloc (sizeof *res);
1e9798d5 52
17ee7397 53 uniqstr_assert (tag);
95612cfa 54 res->tag = tag;
17ee7397 55 res->location = loc;
24c0aad7 56
1e9798d5 57 res->type_name = NULL;
9280d3ef 58 res->destructor = NULL;
260008e5 59 res->printer = NULL;
24c0aad7 60
5fbb0954 61 res->number = NUMBER_UNDEFINED;
1e9798d5 62 res->prec = 0;
a945ec39 63 res->assoc = undef_assoc;
b87f8b21 64 res->user_token_number = USER_NUMBER_UNDEFINED;
260008e5 65
1e9798d5
AD
66 res->alias = NULL;
67 res->class = unknown_sym;
073f9288 68 res->declared = false;
1e9798d5 69
3239db74
PE
70 if (nsyms == SYMBOL_NUMBER_MAXIMUM)
71 fatal (_("too many symbols in input grammar (limit is %d)"),
72 SYMBOL_NUMBER_MAXIMUM);
1e9798d5 73 nsyms++;
1e9798d5
AD
74 return res;
75}
76
40675e7c 77
867a3e00
AD
78/*-----------------.
79| Print a symbol. |
80`-----------------*/
81
82#define SYMBOL_ATTR_PRINT(Attr) \
83 if (s->Attr) \
ab703f2c 84 fprintf (f, " %s { %s }", #Attr, s->Attr)
867a3e00
AD
85
86void
22dda0f0 87symbol_print (symbol *s, FILE *f)
867a3e00 88{
affac613
AD
89 if (s)
90 {
91 fprintf (f, "\"%s\"", s->tag);
92 SYMBOL_ATTR_PRINT (type_name);
93 SYMBOL_ATTR_PRINT (destructor);
94 SYMBOL_ATTR_PRINT (printer);
95 }
96 else
97 fprintf (f, "<NULL>");
867a3e00
AD
98}
99
100#undef SYMBOL_ATTR_PRINT
101
df09ef2e
AD
102/*------------------------------------------------------------------.
103| Complain that S's WHAT is redeclared at SECOND, and was first set |
104| at FIRST. |
105`------------------------------------------------------------------*/
106
107static void
108redeclaration (symbol* s, const char *what, location first, location second)
109{
110 complain_at (second, _("%s redeclaration for %s"), what, s->tag);
111 complain_at (first, _("first declaration"));
112}
113
114
17ee7397
PE
115/*-----------------------------------------------------------------.
116| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
117| as TYPE_NAME. |
118`-----------------------------------------------------------------*/
3ae2b51f
AD
119
120void
17ee7397 121symbol_type_set (symbol *sym, uniqstr type_name, location loc)
3ae2b51f 122{
e9955c83
AD
123 if (type_name)
124 {
17ee7397 125 if (sym->type_name)
df09ef2e 126 redeclaration (sym, "%type", sym->type_location, loc);
17ee7397
PE
127 uniqstr_assert (type_name);
128 sym->type_name = type_name;
df09ef2e 129 sym->type_location = loc;
e9955c83 130 }
3ae2b51f
AD
131}
132
133
17ee7397
PE
134/*------------------------------------------------------------------.
135| Set the DESTRUCTOR associated with SYM. Do nothing if passed 0. |
136`------------------------------------------------------------------*/
9280d3ef
AD
137
138void
c1432f65 139symbol_destructor_set (symbol *sym, const char *destructor, location loc)
9280d3ef
AD
140{
141 if (destructor)
142 {
17ee7397 143 if (sym->destructor)
df09ef2e 144 redeclaration (sym, "%destructor", sym->destructor_location, loc);
17ee7397
PE
145 sym->destructor = destructor;
146 sym->destructor_location = loc;
9280d3ef
AD
147 }
148}
149
150
17ee7397
PE
151/*---------------------------------------------------------------.
152| Set the PRINTER associated with SYM. Do nothing if passed 0. |
153`---------------------------------------------------------------*/
366eea36
AD
154
155void
c1432f65 156symbol_printer_set (symbol *sym, const char *printer, location loc)
366eea36
AD
157{
158 if (printer)
159 {
17ee7397 160 if (sym->printer)
df09ef2e 161 redeclaration (sym, "%printer", sym->destructor_location, loc);
17ee7397
PE
162 sym->printer = printer;
163 sym->printer_location = loc;
366eea36
AD
164 }
165}
166
167
17ee7397
PE
168/*-----------------------------------------------------------------.
169| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
170| with UNDEF_ASSOC as ASSOC. |
171`-----------------------------------------------------------------*/
3ae2b51f
AD
172
173void
17ee7397 174symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
3ae2b51f 175{
17ee7397 176 if (a != undef_assoc)
e9955c83 177 {
17ee7397 178 if (sym->prec != 0)
df09ef2e 179 redeclaration (sym, assoc_to_string (a), sym->prec_location, loc);
17ee7397
PE
180 sym->prec = prec;
181 sym->assoc = a;
df09ef2e 182 sym->prec_location = loc;
e9955c83
AD
183 }
184
185 /* Only terminals have a precedence. */
073f9288 186 symbol_class_set (sym, token_sym, loc, false);
3ae2b51f
AD
187}
188
189
17ee7397
PE
190/*------------------------------------.
191| Set the CLASS associated with SYM. |
192`------------------------------------*/
44536b35
AD
193
194void
073f9288 195symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
44536b35 196{
17ee7397 197 if (sym->class != unknown_sym && sym->class != class)
073f9288
PE
198 {
199 complain_at (loc, _("symbol %s redefined"), sym->tag);
200 sym->declared = false;
201 }
44536b35 202
17ee7397
PE
203 if (class == nterm_sym && sym->class != nterm_sym)
204 sym->number = nvars++;
205 else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
206 sym->number = ntokens++;
44536b35 207
17ee7397 208 sym->class = class;
073f9288
PE
209
210 if (declaring)
211 {
212 if (sym->declared)
213 warn_at (loc, _("symbol %s redeclared"), sym->tag);
214 sym->declared = true;
215 }
44536b35
AD
216}
217
218
17ee7397
PE
219/*------------------------------------------------.
220| Set the USER_TOKEN_NUMBER associated with SYM. |
221`------------------------------------------------*/
44536b35
AD
222
223void
17ee7397 224symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
44536b35 225{
68cae94e 226 assert (sym->class == token_sym);
44536b35 227
17ee7397
PE
228 if (sym->user_token_number != USER_NUMBER_UNDEFINED
229 && sym->user_token_number != user_token_number)
230 complain_at (loc, _("redefining user token number of %s"), sym->tag);
44536b35 231
17ee7397 232 sym->user_token_number = user_token_number;
88bce5a2 233 /* User defined $end token? */
44536b35
AD
234 if (user_token_number == 0)
235 {
17ee7397 236 endtoken = sym;
88bce5a2 237 endtoken->number = 0;
44536b35
AD
238 /* It is always mapped to 0, so it was already counted in
239 NTOKENS. */
240 --ntokens;
241 }
242}
243
244
17ee7397
PE
245/*----------------------------------------------------------.
246| If SYM is not defined, report an error, and consider it a |
247| nonterminal. |
248`----------------------------------------------------------*/
2f1afb73 249
0fb1efaf 250static inline bool
17ee7397 251symbol_check_defined (symbol *sym)
2f1afb73 252{
17ee7397 253 if (sym->class == unknown_sym)
2f1afb73 254 {
ee000ba4 255 complain_at
17ee7397 256 (sym->location,
ee000ba4 257 _("symbol %s is used, but is not defined as a token and has no rules"),
17ee7397
PE
258 sym->tag);
259 sym->class = nterm_sym;
260 sym->number = nvars++;
2f1afb73
AD
261 }
262
a3714bce 263 return true;
2f1afb73
AD
264}
265
0fb1efaf
PE
266static bool
267symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
268{
269 return symbol_check_defined (sym);
270}
271
2f1afb73 272
17ee7397
PE
273/*------------------------------------------------------------------.
274| Declare the new symbol SYM. Make it an alias of SYMVAL, and type |
527203e9 275| SYMVAL with SYM's type. |
17ee7397 276`------------------------------------------------------------------*/
2f1afb73
AD
277
278void
17ee7397 279symbol_make_alias (symbol *sym, symbol *symval, location loc)
2f1afb73
AD
280{
281 if (symval->alias)
a5d50994 282 warn_at (loc, _("symbol `%s' used more than once as a literal string"),
df09ef2e 283 symval->tag);
17ee7397 284 else if (sym->alias)
a5d50994 285 warn_at (loc, _("symbol `%s' given more than one literal string"),
df09ef2e 286 sym->tag);
2f1afb73
AD
287 else
288 {
289 symval->class = token_sym;
17ee7397
PE
290 symval->user_token_number = sym->user_token_number;
291 sym->user_token_number = USER_NUMBER_ALIAS;
292 symval->alias = sym;
293 sym->alias = symval;
294 /* sym and symval combined are only one symbol. */
2f1afb73
AD
295 nsyms--;
296 ntokens--;
68cae94e 297 assert (ntokens == sym->number || ntokens == symval->number);
17ee7397
PE
298 sym->number = symval->number =
299 (symval->number < sym->number) ? symval->number : sym->number;
e8fd72d5 300 symbol_type_set (symval, sym->type_name, loc);
2f1afb73
AD
301 }
302}
303
304
305/*---------------------------------------------------------.
306| Check that THIS, and its alias, have same precedence and |
307| associativity. |
308`---------------------------------------------------------*/
309
df09ef2e 310static inline void
0fb1efaf 311symbol_check_alias_consistency (symbol *this)
2f1afb73 312{
df09ef2e
AD
313 symbol *alias = this;
314 symbol *orig = this->alias;
315
316 /* Check only those that _are_ the aliases. */
317 if (!(this->alias && this->user_token_number == USER_NUMBER_ALIAS))
318 return;
319
e8fd72d5 320 if (orig->type_name != alias->type_name)
2f1afb73 321 {
df09ef2e
AD
322 if (orig->type_name)
323 symbol_type_set (alias, orig->type_name, orig->type_location);
324 else
325 symbol_type_set (orig, alias->type_name, alias->type_location);
326 }
2f1afb73 327
df09ef2e
AD
328
329 if (orig->destructor || alias->destructor)
330 {
331 if (orig->destructor)
332 symbol_destructor_set (alias, orig->destructor,
333 orig->destructor_location);
334 else
335 symbol_destructor_set (orig, alias->destructor,
336 alias->destructor_location);
337 }
338
339 if (orig->printer || alias->printer)
340 {
341 if (orig->printer)
342 symbol_printer_set (alias, orig->printer, orig->printer_location);
343 else
344 symbol_printer_set (orig, alias->printer, alias->printer_location);
345 }
346
347 if (alias->prec || orig->prec)
348 {
349 if (orig->prec)
350 symbol_precedence_set (alias, orig->prec, orig->assoc,
351 orig->prec_location);
352 else
353 symbol_precedence_set (orig, alias->prec, alias->assoc,
354 alias->prec_location);
2f1afb73 355 }
2f1afb73
AD
356}
357
0fb1efaf
PE
358static bool
359symbol_check_alias_consistency_processor (void *this,
360 void *null ATTRIBUTE_UNUSED)
361{
df09ef2e
AD
362 symbol_check_alias_consistency (this);
363 return true;
0fb1efaf
PE
364}
365
2f1afb73
AD
366
367/*-------------------------------------------------------------------.
368| Assign a symbol number, and write the definition of the token name |
369| into FDEFINES. Put in SYMBOLS. |
370`-------------------------------------------------------------------*/
371
0fb1efaf 372static inline bool
17ee7397 373symbol_pack (symbol *this)
2f1afb73
AD
374{
375 if (this->class == nterm_sym)
376 {
377 this->number += ntokens;
378 }
379 else if (this->alias)
380 {
381 /* This symbol and its alias are a single token defn.
382 Allocate a tokno, and assign to both check agreement of
383 prec and assoc fields and make both the same */
384 if (this->number == NUMBER_UNDEFINED)
385 {
88bce5a2 386 if (this == endtoken || this->alias == endtoken)
2f1afb73
AD
387 this->number = this->alias->number = 0;
388 else
389 {
68cae94e 390 assert (this->alias->number != NUMBER_UNDEFINED);
2f1afb73
AD
391 this->number = this->alias->number;
392 }
393 }
b9e00562 394 /* Do not do processing below for USER_NUMBER_ALIASes. */
2f1afb73 395 if (this->user_token_number == USER_NUMBER_ALIAS)
a3714bce 396 return true;
2f1afb73
AD
397 }
398 else /* this->class == token_sym */
68cae94e 399 assert (this->number != NUMBER_UNDEFINED);
2f1afb73
AD
400
401 symbols[this->number] = this;
a3714bce 402 return true;
2f1afb73
AD
403}
404
0fb1efaf
PE
405static bool
406symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
407{
408 return symbol_pack (this);
409}
410
2f1afb73
AD
411
412
413
414/*--------------------------------------------------.
415| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
416`--------------------------------------------------*/
417
0fb1efaf 418static inline bool
17ee7397 419symbol_translation (symbol *this)
2f1afb73
AD
420{
421 /* Non-terminal? */
422 if (this->class == token_sym
423 && this->user_token_number != USER_NUMBER_ALIAS)
424 {
425 /* A token which translation has already been set? */
426 if (token_translations[this->user_token_number] != undeftoken->number)
a5d50994
AD
427 complain_at (this->location,
428 _("tokens %s and %s both assigned number %d"),
429 symbols[token_translations[this->user_token_number]]->tag,
430 this->tag, this->user_token_number);
2f1afb73
AD
431
432 token_translations[this->user_token_number] = this->number;
433 }
434
a3714bce 435 return true;
2f1afb73
AD
436}
437
0fb1efaf
PE
438static bool
439symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
440{
441 return symbol_translation (this);
442}
443
72a23c97
AD
444
445/*----------------------.
2f1afb73 446| A symbol hash table. |
72a23c97 447`----------------------*/
40675e7c 448
db8837cb 449/* Initial capacity of symbols hash table. */
72a23c97
AD
450#define HT_INITIAL_CAPACITY 257
451
db8837cb 452static struct hash_table *symbol_table = NULL;
72a23c97 453
0fb1efaf 454static inline bool
17ee7397 455hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 456{
95612cfa 457 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 458 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
459}
460
0fb1efaf
PE
461static bool
462hash_symbol_comparator (void const *m1, void const *m2)
463{
464 return hash_compare_symbol (m1, m2);
465}
466
233a88ad
PE
467static inline size_t
468hash_symbol (const symbol *m, size_t tablesize)
72a23c97 469{
95612cfa 470 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
471 return ((uintptr_t) m->tag) % tablesize;
472}
473
233a88ad
PE
474static size_t
475hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
476{
477 return hash_symbol (m, tablesize);
72a23c97
AD
478}
479
480
481/*-------------------------------.
2f1afb73 482| Create the symbol hash table. |
72a23c97
AD
483`-------------------------------*/
484
485void
db8837cb 486symbols_new (void)
72a23c97 487{
db8837cb 488 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
72a23c97 489 NULL,
0fb1efaf
PE
490 hash_symbol_hasher,
491 hash_symbol_comparator,
492 free);
40675e7c
DM
493}
494
495
1e9798d5
AD
496/*----------------------------------------------------------------.
497| Find the symbol named KEY, and return it. If it does not exist |
498| yet, create it. |
499`----------------------------------------------------------------*/
500
17ee7397
PE
501symbol *
502symbol_get (const char *key, location loc)
40675e7c 503{
17ee7397
PE
504 symbol probe;
505 symbol *entry;
40675e7c 506
ca407bdf 507 key = uniqstr_new (key);
0fb1efaf 508 probe.tag = key;
db8837cb 509 entry = hash_lookup (symbol_table, &probe);
40675e7c 510
72a23c97 511 if (!entry)
40675e7c 512 {
72a23c97 513 /* First insertion in the hash. */
17ee7397 514 entry = symbol_new (key, loc);
db8837cb 515 hash_insert (symbol_table, entry);
40675e7c 516 }
72a23c97
AD
517 return entry;
518}
40675e7c 519
40675e7c 520
39f41916
AD
521/*------------------------------------------------------------------.
522| Generate a dummy nonterminal, whose name cannot conflict with the |
523| user's names. |
524`------------------------------------------------------------------*/
525
17ee7397
PE
526symbol *
527dummy_symbol_get (location loc)
39f41916
AD
528{
529 /* Incremented for each generated symbol. */
530 static int dummy_count = 0;
531 static char buf[256];
532
17ee7397 533 symbol *sym;
39f41916
AD
534
535 sprintf (buf, "@%d", ++dummy_count);
17ee7397 536 sym = symbol_get (buf, loc);
39f41916
AD
537 sym->class = nterm_sym;
538 sym->number = nvars++;
539 return sym;
540}
541
542
72a23c97 543/*-------------------.
db8837cb 544| Free the symbols. |
72a23c97
AD
545`-------------------*/
546
547void
db8837cb 548symbols_free (void)
72a23c97 549{
db8837cb 550 hash_free (symbol_table);
536545f3 551 free (symbols);
40675e7c
DM
552}
553
554
72a23c97 555/*---------------------------------------------------------------.
db8837cb 556| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
557| terminals. |
558`---------------------------------------------------------------*/
559
0fb1efaf
PE
560static void
561symbols_do (Hash_processor processor, void *processor_data)
40675e7c 562{
0fb1efaf 563 hash_do_for_each (symbol_table, processor, processor_data);
40675e7c 564}
2f1afb73
AD
565
566
567/*--------------------------------------------------------------.
568| Check that all the symbols are defined. Report any undefined |
569| symbols and consider them nonterminals. |
570`--------------------------------------------------------------*/
571
572void
573symbols_check_defined (void)
574{
0fb1efaf 575 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
576}
577
578/*------------------------------------------------------------------.
579| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
580| number. |
581`------------------------------------------------------------------*/
582
583static void
584symbols_token_translations_init (void)
585{
a3714bce 586 bool num_256_available_p = true;
2f1afb73
AD
587 int i;
588
589 /* Find the highest user token number, and whether 256, the POSIX
590 preferred user token number for the error token, is used. */
591 max_user_token_number = 0;
592 for (i = 0; i < ntokens; ++i)
593 {
17ee7397 594 symbol *this = symbols[i];
2f1afb73
AD
595 if (this->user_token_number != USER_NUMBER_UNDEFINED)
596 {
597 if (this->user_token_number > max_user_token_number)
598 max_user_token_number = this->user_token_number;
599 if (this->user_token_number == 256)
a3714bce 600 num_256_available_p = false;
2f1afb73
AD
601 }
602 }
603
604 /* If 256 is not used, assign it to error, to follow POSIX. */
605 if (num_256_available_p
606 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
607 errtoken->user_token_number = 256;
608
609 /* Set the missing user numbers. */
610 if (max_user_token_number < 256)
611 max_user_token_number = 256;
612
613 for (i = 0; i < ntokens; ++i)
614 {
17ee7397 615 symbol *this = symbols[i];
2f1afb73
AD
616 if (this->user_token_number == USER_NUMBER_UNDEFINED)
617 this->user_token_number = ++max_user_token_number;
618 if (this->user_token_number > max_user_token_number)
619 max_user_token_number = this->user_token_number;
620 }
621
da2a7671
PE
622 token_translations = xnmalloc (max_user_token_number + 1,
623 sizeof *token_translations);
2f1afb73
AD
624
625 /* Initialize all entries for literal tokens to 2, the internal
88bce5a2
AD
626 token number for $undefined, which represents all invalid inputs.
627 */
2f1afb73
AD
628 for (i = 0; i < max_user_token_number + 1; i++)
629 token_translations[i] = undeftoken->number;
0fb1efaf 630 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
631}
632
633
634/*----------------------------------------------------------------.
635| Assign symbol numbers, and write definition of token names into |
636| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
637`----------------------------------------------------------------*/
638
639void
640symbols_pack (void)
641{
da2a7671 642 symbols = xcalloc (nsyms, sizeof *symbols);
2f1afb73 643
0fb1efaf
PE
644 symbols_do (symbol_check_alias_consistency_processor, NULL);
645 symbols_do (symbol_pack_processor, NULL);
2f1afb73
AD
646
647 symbols_token_translations_init ();
648
649 if (startsymbol->class == unknown_sym)
ee000ba4 650 fatal_at (startsymbol_location,
dafdc66f 651 _("the start symbol %s is undefined"),
97650f4e 652 startsymbol->tag);
2f1afb73 653 else if (startsymbol->class == token_sym)
ee000ba4 654 fatal_at (startsymbol_location,
dafdc66f 655 _("the start symbol %s is a token"),
97650f4e 656 startsymbol->tag);
2f1afb73 657}