]> git.saurik.com Git - bison.git/blame - src/symtab.c
Undo last commit.
[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);
1e9798d5 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++;
269 else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
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;
364 /* sym and symval combined are only one symbol. */
2f1afb73
AD
365 nsyms--;
366 ntokens--;
68cae94e 367 assert (ntokens == sym->number || ntokens == symval->number);
17ee7397
PE
368 sym->number = symval->number =
369 (symval->number < sym->number) ? symval->number : sym->number;
e8fd72d5 370 symbol_type_set (symval, sym->type_name, loc);
2f1afb73
AD
371 }
372}
373
374
375/*---------------------------------------------------------.
376| Check that THIS, and its alias, have same precedence and |
377| associativity. |
378`---------------------------------------------------------*/
379
df09ef2e 380static inline void
0fb1efaf 381symbol_check_alias_consistency (symbol *this)
2f1afb73 382{
df09ef2e
AD
383 symbol *alias = this;
384 symbol *orig = this->alias;
385
386 /* Check only those that _are_ the aliases. */
387 if (!(this->alias && this->user_token_number == USER_NUMBER_ALIAS))
388 return;
389
e8fd72d5 390 if (orig->type_name != alias->type_name)
2f1afb73 391 {
df09ef2e
AD
392 if (orig->type_name)
393 symbol_type_set (alias, orig->type_name, orig->type_location);
394 else
395 symbol_type_set (orig, alias->type_name, alias->type_location);
396 }
2f1afb73 397
df09ef2e
AD
398
399 if (orig->destructor || alias->destructor)
400 {
401 if (orig->destructor)
402 symbol_destructor_set (alias, orig->destructor,
403 orig->destructor_location);
404 else
405 symbol_destructor_set (orig, alias->destructor,
406 alias->destructor_location);
407 }
408
409 if (orig->printer || alias->printer)
410 {
411 if (orig->printer)
412 symbol_printer_set (alias, orig->printer, orig->printer_location);
413 else
414 symbol_printer_set (orig, alias->printer, alias->printer_location);
415 }
416
417 if (alias->prec || orig->prec)
418 {
419 if (orig->prec)
420 symbol_precedence_set (alias, orig->prec, orig->assoc,
421 orig->prec_location);
422 else
423 symbol_precedence_set (orig, alias->prec, alias->assoc,
424 alias->prec_location);
2f1afb73 425 }
2f1afb73
AD
426}
427
0fb1efaf
PE
428static bool
429symbol_check_alias_consistency_processor (void *this,
430 void *null ATTRIBUTE_UNUSED)
431{
df09ef2e
AD
432 symbol_check_alias_consistency (this);
433 return true;
0fb1efaf
PE
434}
435
2f1afb73
AD
436
437/*-------------------------------------------------------------------.
438| Assign a symbol number, and write the definition of the token name |
439| into FDEFINES. Put in SYMBOLS. |
440`-------------------------------------------------------------------*/
441
0fb1efaf 442static inline bool
17ee7397 443symbol_pack (symbol *this)
2f1afb73
AD
444{
445 if (this->class == nterm_sym)
446 {
447 this->number += ntokens;
448 }
449 else if (this->alias)
450 {
451 /* This symbol and its alias are a single token defn.
452 Allocate a tokno, and assign to both check agreement of
453 prec and assoc fields and make both the same */
454 if (this->number == NUMBER_UNDEFINED)
455 {
88bce5a2 456 if (this == endtoken || this->alias == endtoken)
2f1afb73
AD
457 this->number = this->alias->number = 0;
458 else
459 {
68cae94e 460 assert (this->alias->number != NUMBER_UNDEFINED);
2f1afb73
AD
461 this->number = this->alias->number;
462 }
463 }
b9e00562 464 /* Do not do processing below for USER_NUMBER_ALIASes. */
2f1afb73 465 if (this->user_token_number == USER_NUMBER_ALIAS)
a3714bce 466 return true;
2f1afb73
AD
467 }
468 else /* this->class == token_sym */
68cae94e 469 assert (this->number != NUMBER_UNDEFINED);
2f1afb73
AD
470
471 symbols[this->number] = this;
a3714bce 472 return true;
2f1afb73
AD
473}
474
0fb1efaf
PE
475static bool
476symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
477{
478 return symbol_pack (this);
479}
480
2f1afb73
AD
481
482
483
484/*--------------------------------------------------.
485| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
486`--------------------------------------------------*/
487
0fb1efaf 488static inline bool
17ee7397 489symbol_translation (symbol *this)
2f1afb73
AD
490{
491 /* Non-terminal? */
492 if (this->class == token_sym
493 && this->user_token_number != USER_NUMBER_ALIAS)
494 {
495 /* A token which translation has already been set? */
496 if (token_translations[this->user_token_number] != undeftoken->number)
a5d50994
AD
497 complain_at (this->location,
498 _("tokens %s and %s both assigned number %d"),
499 symbols[token_translations[this->user_token_number]]->tag,
500 this->tag, this->user_token_number);
2f1afb73
AD
501
502 token_translations[this->user_token_number] = this->number;
503 }
504
a3714bce 505 return true;
2f1afb73
AD
506}
507
0fb1efaf
PE
508static bool
509symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
510{
511 return symbol_translation (this);
512}
513
72a23c97
AD
514
515/*----------------------.
2f1afb73 516| A symbol hash table. |
72a23c97 517`----------------------*/
40675e7c 518
db8837cb 519/* Initial capacity of symbols hash table. */
72a23c97
AD
520#define HT_INITIAL_CAPACITY 257
521
db8837cb 522static struct hash_table *symbol_table = NULL;
72a23c97 523
0fb1efaf 524static inline bool
17ee7397 525hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 526{
95612cfa 527 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 528 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
529}
530
0fb1efaf
PE
531static bool
532hash_symbol_comparator (void const *m1, void const *m2)
533{
534 return hash_compare_symbol (m1, m2);
535}
536
233a88ad
PE
537static inline size_t
538hash_symbol (const symbol *m, size_t tablesize)
72a23c97 539{
95612cfa 540 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
541 return ((uintptr_t) m->tag) % tablesize;
542}
543
233a88ad
PE
544static size_t
545hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
546{
547 return hash_symbol (m, tablesize);
72a23c97
AD
548}
549
550
551/*-------------------------------.
2f1afb73 552| Create the symbol hash table. |
72a23c97
AD
553`-------------------------------*/
554
555void
db8837cb 556symbols_new (void)
72a23c97 557{
db8837cb 558 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
72a23c97 559 NULL,
0fb1efaf
PE
560 hash_symbol_hasher,
561 hash_symbol_comparator,
562 free);
40675e7c
DM
563}
564
565
1e9798d5
AD
566/*----------------------------------------------------------------.
567| Find the symbol named KEY, and return it. If it does not exist |
568| yet, create it. |
569`----------------------------------------------------------------*/
570
17ee7397 571symbol *
203b9274 572symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 573{
17ee7397
PE
574 symbol probe;
575 symbol *entry;
40675e7c 576
0fb1efaf 577 probe.tag = key;
db8837cb 578 entry = hash_lookup (symbol_table, &probe);
40675e7c 579
72a23c97 580 if (!entry)
40675e7c 581 {
72a23c97 582 /* First insertion in the hash. */
17ee7397 583 entry = symbol_new (key, loc);
db8837cb 584 hash_insert (symbol_table, entry);
40675e7c 585 }
72a23c97
AD
586 return entry;
587}
40675e7c 588
40675e7c 589
203b9274
AD
590/*----------------------------------------------------------------.
591| Find the symbol named KEY, and return it. If it does not exist |
592| yet, create it. |
593`----------------------------------------------------------------*/
594
595symbol *
596symbol_get (const char *key, location loc)
597{
598 return symbol_from_uniqstr (uniqstr_new (key), loc);
599}
600
601
39f41916
AD
602/*------------------------------------------------------------------.
603| Generate a dummy nonterminal, whose name cannot conflict with the |
604| user's names. |
605`------------------------------------------------------------------*/
606
17ee7397
PE
607symbol *
608dummy_symbol_get (location loc)
39f41916
AD
609{
610 /* Incremented for each generated symbol. */
611 static int dummy_count = 0;
612 static char buf[256];
613
17ee7397 614 symbol *sym;
39f41916
AD
615
616 sprintf (buf, "@%d", ++dummy_count);
17ee7397 617 sym = symbol_get (buf, loc);
39f41916
AD
618 sym->class = nterm_sym;
619 sym->number = nvars++;
620 return sym;
621}
622
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{
da2a7671 723 symbols = xcalloc (nsyms, sizeof *symbols);
2f1afb73 724
0fb1efaf
PE
725 symbols_do (symbol_check_alias_consistency_processor, NULL);
726 symbols_do (symbol_pack_processor, NULL);
2f1afb73
AD
727
728 symbols_token_translations_init ();
729
730 if (startsymbol->class == unknown_sym)
ee000ba4 731 fatal_at (startsymbol_location,
dafdc66f 732 _("the start symbol %s is undefined"),
97650f4e 733 startsymbol->tag);
2f1afb73 734 else if (startsymbol->class == token_sym)
ee000ba4 735 fatal_at (startsymbol_location,
dafdc66f 736 _("the start symbol %s is a token"),
97650f4e 737 startsymbol->tag);
2f1afb73 738}
ec5479ce
JD
739
740
741/*-----------------------------------.
742| Set default %destructor/%printer. |
743`-----------------------------------*/
744
745void
746default_destructor_set (const char *destructor, location loc)
747{
748 if (default_destructor != NULL)
749 {
750 complain_at (loc, _("redeclaration for default %%destructor"));
751 complain_at (default_destructor_location, _("previous declaration"));
752 }
753 default_destructor = destructor;
754 default_destructor_location = loc;
755}
756
757void
758default_printer_set (const char *printer, location loc)
759{
760 if (default_printer != NULL)
761 {
762 complain_at (loc, _("redeclaration for default %%printer"));
763 complain_at (default_printer_location, _("previous declaration"));
764 }
765 default_printer = printer;
766 default_printer_location = loc;
767}