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