]> git.saurik.com Git - bison.git/blame - src/symtab.c
warnings: introduce -Wprecedence
[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 {
156 fprintf (f, "\"%s\"", s->tag);
157 SYMBOL_ATTR_PRINT (type_name);
95021767
JD
158 SYMBOL_CODE_PRINT (destructor);
159 SYMBOL_CODE_PRINT (printer);
affac613
AD
160 }
161 else
162 fprintf (f, "<NULL>");
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);
17ee7397
PE
246 uniqstr_assert (type_name);
247 sym->type_name = type_name;
df09ef2e 248 sym->type_location = loc;
e9955c83 249 }
3ae2b51f
AD
250}
251
71da68b3
VS
252/*--------------------------------------------------------.
253| Set the DESTRUCTOR or PRINTER associated with the SYM. |
254`--------------------------------------------------------*/
366eea36
AD
255
256void
71da68b3
VS
257symbol_code_props_set (symbol *sym, code_props_type kind,
258 code_props const *code)
366eea36 259{
71da68b3
VS
260 if (sym->props[kind].code)
261 symbol_redeclaration (sym, code_props_type_string (kind),
262 sym->props[kind].location,
263 code->location);
264 sym->props[kind] = *code;
366eea36
AD
265}
266
71da68b3
VS
267/*-----------------------------------------------------.
268| Set the DESTRUCTOR or PRINTER associated with TYPE. |
269`-----------------------------------------------------*/
b2a0b7ca
JD
270
271void
71da68b3
VS
272semantic_type_code_props_set (semantic_type *type,
273 code_props_type kind,
274 code_props const *code)
b2a0b7ca 275{
71da68b3
VS
276 if (type->props[kind].code)
277 semantic_type_redeclaration (type, code_props_type_string (kind),
278 type->props[kind].location,
279 code->location);
280 type->props[kind] = *code;
b2a0b7ca
JD
281}
282
71da68b3
VS
283/*---------------------------------------------------.
284| Get the computed %destructor or %printer for SYM. |
285`---------------------------------------------------*/
ec5479ce 286
70946cff
AD
287code_props *
288symbol_code_props_get (symbol *sym, code_props_type kind)
ec5479ce 289{
71da68b3
VS
290 /* Per-symbol code props. */
291 if (sym->props[kind].code)
292 return &sym->props[kind];
9350499c 293
71da68b3 294 /* Per-type code props. */
b2a0b7ca
JD
295 if (sym->type_name)
296 {
70946cff 297 code_props *code =
9641b918 298 &semantic_type_get (sym->type_name, NULL)->props[kind];
71da68b3
VS
299 if (code->code)
300 return code;
b2a0b7ca
JD
301 }
302
71da68b3 303 /* Apply default code props's only to user-defined symbols. */
9534d2be
AD
304 if (sym->tag[0] != '$' && sym != errtoken)
305 {
306 code_props *code =
307 &semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind];
308 if (code->code)
309 return code;
310 }
311 return &code_props_none;
ec5479ce
JD
312}
313
17ee7397
PE
314/*-----------------------------------------------------------------.
315| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
316| with UNDEF_ASSOC as ASSOC. |
317`-----------------------------------------------------------------*/
3ae2b51f
AD
318
319void
17ee7397 320symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
3ae2b51f 321{
17ee7397 322 if (a != undef_assoc)
e9955c83 323 {
17ee7397 324 if (sym->prec != 0)
e9690142 325 symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
b2a0b7ca 326 loc);
17ee7397
PE
327 sym->prec = prec;
328 sym->assoc = a;
df09ef2e 329 sym->prec_location = loc;
e9955c83
AD
330 }
331
332 /* Only terminals have a precedence. */
073f9288 333 symbol_class_set (sym, token_sym, loc, false);
3ae2b51f
AD
334}
335
336
17ee7397
PE
337/*------------------------------------.
338| Set the CLASS associated with SYM. |
339`------------------------------------*/
44536b35
AD
340
341void
073f9288 342symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
44536b35 343{
3b0b682f 344 bool warned = false;
17ee7397 345 if (sym->class != unknown_sym && sym->class != class)
073f9288 346 {
bb8e56ff 347 complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
c5ae8e85 348 /* Don't report both "redefined" and "redeclared". */
3b0b682f 349 warned = true;
073f9288 350 }
44536b35 351
17ee7397
PE
352 if (class == nterm_sym && sym->class != nterm_sym)
353 sym->number = nvars++;
6d0ef4ec 354 else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
17ee7397 355 sym->number = ntokens++;
44536b35 356
17ee7397 357 sym->class = class;
073f9288
PE
358
359 if (declaring)
360 {
3b0b682f 361 if (sym->status == declared && !warned)
bb8e56ff 362 complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
b921d92f 363 sym->status = declared;
073f9288 364 }
44536b35
AD
365}
366
367
17ee7397
PE
368/*------------------------------------------------.
369| Set the USER_TOKEN_NUMBER associated with SYM. |
370`------------------------------------------------*/
44536b35
AD
371
372void
17ee7397 373symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
44536b35 374{
1f6b3679
JD
375 int *user_token_numberp;
376
dfaa4860 377 if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
1f6b3679
JD
378 user_token_numberp = &sym->user_token_number;
379 else
380 user_token_numberp = &sym->alias->user_token_number;
381 if (*user_token_numberp != USER_NUMBER_UNDEFINED
382 && *user_token_numberp != user_token_number)
bb8e56ff
TR
383 complain (&loc, complaint, _("redefining user token number of %s"),
384 sym->tag);
44536b35 385
1f6b3679 386 *user_token_numberp = user_token_number;
88bce5a2 387 /* User defined $end token? */
44536b35
AD
388 if (user_token_number == 0)
389 {
17ee7397 390 endtoken = sym;
44536b35 391 /* It is always mapped to 0, so it was already counted in
e9690142 392 NTOKENS. */
1f36f544
JD
393 if (endtoken->number != NUMBER_UNDEFINED)
394 --ntokens;
395 endtoken->number = 0;
44536b35
AD
396 }
397}
398
399
17ee7397
PE
400/*----------------------------------------------------------.
401| If SYM is not defined, report an error, and consider it a |
402| nonterminal. |
403`----------------------------------------------------------*/
2f1afb73 404
0fb1efaf 405static inline bool
17ee7397 406symbol_check_defined (symbol *sym)
2f1afb73 407{
17ee7397 408 if (sym->class == unknown_sym)
2f1afb73 409 {
31557b9e 410 assert (sym->status != declared);
bb8e56ff
TR
411 complain (&sym->location,
412 sym->status == needed ? complaint : Wother,
413 _("symbol %s is used, but is not defined as a token"
414 " and has no rules"),
415 sym->tag);
17ee7397
PE
416 sym->class = nterm_sym;
417 sym->number = nvars++;
2f1afb73
AD
418 }
419
c5ae8e85
AD
420 {
421 int i;
422 for (i = 0; i < 2; ++i)
423 symbol_code_props_get (sym, i)->is_used = true;
424 }
ea9a35c6 425
9641b918
VS
426 /* Set the semantic type status associated to the current symbol to
427 'declared' so that we could check semantic types unnecessary uses. */
428 if (sym->type_name)
429 {
430 semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
431 if (sem_type)
432 sem_type->status = declared;
433 }
434
435 return true;
436}
437
438static inline bool
439semantic_type_check_defined (semantic_type *sem_type)
440{
c5ae8e85 441 /* <*> and <> do not have to be "declared". */
9534d2be
AD
442 if (sem_type->status == declared
443 || !*sem_type->tag
444 || STREQ(sem_type->tag, "*"))
ea9a35c6 445 {
c5ae8e85
AD
446 int i;
447 for (i = 0; i < 2; ++i)
ea9a35c6
VS
448 if (sem_type->props[i].kind != CODE_PROPS_NONE
449 && ! sem_type->props[i].is_used)
bb8e56ff
TR
450 complain (&sem_type->location, Wother,
451 _("useless %s for type <%s>"),
452 code_props_type_string (i), sem_type->tag);
ea9a35c6
VS
453 }
454 else
bb8e56ff
TR
455 complain (&sem_type->location, Wother,
456 _("type <%s> is used, but is not associated to any symbol"),
457 sem_type->tag);
9641b918 458
a3714bce 459 return true;
2f1afb73
AD
460}
461
0fb1efaf
PE
462static bool
463symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
464{
465 return symbol_check_defined (sym);
466}
467
9641b918
VS
468static bool
469semantic_type_check_defined_processor (void *sem_type,
470 void *null ATTRIBUTE_UNUSED)
471{
472 return semantic_type_check_defined (sem_type);
473}
474
2f1afb73 475
2f1afb73 476void
dfaa4860 477symbol_make_alias (symbol *sym, symbol *str, location loc)
2f1afb73 478{
dfaa4860 479 if (str->alias)
bb8e56ff 480 complain (&loc, Wother,
6fb8b256 481 _("symbol %s used more than once as a literal string"), str->tag);
17ee7397 482 else if (sym->alias)
bb8e56ff 483 complain (&loc, Wother,
6fb8b256 484 _("symbol %s given more than one literal string"), sym->tag);
2f1afb73
AD
485 else
486 {
dfaa4860
JD
487 str->class = token_sym;
488 str->user_token_number = sym->user_token_number;
489 sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
490 str->alias = sym;
491 sym->alias = str;
492 str->number = sym->number;
493 symbol_type_set (str, sym->type_name, loc);
2f1afb73
AD
494 }
495}
496
497
498/*---------------------------------------------------------.
499| Check that THIS, and its alias, have same precedence and |
500| associativity. |
501`---------------------------------------------------------*/
502
df09ef2e 503static inline void
0fb1efaf 504symbol_check_alias_consistency (symbol *this)
2f1afb73 505{
dfaa4860 506 symbol *sym = this;
b143f404 507 symbol *str = this->alias;
df09ef2e 508
dfaa4860
JD
509 /* Check only the symbol in the symbol-string pair. */
510 if (!(this->alias
511 && this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
df09ef2e
AD
512 return;
513
dfaa4860 514 if (str->type_name != sym->type_name)
2f1afb73 515 {
dfaa4860 516 if (str->type_name)
e9690142 517 symbol_type_set (sym, str->type_name, str->type_location);
df09ef2e 518 else
e9690142 519 symbol_type_set (str, sym->type_name, sym->type_location);
df09ef2e 520 }
2f1afb73 521
df09ef2e 522
c5ae8e85
AD
523 {
524 int i;
525 for (i = 0; i < CODE_PROPS_SIZE; ++i)
526 if (str->props[i].code)
527 symbol_code_props_set (sym, i, &str->props[i]);
528 else if (sym->props[i].code)
529 symbol_code_props_set (str, i, &sym->props[i]);
530 }
df09ef2e 531
dfaa4860 532 if (sym->prec || str->prec)
df09ef2e 533 {
dfaa4860 534 if (str->prec)
e9690142
JD
535 symbol_precedence_set (sym, str->prec, str->assoc,
536 str->prec_location);
df09ef2e 537 else
e9690142
JD
538 symbol_precedence_set (str, sym->prec, sym->assoc,
539 sym->prec_location);
2f1afb73 540 }
2f1afb73
AD
541}
542
0fb1efaf
PE
543static bool
544symbol_check_alias_consistency_processor (void *this,
e9690142 545 void *null ATTRIBUTE_UNUSED)
0fb1efaf 546{
df09ef2e
AD
547 symbol_check_alias_consistency (this);
548 return true;
0fb1efaf
PE
549}
550
2f1afb73
AD
551
552/*-------------------------------------------------------------------.
553| Assign a symbol number, and write the definition of the token name |
554| into FDEFINES. Put in SYMBOLS. |
555`-------------------------------------------------------------------*/
556
0fb1efaf 557static inline bool
17ee7397 558symbol_pack (symbol *this)
2f1afb73 559{
f74d6d25 560 aver (this->number != NUMBER_UNDEFINED);
2f1afb73 561 if (this->class == nterm_sym)
f74d6d25
JD
562 this->number += ntokens;
563 else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
564 return true;
2f1afb73
AD
565
566 symbols[this->number] = this;
a3714bce 567 return true;
2f1afb73
AD
568}
569
0fb1efaf
PE
570static bool
571symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
572{
573 return symbol_pack (this);
574}
575
2f1afb73 576
12cf133f
AD
577static void
578user_token_number_redeclaration (int num, symbol *first, symbol *second)
579{
cbaea010 580 unsigned i = 0;
12cf133f 581 /* User token numbers are not assigned during the parsing, but in a
83b60c97 582 second step, via a traversal of the symbol table sorted on tag.
2f1afb73 583
83b60c97
JD
584 However, error messages make more sense if we keep the first
585 declaration first. */
12cf133f
AD
586 if (location_cmp (first->location, second->location) > 0)
587 {
588 symbol* tmp = first;
589 first = second;
590 second = tmp;
591 }
b999409e
TR
592 complain_indent (&second->location, complaint, &i,
593 _("user token number %d redeclaration for %s"),
594 num, second->tag);
b506d9bf 595 i += SUB_INDENT;
b999409e
TR
596 complain_indent (&first->location, complaint, &i,
597 _("previous declaration for %s"),
598 first->tag);
12cf133f 599}
2f1afb73
AD
600
601/*--------------------------------------------------.
602| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
603`--------------------------------------------------*/
604
0fb1efaf 605static inline bool
17ee7397 606symbol_translation (symbol *this)
2f1afb73
AD
607{
608 /* Non-terminal? */
609 if (this->class == token_sym
dfaa4860 610 && this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
2f1afb73
AD
611 {
612 /* A token which translation has already been set? */
613 if (token_translations[this->user_token_number] != undeftoken->number)
e9690142 614 user_token_number_redeclaration
12cf133f
AD
615 (this->user_token_number,
616 symbols[token_translations[this->user_token_number]],
617 this);
9553083c 618
2f1afb73
AD
619 token_translations[this->user_token_number] = this->number;
620 }
9553083c 621
a3714bce 622 return true;
2f1afb73
AD
623}
624
0fb1efaf
PE
625static bool
626symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
627{
628 return symbol_translation (this);
629}
630
72a23c97 631
b2a0b7ca
JD
632/*---------------------------------------.
633| Symbol and semantic type hash tables. |
634`---------------------------------------*/
40675e7c 635
b2a0b7ca 636/* Initial capacity of symbol and semantic type hash table. */
72a23c97
AD
637#define HT_INITIAL_CAPACITY 257
638
db8837cb 639static struct hash_table *symbol_table = NULL;
b2a0b7ca 640static struct hash_table *semantic_type_table = NULL;
72a23c97 641
0fb1efaf 642static inline bool
17ee7397 643hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 644{
95612cfa 645 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 646 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
647}
648
b2a0b7ca
JD
649static inline bool
650hash_compare_semantic_type (const semantic_type *m1, const semantic_type *m2)
651{
652 /* Since names are unique, we can compare the pointers themselves. */
653 return UNIQSTR_EQ (m1->tag, m2->tag);
654}
655
0fb1efaf
PE
656static bool
657hash_symbol_comparator (void const *m1, void const *m2)
658{
659 return hash_compare_symbol (m1, m2);
660}
661
b2a0b7ca
JD
662static bool
663hash_semantic_type_comparator (void const *m1, void const *m2)
664{
665 return hash_compare_semantic_type (m1, m2);
666}
667
233a88ad
PE
668static inline size_t
669hash_symbol (const symbol *m, size_t tablesize)
72a23c97 670{
95612cfa 671 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
672 return ((uintptr_t) m->tag) % tablesize;
673}
674
b2a0b7ca
JD
675static inline size_t
676hash_semantic_type (const semantic_type *m, size_t tablesize)
677{
678 /* Since names are unique, we can hash the pointer itself. */
679 return ((uintptr_t) m->tag) % tablesize;
680}
681
233a88ad
PE
682static size_t
683hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
684{
685 return hash_symbol (m, tablesize);
72a23c97
AD
686}
687
b2a0b7ca
JD
688static size_t
689hash_semantic_type_hasher (void const *m, size_t tablesize)
690{
691 return hash_semantic_type (m, tablesize);
692}
72a23c97
AD
693
694/*-------------------------------.
2f1afb73 695| Create the symbol hash table. |
72a23c97
AD
696`-------------------------------*/
697
698void
db8837cb 699symbols_new (void)
72a23c97 700{
db8837cb 701 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
702 NULL,
703 hash_symbol_hasher,
704 hash_symbol_comparator,
705 free);
b2a0b7ca 706 semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
e9690142
JD
707 NULL,
708 hash_semantic_type_hasher,
709 hash_semantic_type_comparator,
710 free);
40675e7c
DM
711}
712
713
1e9798d5
AD
714/*----------------------------------------------------------------.
715| Find the symbol named KEY, and return it. If it does not exist |
716| yet, create it. |
717`----------------------------------------------------------------*/
718
17ee7397 719symbol *
203b9274 720symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 721{
17ee7397
PE
722 symbol probe;
723 symbol *entry;
40675e7c 724
0fb1efaf 725 probe.tag = key;
db8837cb 726 entry = hash_lookup (symbol_table, &probe);
40675e7c 727
72a23c97 728 if (!entry)
40675e7c 729 {
72a23c97 730 /* First insertion in the hash. */
83b60c97 731 aver (!symbols_sorted);
17ee7397 732 entry = symbol_new (key, loc);
92d7a23a
AD
733 if (!hash_insert (symbol_table, entry))
734 xalloc_die ();
40675e7c 735 }
72a23c97
AD
736 return entry;
737}
40675e7c 738
40675e7c 739
b2a0b7ca
JD
740/*-----------------------------------------------------------------------.
741| Find the semantic type named KEY, and return it. If it does not exist |
742| yet, create it. |
743`-----------------------------------------------------------------------*/
744
745semantic_type *
9641b918 746semantic_type_from_uniqstr (const uniqstr key, const location *loc)
b2a0b7ca
JD
747{
748 semantic_type probe;
749 semantic_type *entry;
750
751 probe.tag = key;
752 entry = hash_lookup (semantic_type_table, &probe);
753
754 if (!entry)
755 {
756 /* First insertion in the hash. */
9641b918 757 entry = semantic_type_new (key, loc);
92d7a23a
AD
758 if (!hash_insert (semantic_type_table, entry))
759 xalloc_die ();
b2a0b7ca
JD
760 }
761 return entry;
762}
763
764
203b9274
AD
765/*----------------------------------------------------------------.
766| Find the symbol named KEY, and return it. If it does not exist |
767| yet, create it. |
768`----------------------------------------------------------------*/
769
770symbol *
771symbol_get (const char *key, location loc)
772{
773 return symbol_from_uniqstr (uniqstr_new (key), loc);
774}
775
776
b2a0b7ca
JD
777/*-----------------------------------------------------------------------.
778| Find the semantic type named KEY, and return it. If it does not exist |
779| yet, create it. |
780`-----------------------------------------------------------------------*/
781
782semantic_type *
9641b918 783semantic_type_get (const char *key, const location *loc)
b2a0b7ca 784{
9641b918 785 return semantic_type_from_uniqstr (uniqstr_new (key), loc);
b2a0b7ca
JD
786}
787
788
39f41916
AD
789/*------------------------------------------------------------------.
790| Generate a dummy nonterminal, whose name cannot conflict with the |
791| user's names. |
792`------------------------------------------------------------------*/
793
17ee7397
PE
794symbol *
795dummy_symbol_get (location loc)
39f41916
AD
796{
797 /* Incremented for each generated symbol. */
798 static int dummy_count = 0;
799 static char buf[256];
800
17ee7397 801 symbol *sym;
39f41916 802
f91b1629 803 sprintf (buf, "$@%d", ++dummy_count);
17ee7397 804 sym = symbol_get (buf, loc);
39f41916
AD
805 sym->class = nterm_sym;
806 sym->number = nvars++;
807 return sym;
808}
809
4d7370cb
JD
810bool
811symbol_is_dummy (const symbol *sym)
812{
f91b1629 813 return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
4d7370cb 814}
39f41916 815
72a23c97 816/*-------------------.
db8837cb 817| Free the symbols. |
72a23c97
AD
818`-------------------*/
819
820void
db8837cb 821symbols_free (void)
72a23c97 822{
db8837cb 823 hash_free (symbol_table);
b2a0b7ca 824 hash_free (semantic_type_table);
536545f3 825 free (symbols);
83b60c97 826 free (symbols_sorted);
ae9c90ba 827 free (semantic_types_sorted);
40675e7c
DM
828}
829
830
72a23c97 831/*---------------------------------------------------------------.
db8837cb 832| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
833| terminals. |
834`---------------------------------------------------------------*/
835
83b60c97
JD
836static int
837symbols_cmp (symbol const *a, symbol const *b)
838{
839 return strcmp (a->tag, b->tag);
840}
841
842static int
843symbols_cmp_qsort (void const *a, void const *b)
844{
845 return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
846}
847
0fb1efaf 848static void
dfe292c6 849symbols_do (Hash_processor processor, void *processor_data,
ae9c90ba 850 struct hash_table *table, symbol ***sorted)
40675e7c 851{
dfe292c6 852 size_t count = hash_get_n_entries (table);
ae9c90ba 853 if (!*sorted)
83b60c97 854 {
ae9c90ba
TR
855 *sorted = xnmalloc (count, sizeof **sorted);
856 hash_get_entries (table, (void**)*sorted, count);
857 qsort (*sorted, count, sizeof **sorted, symbols_cmp_qsort);
83b60c97
JD
858 }
859 {
860 size_t i;
861 for (i = 0; i < count; ++i)
ae9c90ba 862 processor ((*sorted)[i], processor_data);
83b60c97 863 }
40675e7c 864}
2f1afb73 865
2f1afb73
AD
866/*--------------------------------------------------------------.
867| Check that all the symbols are defined. Report any undefined |
868| symbols and consider them nonterminals. |
869`--------------------------------------------------------------*/
870
871void
872symbols_check_defined (void)
873{
dfe292c6 874 symbols_do (symbol_check_defined_processor, NULL,
ae9c90ba 875 symbol_table, &symbols_sorted);
9641b918 876 symbols_do (semantic_type_check_defined_processor, NULL,
ae9c90ba 877 semantic_type_table, &semantic_types_sorted);
2f1afb73
AD
878}
879
880/*------------------------------------------------------------------.
881| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
882| number. |
883`------------------------------------------------------------------*/
884
885static void
886symbols_token_translations_init (void)
887{
a3714bce 888 bool num_256_available_p = true;
2f1afb73
AD
889 int i;
890
891 /* Find the highest user token number, and whether 256, the POSIX
892 preferred user token number for the error token, is used. */
893 max_user_token_number = 0;
894 for (i = 0; i < ntokens; ++i)
895 {
17ee7397 896 symbol *this = symbols[i];
2f1afb73 897 if (this->user_token_number != USER_NUMBER_UNDEFINED)
e9690142
JD
898 {
899 if (this->user_token_number > max_user_token_number)
900 max_user_token_number = this->user_token_number;
901 if (this->user_token_number == 256)
902 num_256_available_p = false;
903 }
2f1afb73
AD
904 }
905
906 /* If 256 is not used, assign it to error, to follow POSIX. */
907 if (num_256_available_p
908 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
909 errtoken->user_token_number = 256;
910
911 /* Set the missing user numbers. */
912 if (max_user_token_number < 256)
913 max_user_token_number = 256;
914
915 for (i = 0; i < ntokens; ++i)
916 {
17ee7397 917 symbol *this = symbols[i];
2f1afb73 918 if (this->user_token_number == USER_NUMBER_UNDEFINED)
e9690142 919 this->user_token_number = ++max_user_token_number;
2f1afb73 920 if (this->user_token_number > max_user_token_number)
e9690142 921 max_user_token_number = this->user_token_number;
2f1afb73
AD
922 }
923
da2a7671 924 token_translations = xnmalloc (max_user_token_number + 1,
e9690142 925 sizeof *token_translations);
2f1afb73 926
b3a28fd4
AD
927 /* Initialize all entries for literal tokens to the internal token
928 number for $undefined, which represents all invalid inputs. */
2f1afb73
AD
929 for (i = 0; i < max_user_token_number + 1; i++)
930 token_translations[i] = undeftoken->number;
dfe292c6 931 symbols_do (symbol_translation_processor, NULL,
ae9c90ba 932 symbol_table, &symbols_sorted);
2f1afb73
AD
933}
934
935
936/*----------------------------------------------------------------.
937| Assign symbol numbers, and write definition of token names into |
938| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
939`----------------------------------------------------------------*/
940
941void
942symbols_pack (void)
943{
dfe292c6 944 symbols_do (symbol_check_alias_consistency_processor, NULL,
ae9c90ba 945 symbol_table, &symbols_sorted);
6d0ef4ec
JD
946
947 symbols = xcalloc (nsyms, sizeof *symbols);
ae9c90ba 948 symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
2f1afb73 949
6d0ef4ec
JD
950 /* Aliases leave empty slots in symbols, so remove them. */
951 {
952 int writei;
953 int readi;
954 int nsyms_old = nsyms;
955 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
956 {
957 if (symbols[readi] == NULL)
958 {
959 nsyms -= 1;
960 ntokens -= 1;
961 }
962 else
963 {
964 symbols[writei] = symbols[readi];
965 symbols[writei]->number = writei;
966 if (symbols[writei]->alias)
967 symbols[writei]->alias->number = writei;
968 writei += 1;
969 }
970 }
971 }
972 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
973
2f1afb73
AD
974 symbols_token_translations_init ();
975
976 if (startsymbol->class == unknown_sym)
bb8e56ff
TR
977 complain (&startsymbol_location, fatal,
978 _("the start symbol %s is undefined"),
979 startsymbol->tag);
2f1afb73 980 else if (startsymbol->class == token_sym)
bb8e56ff
TR
981 complain (&startsymbol_location, fatal,
982 _("the start symbol %s is a token"),
983 startsymbol->tag);
2f1afb73 984}
284bc49c
VT
985
986/*---------------------------------.
987| Initialize relation graph nodes. |
988`---------------------------------*/
989
990static void
991init_prec_nodes (void)
992{
993 int i;
994 prec_nodes = xcalloc (nsyms, sizeof *prec_nodes);
995 for (i = 0; i < nsyms; ++i)
996 {
997 prec_nodes[i] = xmalloc (sizeof *prec_nodes[i]);
998 symgraph *s = prec_nodes[i];
999 s->id = i;
1000 s->succ = 0;
1001 s->pred = 0;
1002 }
1003}
1004
1005/*----------------.
1006| Create a link. |
1007`----------------*/
1008
1009static symgraphlink *
1010symgraphlink_new (graphid id, symgraphlink *next)
1011{
1012 symgraphlink *l = xmalloc (sizeof *l);
1013 l->id = id;
1014 l->next = next;
1015 return l;
1016}
1017
1018
1019/*------------------------------------------------------------------.
1020| Register the second symbol of the precedence relation, and return |
1021| whether this relation is new. Use only in register_precedence. |
1022`------------------------------------------------------------------*/
1023
1024static bool
1025register_precedence_second_symbol (symgraphlink **first, graphid sym)
1026{
1027 if (!*first || sym < (*first)->id)
1028 *first = symgraphlink_new (sym, *first);
1029 else
1030 {
1031 symgraphlink *slist = *first;
1032
1033 while (slist->next && slist->next->id <= sym)
1034 slist = slist->next;
1035
1036 if (slist->id == sym)
1037 /* Relation already present. */
1038 return false;
1039
1040 slist->next = symgraphlink_new (sym, slist->next);
1041 }
1042 return true;
1043}
1044
1045/*------------------------------------------------------------------.
1046| Register a new relation between symbols as used. The first symbol |
1047| has a greater precedence than the second one. |
1048`------------------------------------------------------------------*/
1049
1050void
1051register_precedence (graphid first, graphid snd)
1052{
1053 if (!prec_nodes)
1054 init_prec_nodes ();
1055 register_precedence_second_symbol (&(prec_nodes[first]->succ), snd);
1056 register_precedence_second_symbol (&(prec_nodes[snd]->pred), first);
1057}
1058
1059
e8f7155d
VT
1060/*---------------------------------------.
1061| Initialize association tracking table. |
1062`---------------------------------------*/
1063
1064static void
1065init_assoc (void)
1066{
1067 graphid i;
1068 used_assoc = xcalloc(nsyms, sizeof(*used_assoc));
1069 for (i = 0; i < nsyms; ++i)
1070 used_assoc[i] = false;
1071}
1072
1073/*------------------------------------------------------------------.
1074| Test if the associativity for the symbols is defined and useless. |
1075`------------------------------------------------------------------*/
1076
1077static inline bool
1078is_assoc_useless (symbol *s)
1079{
1080 return s
1081 && s->assoc != undef_assoc
1082 && s->assoc != precedence_assoc
1083 && !used_assoc[s->number];
1084}
1085
1086/*-------------------------------.
1087| Register a used associativity. |
1088`-------------------------------*/
1089
1090void
1091register_assoc (graphid i, graphid j)
1092{
1093 if (!used_assoc)
1094 init_assoc ();
1095 used_assoc[i] = true;
1096 used_assoc[j] = true;
1097}
1098
cc2235ac
VT
1099/*--------------------------------------------------.
1100| Print a warning for unused precedence relations. |
1101`--------------------------------------------------*/
e8f7155d
VT
1102
1103void
cc2235ac 1104print_precedence_warnings (void)
e8f7155d 1105{
cc2235ac
VT
1106 int i;
1107 if (!prec_nodes)
1108 init_prec_nodes ();
e8f7155d
VT
1109 if (!used_assoc)
1110 init_assoc ();
1111 for (i = 0; i < nsyms; ++i)
1112 {
1113 symbol *s = symbols[i];
cc2235ac
VT
1114 if (s
1115 && s->prec != 0
1116 && !prec_nodes[i]->pred
1117 && !prec_nodes[i]->succ)
1118 {
1119 if (is_assoc_useless (s))
1120 complain (&s->location, Wprecedence,
1121 _("useless precedence and associativity for %s"), s->tag);
1122 else if (s->assoc == precedence_assoc)
1123 complain (&s->location, Wprecedence,
1124 _("useless precedence for %s"), s->tag);
1125 }
1126 else if (is_assoc_useless (s))
1127 complain (&s->location, Wprecedence,
1128 _("useless associativity for %s, use %%precedence"), s->tag);
e8f7155d
VT
1129 }
1130}