]> git.saurik.com Git - bison.git/blame - src/symtab.c
tests: skip C++ tests that are too demanding for some compilers
[bison.git] / src / symtab.c
CommitLineData
0fb1efaf
PE
1/* Symbol table manager for Bison.
2
7d6bad19 3 Copyright (C) 1984, 1989, 2000-2002, 2004-2013 Free Software
575619af 4 Foundation, Inc.
40675e7c 5
95e36146 6 This file is part of Bison, the GNU Compiler Compiler.
40675e7c 7
f16b0819 8 This program is free software: you can redistribute it and/or modify
95e36146 9 it under the terms of the GNU General Public License as published by
f16b0819
PE
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
40675e7c 12
f16b0819 13 This program is distributed in the hope that it will be useful,
95e36146
AD
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
40675e7c 17
95e36146 18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
40675e7c 20
2cec9080 21#include <config.h>
40675e7c 22#include "system.h"
17ee7397
PE
23
24#include <hash.h>
17ee7397 25
2f1afb73 26#include "complain.h"
40675e7c 27#include "gram.h"
17ee7397 28#include "symtab.h"
40675e7c 29
83b60c97
JD
30/*-------------------------------------------------------------------.
31| Symbols sorted by tag. Allocated by the first invocation of |
32| symbols_do, after which no more symbols should be created. |
33`-------------------------------------------------------------------*/
34
35static symbol **symbols_sorted = NULL;
9641b918 36static symbol **semantic_types_sorted = NULL;
83b60c97 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
284bc49c
VT
49/*---------------------------.
50| Precedence relation graph. |
51`---------------------------*/
52
53static symgraph **prec_nodes;
ec5479ce 54
e8f7155d
VT
55/*-----------------------------------.
56| Store which associativity is used. |
57`-----------------------------------*/
58
59bool *used_assoc = NULL;
60
72a23c97
AD
61/*---------------------------------.
62| Create a new symbol, named TAG. |
63`---------------------------------*/
1e9798d5 64
17ee7397
PE
65static symbol *
66symbol_new (uniqstr tag, location loc)
1e9798d5 67{
da2a7671 68 symbol *res = xmalloc (sizeof *res);
17ee7397 69 uniqstr_assert (tag);
4f646c37
AD
70
71 /* If the tag is not a string (starts with a double quote), check
72 that it is valid for Yacc. */
84526bf3 73 if (tag[0] != '\"' && tag[0] != '\'' && strchr (tag, '-'))
bb8e56ff
TR
74 complain (&loc, Wyacc,
75 _("POSIX Yacc forbids dashes in symbol names: %s"), tag);
4f646c37 76
95612cfa 77 res->tag = tag;
17ee7397 78 res->location = loc;
24c0aad7 79
1e9798d5 80 res->type_name = NULL;
c5ae8e85
AD
81 {
82 int i;
83 for (i = 0; i < CODE_PROPS_SIZE; ++i)
84 code_props_none_init (&res->props[i]);
85 }
24c0aad7 86
5fbb0954 87 res->number = NUMBER_UNDEFINED;
1e9798d5 88 res->prec = 0;
a945ec39 89 res->assoc = undef_assoc;
b87f8b21 90 res->user_token_number = USER_NUMBER_UNDEFINED;
260008e5 91
1e9798d5
AD
92 res->alias = NULL;
93 res->class = unknown_sym;
3b0b682f 94 res->status = undeclared;
1e9798d5 95
3239db74 96 if (nsyms == SYMBOL_NUMBER_MAXIMUM)
bb8e56ff 97 complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
6fb8b256 98 SYMBOL_NUMBER_MAXIMUM);
6d0ef4ec 99 nsyms++;
1e9798d5
AD
100 return res;
101}
102
6a0655d9 103char const *
71da68b3
VS
104code_props_type_string (code_props_type kind)
105{
106 switch (kind)
107 {
108 case destructor:
109 return "%destructor";
110 case printer:
111 return "%printer";
112 }
113 assert (0);
114}
115
b2a0b7ca
JD
116/*----------------------------------------.
117| Create a new semantic type, named TAG. |
118`----------------------------------------*/
119
120static semantic_type *
9641b918 121semantic_type_new (uniqstr tag, const location *loc)
b2a0b7ca
JD
122{
123 semantic_type *res = xmalloc (sizeof *res);
124
125 uniqstr_assert (tag);
126 res->tag = tag;
e96b1b2c
TR
127 res->location = loc ? *loc : empty_location;
128 res->status = undeclared;
c5ae8e85
AD
129 {
130 int i;
131 for (i = 0; i < CODE_PROPS_SIZE; ++i)
132 code_props_none_init (&res->props[i]);
133 }
b2a0b7ca
JD
134
135 return res;
136}
137
40675e7c 138
867a3e00
AD
139/*-----------------.
140| Print a symbol. |
141`-----------------*/
142
e9690142
JD
143#define SYMBOL_ATTR_PRINT(Attr) \
144 if (s->Attr) \
ab703f2c 145 fprintf (f, " %s { %s }", #Attr, s->Attr)
867a3e00 146
71da68b3
VS
147#define SYMBOL_CODE_PRINT(Attr) \
148 if (s->props[Attr].code) \
149 fprintf (f, " %s { %s }", #Attr, s->props[Attr].code)
95021767 150
867a3e00 151void
c5289832 152symbol_print (symbol const *s, FILE *f)
867a3e00 153{
affac613
AD
154 if (s)
155 {
848bcc28 156 fputs (s->tag, f);
affac613 157 SYMBOL_ATTR_PRINT (type_name);
95021767
JD
158 SYMBOL_CODE_PRINT (destructor);
159 SYMBOL_CODE_PRINT (printer);
affac613
AD
160 }
161 else
848bcc28 162 fputs ("<NULL>", f);
867a3e00
AD
163}
164
165#undef SYMBOL_ATTR_PRINT
95021767 166#undef SYMBOL_CODE_PRINT
867a3e00 167
aea10ef4
AD
168
169/*----------------------------------.
170| Whether S is a valid identifier. |
171`----------------------------------*/
172
173static bool
174is_identifier (uniqstr s)
175{
176 static char const alphanum[26 + 26 + 1 + 10] =
177 "abcdefghijklmnopqrstuvwxyz"
178 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
179 "_"
180 "0123456789";
181 if (!s || ! memchr (alphanum, *s, sizeof alphanum - 10))
182 return false;
183 for (++s; *s; ++s)
184 if (! memchr (alphanum, *s, sizeof alphanum))
185 return false;
186 return true;
187}
188
189
190/*-----------------------------------------------.
191| Get the identifier associated to this symbol. |
192`-----------------------------------------------*/
193uniqstr
194symbol_id_get (symbol const *sym)
195{
dfaa4860 196 aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
aea10ef4
AD
197 if (sym->alias)
198 sym = sym->alias;
199 return is_identifier (sym->tag) ? sym->tag : 0;
200}
201
202
df09ef2e
AD
203/*------------------------------------------------------------------.
204| Complain that S's WHAT is redeclared at SECOND, and was first set |
205| at FIRST. |
206`------------------------------------------------------------------*/
207
208static void
b2a0b7ca
JD
209symbol_redeclaration (symbol *s, const char *what, location first,
210 location second)
df09ef2e 211{
cbaea010 212 unsigned i = 0;
b999409e
TR
213 complain_indent (&second, complaint, &i,
214 _("%s redeclaration for %s"), what, s->tag);
cbaea010 215 i += SUB_INDENT;
b999409e
TR
216 complain_indent (&first, complaint, &i,
217 _("previous declaration"));
df09ef2e
AD
218}
219
b2a0b7ca
JD
220static void
221semantic_type_redeclaration (semantic_type *s, const char *what, location first,
222 location second)
223{
cbaea010 224 unsigned i = 0;
b999409e
TR
225 complain_indent (&second, complaint, &i,
226 _("%s redeclaration for <%s>"), what, s->tag);
cbaea010 227 i += SUB_INDENT;
b999409e
TR
228 complain_indent (&first, complaint, &i,
229 _("previous declaration"));
b2a0b7ca
JD
230}
231
df09ef2e 232
12cf133f 233
17ee7397
PE
234/*-----------------------------------------------------------------.
235| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
236| as TYPE_NAME. |
237`-----------------------------------------------------------------*/
3ae2b51f
AD
238
239void
17ee7397 240symbol_type_set (symbol *sym, uniqstr type_name, location loc)
3ae2b51f 241{
e9955c83
AD
242 if (type_name)
243 {
17ee7397 244 if (sym->type_name)
e9690142 245 symbol_redeclaration (sym, "%type", sym->type_location, loc);
f249e803
AD
246 else
247 {
248 uniqstr_assert (type_name);
249 sym->type_name = type_name;
250 sym->type_location = loc;
251 }
e9955c83 252 }
3ae2b51f
AD
253}
254
71da68b3
VS
255/*--------------------------------------------------------.
256| Set the DESTRUCTOR or PRINTER associated with the SYM. |
257`--------------------------------------------------------*/
366eea36
AD
258
259void
71da68b3
VS
260symbol_code_props_set (symbol *sym, code_props_type kind,
261 code_props const *code)
366eea36 262{
71da68b3
VS
263 if (sym->props[kind].code)
264 symbol_redeclaration (sym, code_props_type_string (kind),
265 sym->props[kind].location,
266 code->location);
f249e803
AD
267 else
268 sym->props[kind] = *code;
366eea36
AD
269}
270
71da68b3
VS
271/*-----------------------------------------------------.
272| Set the DESTRUCTOR or PRINTER associated with TYPE. |
273`-----------------------------------------------------*/
b2a0b7ca
JD
274
275void
71da68b3
VS
276semantic_type_code_props_set (semantic_type *type,
277 code_props_type kind,
278 code_props const *code)
b2a0b7ca 279{
71da68b3
VS
280 if (type->props[kind].code)
281 semantic_type_redeclaration (type, code_props_type_string (kind),
282 type->props[kind].location,
283 code->location);
f249e803
AD
284 else
285 type->props[kind] = *code;
b2a0b7ca
JD
286}
287
71da68b3
VS
288/*---------------------------------------------------.
289| Get the computed %destructor or %printer for SYM. |
290`---------------------------------------------------*/
ec5479ce 291
70946cff
AD
292code_props *
293symbol_code_props_get (symbol *sym, code_props_type kind)
ec5479ce 294{
71da68b3
VS
295 /* Per-symbol code props. */
296 if (sym->props[kind].code)
297 return &sym->props[kind];
9350499c 298
71da68b3 299 /* Per-type code props. */
b2a0b7ca
JD
300 if (sym->type_name)
301 {
70946cff 302 code_props *code =
9641b918 303 &semantic_type_get (sym->type_name, NULL)->props[kind];
71da68b3
VS
304 if (code->code)
305 return code;
b2a0b7ca
JD
306 }
307
71da68b3 308 /* Apply default code props's only to user-defined symbols. */
9534d2be
AD
309 if (sym->tag[0] != '$' && sym != errtoken)
310 {
311 code_props *code =
312 &semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind];
313 if (code->code)
314 return code;
315 }
316 return &code_props_none;
ec5479ce
JD
317}
318
17ee7397
PE
319/*-----------------------------------------------------------------.
320| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
321| with UNDEF_ASSOC as ASSOC. |
322`-----------------------------------------------------------------*/
3ae2b51f
AD
323
324void
17ee7397 325symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
3ae2b51f 326{
17ee7397 327 if (a != undef_assoc)
e9955c83 328 {
d8ce7031 329 if (sym->prec)
e9690142 330 symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
b2a0b7ca 331 loc);
d8ce7031
AD
332 else
333 {
334 sym->prec = prec;
335 sym->assoc = a;
336 sym->prec_location = loc;
337 }
e9955c83
AD
338 }
339
340 /* Only terminals have a precedence. */
073f9288 341 symbol_class_set (sym, token_sym, loc, false);
3ae2b51f
AD
342}
343
344
17ee7397
PE
345/*------------------------------------.
346| Set the CLASS associated with SYM. |
347`------------------------------------*/
44536b35
AD
348
349void
073f9288 350symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
44536b35 351{
3b0b682f 352 bool warned = false;
17ee7397 353 if (sym->class != unknown_sym && sym->class != class)
073f9288 354 {
bb8e56ff 355 complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
c5ae8e85 356 /* Don't report both "redefined" and "redeclared". */
3b0b682f 357 warned = true;
073f9288 358 }
44536b35 359
17ee7397
PE
360 if (class == nterm_sym && sym->class != nterm_sym)
361 sym->number = nvars++;
6d0ef4ec 362 else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
17ee7397 363 sym->number = ntokens++;
44536b35 364
17ee7397 365 sym->class = class;
073f9288
PE
366
367 if (declaring)
368 {
3b0b682f 369 if (sym->status == declared && !warned)
bb8e56ff 370 complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
f249e803
AD
371 else
372 sym->status = declared;
073f9288 373 }
44536b35
AD
374}
375
376
17ee7397
PE
377/*------------------------------------------------.
378| Set the USER_TOKEN_NUMBER associated with SYM. |
379`------------------------------------------------*/
44536b35
AD
380
381void
17ee7397 382symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
44536b35 383{
1f6b3679
JD
384 int *user_token_numberp;
385
dfaa4860 386 if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
1f6b3679
JD
387 user_token_numberp = &sym->user_token_number;
388 else
389 user_token_numberp = &sym->alias->user_token_number;
390 if (*user_token_numberp != USER_NUMBER_UNDEFINED
391 && *user_token_numberp != user_token_number)
bb8e56ff
TR
392 complain (&loc, complaint, _("redefining user token number of %s"),
393 sym->tag);
44536b35 394
1f6b3679 395 *user_token_numberp = user_token_number;
88bce5a2 396 /* User defined $end token? */
44536b35
AD
397 if (user_token_number == 0)
398 {
17ee7397 399 endtoken = sym;
44536b35 400 /* It is always mapped to 0, so it was already counted in
e9690142 401 NTOKENS. */
1f36f544
JD
402 if (endtoken->number != NUMBER_UNDEFINED)
403 --ntokens;
404 endtoken->number = 0;
44536b35
AD
405 }
406}
407
408
17ee7397
PE
409/*----------------------------------------------------------.
410| If SYM is not defined, report an error, and consider it a |
411| nonterminal. |
412`----------------------------------------------------------*/
2f1afb73 413
0fb1efaf 414static inline bool
17ee7397 415symbol_check_defined (symbol *sym)
2f1afb73 416{
17ee7397 417 if (sym->class == unknown_sym)
2f1afb73 418 {
31557b9e 419 assert (sym->status != declared);
bb8e56ff
TR
420 complain (&sym->location,
421 sym->status == needed ? complaint : Wother,
422 _("symbol %s is used, but is not defined as a token"
423 " and has no rules"),
424 sym->tag);
17ee7397
PE
425 sym->class = nterm_sym;
426 sym->number = nvars++;
2f1afb73
AD
427 }
428
c5ae8e85
AD
429 {
430 int i;
431 for (i = 0; i < 2; ++i)
432 symbol_code_props_get (sym, i)->is_used = true;
433 }
ea9a35c6 434
9641b918
VS
435 /* Set the semantic type status associated to the current symbol to
436 'declared' so that we could check semantic types unnecessary uses. */
437 if (sym->type_name)
438 {
439 semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
440 if (sem_type)
441 sem_type->status = declared;
442 }
443
444 return true;
445}
446
447static inline bool
448semantic_type_check_defined (semantic_type *sem_type)
449{
c5ae8e85 450 /* <*> and <> do not have to be "declared". */
9534d2be
AD
451 if (sem_type->status == declared
452 || !*sem_type->tag
c0ef22ab 453 || STREQ (sem_type->tag, "*"))
ea9a35c6 454 {
c5ae8e85
AD
455 int i;
456 for (i = 0; i < 2; ++i)
ea9a35c6
VS
457 if (sem_type->props[i].kind != CODE_PROPS_NONE
458 && ! sem_type->props[i].is_used)
bb8e56ff
TR
459 complain (&sem_type->location, Wother,
460 _("useless %s for type <%s>"),
461 code_props_type_string (i), sem_type->tag);
ea9a35c6
VS
462 }
463 else
bb8e56ff
TR
464 complain (&sem_type->location, Wother,
465 _("type <%s> is used, but is not associated to any symbol"),
466 sem_type->tag);
9641b918 467
a3714bce 468 return true;
2f1afb73
AD
469}
470
0fb1efaf
PE
471static bool
472symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
473{
474 return symbol_check_defined (sym);
475}
476
9641b918
VS
477static bool
478semantic_type_check_defined_processor (void *sem_type,
479 void *null ATTRIBUTE_UNUSED)
480{
481 return semantic_type_check_defined (sem_type);
482}
483
2f1afb73 484
2f1afb73 485void
dfaa4860 486symbol_make_alias (symbol *sym, symbol *str, location loc)
2f1afb73 487{
dfaa4860 488 if (str->alias)
bb8e56ff 489 complain (&loc, Wother,
6fb8b256 490 _("symbol %s used more than once as a literal string"), str->tag);
17ee7397 491 else if (sym->alias)
bb8e56ff 492 complain (&loc, Wother,
6fb8b256 493 _("symbol %s given more than one literal string"), sym->tag);
2f1afb73
AD
494 else
495 {
dfaa4860
JD
496 str->class = token_sym;
497 str->user_token_number = sym->user_token_number;
498 sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
499 str->alias = sym;
500 sym->alias = str;
501 str->number = sym->number;
502 symbol_type_set (str, sym->type_name, loc);
2f1afb73
AD
503 }
504}
505
506
507/*---------------------------------------------------------.
508| Check that THIS, and its alias, have same precedence and |
509| associativity. |
510`---------------------------------------------------------*/
511
df09ef2e 512static inline void
0fb1efaf 513symbol_check_alias_consistency (symbol *this)
2f1afb73 514{
dfaa4860 515 symbol *sym = this;
b143f404 516 symbol *str = this->alias;
df09ef2e 517
dfaa4860
JD
518 /* Check only the symbol in the symbol-string pair. */
519 if (!(this->alias
520 && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
df09ef2e
AD
521 return;
522
dfaa4860 523 if (str->type_name != sym->type_name)
2f1afb73 524 {
dfaa4860 525 if (str->type_name)
e9690142 526 symbol_type_set (sym, str->type_name, str->type_location);
df09ef2e 527 else
e9690142 528 symbol_type_set (str, sym->type_name, sym->type_location);
df09ef2e 529 }
2f1afb73 530
df09ef2e 531
c5ae8e85
AD
532 {
533 int i;
534 for (i = 0; i < CODE_PROPS_SIZE; ++i)
535 if (str->props[i].code)
536 symbol_code_props_set (sym, i, &str->props[i]);
537 else if (sym->props[i].code)
538 symbol_code_props_set (str, i, &sym->props[i]);
539 }
df09ef2e 540
dfaa4860 541 if (sym->prec || str->prec)
df09ef2e 542 {
dfaa4860 543 if (str->prec)
e9690142
JD
544 symbol_precedence_set (sym, str->prec, str->assoc,
545 str->prec_location);
df09ef2e 546 else
e9690142
JD
547 symbol_precedence_set (str, sym->prec, sym->assoc,
548 sym->prec_location);
2f1afb73 549 }
2f1afb73
AD
550}
551
0fb1efaf
PE
552static bool
553symbol_check_alias_consistency_processor (void *this,
e9690142 554 void *null ATTRIBUTE_UNUSED)
0fb1efaf 555{
df09ef2e
AD
556 symbol_check_alias_consistency (this);
557 return true;
0fb1efaf
PE
558}
559
2f1afb73
AD
560
561/*-------------------------------------------------------------------.
562| Assign a symbol number, and write the definition of the token name |
563| into FDEFINES. Put in SYMBOLS. |
564`-------------------------------------------------------------------*/
565
0fb1efaf 566static inline bool
17ee7397 567symbol_pack (symbol *this)
2f1afb73 568{
f74d6d25 569 aver (this->number != NUMBER_UNDEFINED);
2f1afb73 570 if (this->class == nterm_sym)
f74d6d25
JD
571 this->number += ntokens;
572 else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
573 return true;
2f1afb73
AD
574
575 symbols[this->number] = this;
a3714bce 576 return true;
2f1afb73
AD
577}
578
0fb1efaf
PE
579static bool
580symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
581{
582 return symbol_pack (this);
583}
584
2f1afb73 585
12cf133f
AD
586static void
587user_token_number_redeclaration (int num, symbol *first, symbol *second)
588{
cbaea010 589 unsigned i = 0;
12cf133f 590 /* User token numbers are not assigned during the parsing, but in a
83b60c97 591 second step, via a traversal of the symbol table sorted on tag.
2f1afb73 592
83b60c97
JD
593 However, error messages make more sense if we keep the first
594 declaration first. */
12cf133f
AD
595 if (location_cmp (first->location, second->location) > 0)
596 {
597 symbol* tmp = first;
598 first = second;
599 second = tmp;
600 }
b999409e
TR
601 complain_indent (&second->location, complaint, &i,
602 _("user token number %d redeclaration for %s"),
603 num, second->tag);
b506d9bf 604 i += SUB_INDENT;
b999409e
TR
605 complain_indent (&first->location, complaint, &i,
606 _("previous declaration for %s"),
607 first->tag);
12cf133f 608}
2f1afb73
AD
609
610/*--------------------------------------------------.
611| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
612`--------------------------------------------------*/
613
0fb1efaf 614static inline bool
17ee7397 615symbol_translation (symbol *this)
2f1afb73
AD
616{
617 /* Non-terminal? */
618 if (this->class == token_sym
dfaa4860 619 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
2f1afb73
AD
620 {
621 /* A token which translation has already been set? */
622 if (token_translations[this->user_token_number] != undeftoken->number)
e9690142 623 user_token_number_redeclaration
12cf133f
AD
624 (this->user_token_number,
625 symbols[token_translations[this->user_token_number]],
626 this);
f249e803
AD
627 else
628 token_translations[this->user_token_number] = this->number;
2f1afb73 629 }
9553083c 630
a3714bce 631 return true;
2f1afb73
AD
632}
633
0fb1efaf
PE
634static bool
635symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
636{
637 return symbol_translation (this);
638}
639
72a23c97 640
b2a0b7ca
JD
641/*---------------------------------------.
642| Symbol and semantic type hash tables. |
643`---------------------------------------*/
40675e7c 644
b2a0b7ca 645/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
646#define HT_INITIAL_CAPACITY 257
647
db8837cb 648static struct hash_table *symbol_table = NULL;
b2a0b7ca 649static struct hash_table *semantic_type_table = NULL;
72a23c97 650
0fb1efaf 651static inline bool
17ee7397 652hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 653{
95612cfa 654 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 655 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
656}
657
b2a0b7ca
JD
658static inline bool
659hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
660{
661 /* Since names are unique, we can compare the pointers themselves. */
662 return UNIQSTR_EQ (m1->tag, m2->tag);
663}
664
0fb1efaf
PE
665static bool
666hash_symbol_comparator (void const *m1, void const *m2)
667{
668 return hash_compare_symbol (m1, m2);
669}
670
b2a0b7ca
JD
671static bool
672hash_semantic_type_comparator (void const *m1, void const *m2)
673{
674 return hash_compare_semantic_type (m1, m2);
675}
676
233a88ad
PE
677static inline size_t
678hash_symbol (const symbol *m, size_t tablesize)
72a23c97 679{
95612cfa 680 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
681 return ((uintptr_t) m->tag) % tablesize;
682}
683
b2a0b7ca
JD
684static inline size_t
685hash_semantic_type (const semantic_type *m, size_t tablesize)
686{
687 /* Since names are unique, we can hash the pointer itself. */
688 return ((uintptr_t) m->tag) % tablesize;
689}
690
233a88ad
PE
691static size_t
692hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
693{
694 return hash_symbol (m, tablesize);
72a23c97
AD
695}
696
b2a0b7ca
JD
697static size_t
698hash_semantic_type_hasher (void const *m, size_t tablesize)
699{
700 return hash_semantic_type (m, tablesize);
701}
72a23c97
AD
702
703/*-------------------------------.
2f1afb73 704| Create the symbol hash table. |
72a23c97
AD
705`-------------------------------*/
706
707void
db8837cb 708symbols_new (void)
72a23c97 709{
db8837cb 710 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
711 NULL,
712 hash_symbol_hasher,
713 hash_symbol_comparator,
714 free);
b2a0b7ca 715 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
716 NULL,
717 hash_semantic_type_hasher,
718 hash_semantic_type_comparator,
719 free);
40675e7c
DM
720}
721
722
1e9798d5
AD
723/*----------------------------------------------------------------.
724| Find the symbol named KEY, and return it. If it does not exist |
725| yet, create it. |
726`----------------------------------------------------------------*/
727
17ee7397 728symbol *
203b9274 729symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 730{
17ee7397
PE
731 symbol probe;
732 symbol *entry;
40675e7c 733
0fb1efaf 734 probe.tag = key;
db8837cb 735 entry = hash_lookup (symbol_table, &probe);
40675e7c 736
72a23c97 737 if (!entry)
40675e7c 738 {
72a23c97 739 /* First insertion in the hash. */
83b60c97 740 aver (!symbols_sorted);
17ee7397 741 entry = symbol_new (key, loc);
92d7a23a
AD
742 if (!hash_insert (symbol_table, entry))
743 xalloc_die ();
40675e7c 744 }
72a23c97
AD
745 return entry;
746}
40675e7c 747
40675e7c 748
b2a0b7ca
JD
749/*-----------------------------------------------------------------------.
750| Find the semantic type named KEY, and return it. If it does not exist |
751| yet, create it. |
752`-----------------------------------------------------------------------*/
753
754semantic_type *
9641b918 755semantic_type_from_uniqstr (const uniqstr key, const location *loc)
b2a0b7ca
JD
756{
757 semantic_type probe;
758 semantic_type *entry;
759
760 probe.tag = key;
761 entry = hash_lookup (semantic_type_table, &probe);
762
763 if (!entry)
764 {
765 /* First insertion in the hash. */
9641b918 766 entry = semantic_type_new (key, loc);
92d7a23a
AD
767 if (!hash_insert (semantic_type_table, entry))
768 xalloc_die ();
b2a0b7ca
JD
769 }
770 return entry;
771}
772
773
203b9274
AD
774/*----------------------------------------------------------------.
775| Find the symbol named KEY, and return it. If it does not exist |
776| yet, create it. |
777`----------------------------------------------------------------*/
778
779symbol *
780symbol_get (const char *key, location loc)
781{
782 return symbol_from_uniqstr (uniqstr_new (key), loc);
783}
784
785
b2a0b7ca
JD
786/*-----------------------------------------------------------------------.
787| Find the semantic type named KEY, and return it. If it does not exist |
788| yet, create it. |
789`-----------------------------------------------------------------------*/
790
791semantic_type *
9641b918 792semantic_type_get (const char *key, const location *loc)
b2a0b7ca 793{
9641b918 794 return semantic_type_from_uniqstr (uniqstr_new (key), loc);
b2a0b7ca
JD
795}
796
797
39f41916
AD
798/*------------------------------------------------------------------.
799| Generate a dummy nonterminal, whose name cannot conflict with the |
800| user's names. |
801`------------------------------------------------------------------*/
802
17ee7397
PE
803symbol *
804dummy_symbol_get (location loc)
39f41916
AD
805{
806 /* Incremented for each generated symbol. */
807 static int dummy_count = 0;
808 static char buf[256];
809
17ee7397 810 symbol *sym;
39f41916 811
f91b1629 812 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 813 sym = symbol_get (buf, loc);
39f41916
AD
814 sym->class = nterm_sym;
815 sym->number = nvars++;
816 return sym;
817}
818
4d7370cb
JD
819bool
820symbol_is_dummy (const symbol *sym)
821{
f91b1629 822 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 823}
39f41916 824
72a23c97 825/*-------------------.
db8837cb 826| Free the symbols. |
72a23c97
AD
827`-------------------*/
828
829void
db8837cb 830symbols_free (void)
72a23c97 831{
db8837cb 832 hash_free (symbol_table);
b2a0b7ca 833 hash_free (semantic_type_table);
536545f3 834 free (symbols);
83b60c97 835 free (symbols_sorted);
ae9c90ba 836 free (semantic_types_sorted);
40675e7c
DM
837}
838
839
72a23c97 840/*---------------------------------------------------------------.
db8837cb 841| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
842| terminals. |
843`---------------------------------------------------------------*/
844
83b60c97
JD
845static int
846symbols_cmp (symbol const *a, symbol const *b)
847{
848 return strcmp (a->tag, b->tag);
849}
850
851static int
852symbols_cmp_qsort (void const *a, void const *b)
853{
854 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
855}
856
0fb1efaf 857static void
dfe292c6 858symbols_do (Hash_processor processor, void *processor_data,
ae9c90ba 859 struct hash_table *table, symbol ***sorted)
40675e7c 860{
dfe292c6 861 size_t count = hash_get_n_entries (table);
ae9c90ba 862 if (!*sorted)
83b60c97 863 {
ae9c90ba
TR
864 *sorted = xnmalloc (count, sizeof **sorted);
865 hash_get_entries (table, (void**)*sorted, count);
866 qsort (*sorted, count, sizeof **sorted, symbols_cmp_qsort);
83b60c97
JD
867 }
868 {
869 size_t i;
870 for (i = 0; i < count; ++i)
ae9c90ba 871 processor ((*sorted)[i], processor_data);
83b60c97 872 }
40675e7c 873}
2f1afb73 874
2f1afb73
AD
875/*--------------------------------------------------------------.
876| Check that all the symbols are defined. Report any undefined |
877| symbols and consider them nonterminals. |
878`--------------------------------------------------------------*/
879
880void
881symbols_check_defined (void)
882{
dfe292c6 883 symbols_do (symbol_check_defined_processor, NULL,
ae9c90ba 884 symbol_table, &symbols_sorted);
9641b918 885 symbols_do (semantic_type_check_defined_processor, NULL,
ae9c90ba 886 semantic_type_table, &semantic_types_sorted);
2f1afb73
AD
887}
888
889/*------------------------------------------------------------------.
890| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
891| number. |
892`------------------------------------------------------------------*/
893
894static void
895symbols_token_translations_init (void)
896{
a3714bce 897 bool num_256_available_p = true;
2f1afb73
AD
898 int i;
899
900 /* Find the highest user token number, and whether 256, the POSIX
901 preferred user token number for the error token, is used. */
902 max_user_token_number = 0;
903 for (i = 0; i < ntokens; ++i)
904 {
17ee7397 905 symbol *this = symbols[i];
2f1afb73 906 if (this->user_token_number != USER_NUMBER_UNDEFINED)
e9690142
JD
907 {
908 if (this->user_token_number > max_user_token_number)
909 max_user_token_number = this->user_token_number;
910 if (this->user_token_number == 256)
911 num_256_available_p = false;
912 }
2f1afb73
AD
913 }
914
915 /* If 256 is not used, assign it to error, to follow POSIX. */
916 if (num_256_available_p
917 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
918 errtoken->user_token_number = 256;
919
920 /* Set the missing user numbers. */
921 if (max_user_token_number < 256)
922 max_user_token_number = 256;
923
924 for (i = 0; i < ntokens; ++i)
925 {
17ee7397 926 symbol *this = symbols[i];
2f1afb73 927 if (this->user_token_number == USER_NUMBER_UNDEFINED)
e9690142 928 this->user_token_number = ++max_user_token_number;
2f1afb73 929 if (this->user_token_number > max_user_token_number)
e9690142 930 max_user_token_number = this->user_token_number;
2f1afb73
AD
931 }
932
da2a7671 933 token_translations = xnmalloc (max_user_token_number + 1,
e9690142 934 sizeof *token_translations);
2f1afb73 935
b3a28fd4
AD
936 /* Initialize all entries for literal tokens to the internal token
937 number for $undefined, which represents all invalid inputs. */
2f1afb73
AD
938 for (i = 0; i < max_user_token_number + 1; i++)
939 token_translations[i] = undeftoken->number;
dfe292c6 940 symbols_do (symbol_translation_processor, NULL,
ae9c90ba 941 symbol_table, &symbols_sorted);
2f1afb73
AD
942}
943
944
945/*----------------------------------------------------------------.
946| Assign symbol numbers, and write definition of token names into |
947| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
948`----------------------------------------------------------------*/
949
950void
951symbols_pack (void)
952{
dfe292c6 953 symbols_do (symbol_check_alias_consistency_processor, NULL,
ae9c90ba 954 symbol_table, &symbols_sorted);
6d0ef4ec
JD
955
956 symbols = xcalloc (nsyms, sizeof *symbols);
ae9c90ba 957 symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
2f1afb73 958
6d0ef4ec
JD
959 /* Aliases leave empty slots in symbols, so remove them. */
960 {
961 int writei;
962 int readi;
963 int nsyms_old = nsyms;
964 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
965 {
966 if (symbols[readi] == NULL)
967 {
968 nsyms -= 1;
969 ntokens -= 1;
970 }
971 else
972 {
973 symbols[writei] = symbols[readi];
974 symbols[writei]->number = writei;
975 if (symbols[writei]->alias)
976 symbols[writei]->alias->number = writei;
977 writei += 1;
978 }
979 }
980 }
981 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
982
2f1afb73
AD
983 symbols_token_translations_init ();
984
985 if (startsymbol->class == unknown_sym)
bb8e56ff
TR
986 complain (&startsymbol_location, fatal,
987 _("the start symbol %s is undefined"),
988 startsymbol->tag);
2f1afb73 989 else if (startsymbol->class == token_sym)
bb8e56ff
TR
990 complain (&startsymbol_location, fatal,
991 _("the start symbol %s is a token"),
992 startsymbol->tag);
2f1afb73 993}
284bc49c
VT
994
995/*---------------------------------.
996| Initialize relation graph nodes. |
997`---------------------------------*/
998
999static void
1000init_prec_nodes (void)
1001{
1002 int i;
1003 prec_nodes = xcalloc (nsyms, sizeof *prec_nodes);
1004 for (i = 0; i < nsyms; ++i)
1005 {
1006 prec_nodes[i] = xmalloc (sizeof *prec_nodes[i]);
1007 symgraph *s = prec_nodes[i];
1008 s->id = i;
1009 s->succ = 0;
1010 s->pred = 0;
1011 }
1012}
1013
1014/*----------------.
1015| Create a link. |
1016`----------------*/
1017
1018static symgraphlink *
1019symgraphlink_new (graphid id, symgraphlink *next)
1020{
1021 symgraphlink *l = xmalloc (sizeof *l);
1022 l->id = id;
1023 l->next = next;
1024 return l;
1025}
1026
1027
1028/*------------------------------------------------------------------.
1029| Register the second symbol of the precedence relation, and return |
1030| whether this relation is new. Use only in register_precedence. |
1031`------------------------------------------------------------------*/
1032
1033static bool
1034register_precedence_second_symbol (symgraphlink **first, graphid sym)
1035{
1036 if (!*first || sym < (*first)->id)
1037 *first = symgraphlink_new (sym, *first);
1038 else
1039 {
1040 symgraphlink *slist = *first;
1041
1042 while (slist->next && slist->next->id <= sym)
1043 slist = slist->next;
1044
1045 if (slist->id == sym)
1046 /* Relation already present. */
1047 return false;
1048
1049 slist->next = symgraphlink_new (sym, slist->next);
1050 }
1051 return true;
1052}
1053
1054/*------------------------------------------------------------------.
1055| Register a new relation between symbols as used. The first symbol |
1056| has a greater precedence than the second one. |
1057`------------------------------------------------------------------*/
1058
1059void
1060register_precedence (graphid first, graphid snd)
1061{
1062 if (!prec_nodes)
1063 init_prec_nodes ();
1064 register_precedence_second_symbol (&(prec_nodes[first]->succ), snd);
1065 register_precedence_second_symbol (&(prec_nodes[snd]->pred), first);
1066}
1067
1068
f038e56c
TR
1069/*---------------------------------------.
1070| Deep clear a linked / adjacency list). |
1071`---------------------------------------*/
1072
1073static void
1074linkedlist_free (symgraphlink *node)
1075{
1076 if (node)
1077 {
1078 while (node->next)
1079 {
1080 symgraphlink *tmp = node->next;
1081 free (node);
1082 node = tmp;
1083 }
1084 free (node);
1085 }
1086}
1087
1088/*----------------------------------------------.
1089| Clear and destroy association tracking table. |
1090`----------------------------------------------*/
1091
1092static void
1093assoc_free (void)
1094{
1095 int i;
1096 for (i = 0; i < nsyms; ++i)
1097 {
1098 linkedlist_free (prec_nodes[i]->pred);
1099 linkedlist_free (prec_nodes[i]->succ);
1100 free (prec_nodes[i]);
1101 }
1102 free (prec_nodes);
1103}
1104
e8f7155d
VT
1105/*---------------------------------------.
1106| Initialize association tracking table. |
1107`---------------------------------------*/
1108
1109static void
1110init_assoc (void)
1111{
1112 graphid i;
c0ef22ab 1113 used_assoc = xcalloc (nsyms, sizeof *used_assoc);
e8f7155d
VT
1114 for (i = 0; i < nsyms; ++i)
1115 used_assoc[i] = false;
1116}
1117
1118/*------------------------------------------------------------------.
1119| Test if the associativity for the symbols is defined and useless. |
1120`------------------------------------------------------------------*/
1121
1122static inline bool
1123is_assoc_useless (symbol *s)
1124{
1125 return s
1126 && s->assoc != undef_assoc
1127 && s->assoc != precedence_assoc
1128 && !used_assoc[s->number];
1129}
1130
1131/*-------------------------------.
1132| Register a used associativity. |
1133`-------------------------------*/
1134
1135void
1136register_assoc (graphid i, graphid j)
1137{
1138 if (!used_assoc)
1139 init_assoc ();
1140 used_assoc[i] = true;
1141 used_assoc[j] = true;
1142}
1143
cc2235ac
VT
1144/*--------------------------------------------------.
1145| Print a warning for unused precedence relations. |
1146`--------------------------------------------------*/
e8f7155d
VT
1147
1148void
cc2235ac 1149print_precedence_warnings (void)
e8f7155d 1150{
cc2235ac
VT
1151 int i;
1152 if (!prec_nodes)
1153 init_prec_nodes ();
e8f7155d
VT
1154 if (!used_assoc)
1155 init_assoc ();
1156 for (i = 0; i < nsyms; ++i)
1157 {
1158 symbol *s = symbols[i];
cc2235ac
VT
1159 if (s
1160 && s->prec != 0
1161 && !prec_nodes[i]->pred
1162 && !prec_nodes[i]->succ)
1163 {
1164 if (is_assoc_useless (s))
d8ce7031 1165 complain (&s->prec_location, Wprecedence,
cc2235ac
VT
1166 _("useless precedence and associativity for %s"), s->tag);
1167 else if (s->assoc == precedence_assoc)
d8ce7031 1168 complain (&s->prec_location, Wprecedence,
cc2235ac
VT
1169 _("useless precedence for %s"), s->tag);
1170 }
1171 else if (is_assoc_useless (s))
d8ce7031 1172 complain (&s->prec_location, Wprecedence,
cc2235ac 1173 _("useless associativity for %s, use %%precedence"), s->tag);
e8f7155d 1174 }
f038e56c
TR
1175 free (used_assoc);
1176 assoc_free ();
e8f7155d 1177}