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