]> git.saurik.com Git - bison.git/blame - src/symtab.c
Whether the default %destructor/%printer applies to a particular symbol
[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{
9350499c 166 /* Per-symbol %destructor. */
ec5479ce
JD
167 if (sym->destructor != NULL)
168 return sym->destructor;
9350499c
JD
169
170 /* Apply the default %destructor only to user-defined symbols. */
3508ce36 171 if (sym->tag[0] == '$' || sym == errtoken)
9350499c 172 return NULL;
ec5479ce
JD
173 return default_destructor;
174}
175
176/*---------------------------------------------------------------.
177| Get the grammar location of the %destructor computed for SYM. |
178`---------------------------------------------------------------*/
179
180location
181symbol_destructor_location_get (symbol *sym)
182{
183 if (sym->destructor != NULL)
184 return sym->destructor_location;
185 return default_destructor_location;
186}
9280d3ef 187
17ee7397
PE
188/*---------------------------------------------------------------.
189| Set the PRINTER associated with SYM. Do nothing if passed 0. |
190`---------------------------------------------------------------*/
366eea36
AD
191
192void
c1432f65 193symbol_printer_set (symbol *sym, const char *printer, location loc)
366eea36
AD
194{
195 if (printer)
196 {
17ee7397 197 if (sym->printer)
31b2b07e 198 redeclaration (sym, "%printer", sym->printer_location, loc);
17ee7397
PE
199 sym->printer = printer;
200 sym->printer_location = loc;
366eea36
AD
201 }
202}
203
ec5479ce
JD
204/*------------------------------------.
205| Get the computed %printer for SYM. |
206`------------------------------------*/
207
208const char *
209symbol_printer_get (symbol *sym)
210{
9350499c 211 /* Per-symbol %printer. */
ec5479ce
JD
212 if (sym->printer != NULL)
213 return sym->printer;
9350499c
JD
214
215 /* Apply the default %printer only to user-defined symbols. */
3508ce36 216 if (sym->tag[0] == '$' || sym == errtoken)
9350499c 217 return NULL;
ec5479ce
JD
218 return default_printer;
219}
220
221/*------------------------------------------------------------.
222| Get the grammar location of the %printer computed for SYM. |
223`------------------------------------------------------------*/
224
225location
226symbol_printer_location_get (symbol *sym)
227{
228 if (sym->printer != NULL)
229 return sym->printer_location;
230 return default_printer_location;
231}
232
366eea36 233
17ee7397
PE
234/*-----------------------------------------------------------------.
235| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
236| with UNDEF_ASSOC as ASSOC. |
237`-----------------------------------------------------------------*/
3ae2b51f
AD
238
239void
17ee7397 240symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
3ae2b51f 241{
17ee7397 242 if (a != undef_assoc)
e9955c83 243 {
17ee7397 244 if (sym->prec != 0)
df09ef2e 245 redeclaration (sym, assoc_to_string (a), sym->prec_location, loc);
17ee7397
PE
246 sym->prec = prec;
247 sym->assoc = a;
df09ef2e 248 sym->prec_location = loc;
e9955c83
AD
249 }
250
251 /* Only terminals have a precedence. */
073f9288 252 symbol_class_set (sym, token_sym, loc, false);
3ae2b51f
AD
253}
254
255
17ee7397
PE
256/*------------------------------------.
257| Set the CLASS associated with SYM. |
258`------------------------------------*/
44536b35
AD
259
260void
073f9288 261symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
44536b35 262{
17ee7397 263 if (sym->class != unknown_sym && sym->class != class)
073f9288
PE
264 {
265 complain_at (loc, _("symbol %s redefined"), sym->tag);
266 sym->declared = false;
267 }
44536b35 268
17ee7397
PE
269 if (class == nterm_sym && sym->class != nterm_sym)
270 sym->number = nvars++;
6d0ef4ec 271 else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
17ee7397 272 sym->number = ntokens++;
44536b35 273
17ee7397 274 sym->class = class;
073f9288
PE
275
276 if (declaring)
277 {
278 if (sym->declared)
279 warn_at (loc, _("symbol %s redeclared"), sym->tag);
280 sym->declared = true;
281 }
44536b35
AD
282}
283
284
17ee7397
PE
285/*------------------------------------------------.
286| Set the USER_TOKEN_NUMBER associated with SYM. |
287`------------------------------------------------*/
44536b35
AD
288
289void
17ee7397 290symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
44536b35 291{
1f6b3679
JD
292 int *user_token_numberp;
293
68cae94e 294 assert (sym->class == token_sym);
44536b35 295
1f6b3679
JD
296 if (sym->user_token_number != USER_NUMBER_ALIAS)
297 user_token_numberp = &sym->user_token_number;
298 else
299 user_token_numberp = &sym->alias->user_token_number;
300 if (*user_token_numberp != USER_NUMBER_UNDEFINED
301 && *user_token_numberp != user_token_number)
17ee7397 302 complain_at (loc, _("redefining user token number of %s"), sym->tag);
44536b35 303
1f6b3679 304 *user_token_numberp = user_token_number;
88bce5a2 305 /* User defined $end token? */
44536b35
AD
306 if (user_token_number == 0)
307 {
17ee7397 308 endtoken = sym;
88bce5a2 309 endtoken->number = 0;
44536b35
AD
310 /* It is always mapped to 0, so it was already counted in
311 NTOKENS. */
312 --ntokens;
313 }
314}
315
316
17ee7397
PE
317/*----------------------------------------------------------.
318| If SYM is not defined, report an error, and consider it a |
319| nonterminal. |
320`----------------------------------------------------------*/
2f1afb73 321
0fb1efaf 322static inline bool
17ee7397 323symbol_check_defined (symbol *sym)
2f1afb73 324{
17ee7397 325 if (sym->class == unknown_sym)
2f1afb73 326 {
ee000ba4 327 complain_at
17ee7397 328 (sym->location,
ee000ba4 329 _("symbol %s is used, but is not defined as a token and has no rules"),
17ee7397
PE
330 sym->tag);
331 sym->class = nterm_sym;
332 sym->number = nvars++;
2f1afb73
AD
333 }
334
a3714bce 335 return true;
2f1afb73
AD
336}
337
0fb1efaf
PE
338static bool
339symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
340{
341 return symbol_check_defined (sym);
342}
343
2f1afb73 344
17ee7397
PE
345/*------------------------------------------------------------------.
346| Declare the new symbol SYM. Make it an alias of SYMVAL, and type |
527203e9 347| SYMVAL with SYM's type. |
17ee7397 348`------------------------------------------------------------------*/
2f1afb73
AD
349
350void
17ee7397 351symbol_make_alias (symbol *sym, symbol *symval, location loc)
2f1afb73
AD
352{
353 if (symval->alias)
a5d50994 354 warn_at (loc, _("symbol `%s' used more than once as a literal string"),
df09ef2e 355 symval->tag);
17ee7397 356 else if (sym->alias)
a5d50994 357 warn_at (loc, _("symbol `%s' given more than one literal string"),
df09ef2e 358 sym->tag);
2f1afb73
AD
359 else
360 {
361 symval->class = token_sym;
17ee7397
PE
362 symval->user_token_number = sym->user_token_number;
363 sym->user_token_number = USER_NUMBER_ALIAS;
364 symval->alias = sym;
365 sym->alias = symval;
965537bc 366 symval->number = sym->number;
e8fd72d5 367 symbol_type_set (symval, sym->type_name, loc);
2f1afb73
AD
368 }
369}
370
371
372/*---------------------------------------------------------.
373| Check that THIS, and its alias, have same precedence and |
374| associativity. |
375`---------------------------------------------------------*/
376
df09ef2e 377static inline void
0fb1efaf 378symbol_check_alias_consistency (symbol *this)
2f1afb73 379{
df09ef2e
AD
380 symbol *alias = this;
381 symbol *orig = this->alias;
382
383 /* Check only those that _are_ the aliases. */
384 if (!(this->alias && this->user_token_number == USER_NUMBER_ALIAS))
385 return;
386
e8fd72d5 387 if (orig->type_name != alias->type_name)
2f1afb73 388 {
df09ef2e
AD
389 if (orig->type_name)
390 symbol_type_set (alias, orig->type_name, orig->type_location);
391 else
392 symbol_type_set (orig, alias->type_name, alias->type_location);
393 }
2f1afb73 394
df09ef2e
AD
395
396 if (orig->destructor || alias->destructor)
397 {
398 if (orig->destructor)
399 symbol_destructor_set (alias, orig->destructor,
400 orig->destructor_location);
401 else
402 symbol_destructor_set (orig, alias->destructor,
403 alias->destructor_location);
404 }
405
406 if (orig->printer || alias->printer)
407 {
408 if (orig->printer)
409 symbol_printer_set (alias, orig->printer, orig->printer_location);
410 else
411 symbol_printer_set (orig, alias->printer, alias->printer_location);
412 }
413
414 if (alias->prec || orig->prec)
415 {
416 if (orig->prec)
417 symbol_precedence_set (alias, orig->prec, orig->assoc,
418 orig->prec_location);
419 else
420 symbol_precedence_set (orig, alias->prec, alias->assoc,
421 alias->prec_location);
2f1afb73 422 }
2f1afb73
AD
423}
424
0fb1efaf
PE
425static bool
426symbol_check_alias_consistency_processor (void *this,
427 void *null ATTRIBUTE_UNUSED)
428{
df09ef2e
AD
429 symbol_check_alias_consistency (this);
430 return true;
0fb1efaf
PE
431}
432
2f1afb73
AD
433
434/*-------------------------------------------------------------------.
435| Assign a symbol number, and write the definition of the token name |
436| into FDEFINES. Put in SYMBOLS. |
437`-------------------------------------------------------------------*/
438
0fb1efaf 439static inline bool
17ee7397 440symbol_pack (symbol *this)
2f1afb73
AD
441{
442 if (this->class == nterm_sym)
443 {
444 this->number += ntokens;
445 }
446 else if (this->alias)
447 {
448 /* This symbol and its alias are a single token defn.
449 Allocate a tokno, and assign to both check agreement of
450 prec and assoc fields and make both the same */
451 if (this->number == NUMBER_UNDEFINED)
452 {
88bce5a2 453 if (this == endtoken || this->alias == endtoken)
2f1afb73
AD
454 this->number = this->alias->number = 0;
455 else
456 {
68cae94e 457 assert (this->alias->number != NUMBER_UNDEFINED);
2f1afb73
AD
458 this->number = this->alias->number;
459 }
460 }
b9e00562 461 /* Do not do processing below for USER_NUMBER_ALIASes. */
2f1afb73 462 if (this->user_token_number == USER_NUMBER_ALIAS)
a3714bce 463 return true;
2f1afb73
AD
464 }
465 else /* this->class == token_sym */
68cae94e 466 assert (this->number != NUMBER_UNDEFINED);
2f1afb73
AD
467
468 symbols[this->number] = this;
a3714bce 469 return true;
2f1afb73
AD
470}
471
0fb1efaf
PE
472static bool
473symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
474{
475 return symbol_pack (this);
476}
477
2f1afb73
AD
478
479
480
481/*--------------------------------------------------.
482| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
483`--------------------------------------------------*/
484
0fb1efaf 485static inline bool
17ee7397 486symbol_translation (symbol *this)
2f1afb73
AD
487{
488 /* Non-terminal? */
489 if (this->class == token_sym
490 && this->user_token_number != USER_NUMBER_ALIAS)
491 {
492 /* A token which translation has already been set? */
493 if (token_translations[this->user_token_number] != undeftoken->number)
a5d50994
AD
494 complain_at (this->location,
495 _("tokens %s and %s both assigned number %d"),
496 symbols[token_translations[this->user_token_number]]->tag,
497 this->tag, this->user_token_number);
2f1afb73
AD
498
499 token_translations[this->user_token_number] = this->number;
500 }
501
a3714bce 502 return true;
2f1afb73
AD
503}
504
0fb1efaf
PE
505static bool
506symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
507{
508 return symbol_translation (this);
509}
510
72a23c97
AD
511
512/*----------------------.
2f1afb73 513| A symbol hash table. |
72a23c97 514`----------------------*/
40675e7c 515
db8837cb 516/* Initial capacity of symbols hash table. */
72a23c97
AD
517#define HT_INITIAL_CAPACITY 257
518
db8837cb 519static struct hash_table *symbol_table = NULL;
72a23c97 520
0fb1efaf 521static inline bool
17ee7397 522hash_compare_symbol (const symbol *m1, const symbol *m2)
72a23c97 523{
95612cfa 524 /* Since tags are unique, we can compare the pointers themselves. */
17ee7397 525 return UNIQSTR_EQ (m1->tag, m2->tag);
72a23c97
AD
526}
527
0fb1efaf
PE
528static bool
529hash_symbol_comparator (void const *m1, void const *m2)
530{
531 return hash_compare_symbol (m1, m2);
532}
533
233a88ad
PE
534static inline size_t
535hash_symbol (const symbol *m, size_t tablesize)
72a23c97 536{
95612cfa 537 /* Since tags are unique, we can hash the pointer itself. */
0fb1efaf
PE
538 return ((uintptr_t) m->tag) % tablesize;
539}
540
233a88ad
PE
541static size_t
542hash_symbol_hasher (void const *m, size_t tablesize)
0fb1efaf
PE
543{
544 return hash_symbol (m, tablesize);
72a23c97
AD
545}
546
547
548/*-------------------------------.
2f1afb73 549| Create the symbol hash table. |
72a23c97
AD
550`-------------------------------*/
551
552void
db8837cb 553symbols_new (void)
72a23c97 554{
db8837cb 555 symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
72a23c97 556 NULL,
0fb1efaf
PE
557 hash_symbol_hasher,
558 hash_symbol_comparator,
559 free);
40675e7c
DM
560}
561
562
1e9798d5
AD
563/*----------------------------------------------------------------.
564| Find the symbol named KEY, and return it. If it does not exist |
565| yet, create it. |
566`----------------------------------------------------------------*/
567
17ee7397 568symbol *
203b9274 569symbol_from_uniqstr (const uniqstr key, location loc)
40675e7c 570{
17ee7397
PE
571 symbol probe;
572 symbol *entry;
40675e7c 573
0fb1efaf 574 probe.tag = key;
db8837cb 575 entry = hash_lookup (symbol_table, &probe);
40675e7c 576
72a23c97 577 if (!entry)
40675e7c 578 {
72a23c97 579 /* First insertion in the hash. */
17ee7397 580 entry = symbol_new (key, loc);
db8837cb 581 hash_insert (symbol_table, entry);
40675e7c 582 }
72a23c97
AD
583 return entry;
584}
40675e7c 585
40675e7c 586
203b9274
AD
587/*----------------------------------------------------------------.
588| Find the symbol named KEY, and return it. If it does not exist |
589| yet, create it. |
590`----------------------------------------------------------------*/
591
592symbol *
593symbol_get (const char *key, location loc)
594{
595 return symbol_from_uniqstr (uniqstr_new (key), loc);
596}
597
598
39f41916
AD
599/*------------------------------------------------------------------.
600| Generate a dummy nonterminal, whose name cannot conflict with the |
601| user's names. |
602`------------------------------------------------------------------*/
603
17ee7397
PE
604symbol *
605dummy_symbol_get (location loc)
39f41916
AD
606{
607 /* Incremented for each generated symbol. */
608 static int dummy_count = 0;
609 static char buf[256];
610
17ee7397 611 symbol *sym;
39f41916
AD
612
613 sprintf (buf, "@%d", ++dummy_count);
17ee7397 614 sym = symbol_get (buf, loc);
39f41916
AD
615 sym->class = nterm_sym;
616 sym->number = nvars++;
617 return sym;
618}
619
4d7370cb
JD
620bool
621symbol_is_dummy (const symbol *sym)
622{
623 return sym->tag[0] == '@';
624}
39f41916 625
72a23c97 626/*-------------------.
db8837cb 627| Free the symbols. |
72a23c97
AD
628`-------------------*/
629
630void
db8837cb 631symbols_free (void)
72a23c97 632{
db8837cb 633 hash_free (symbol_table);
536545f3 634 free (symbols);
40675e7c
DM
635}
636
637
72a23c97 638/*---------------------------------------------------------------.
db8837cb 639| Look for undefined symbols, report an error, and consider them |
72a23c97
AD
640| terminals. |
641`---------------------------------------------------------------*/
642
0fb1efaf
PE
643static void
644symbols_do (Hash_processor processor, void *processor_data)
40675e7c 645{
0fb1efaf 646 hash_do_for_each (symbol_table, processor, processor_data);
40675e7c 647}
2f1afb73
AD
648
649
650/*--------------------------------------------------------------.
651| Check that all the symbols are defined. Report any undefined |
652| symbols and consider them nonterminals. |
653`--------------------------------------------------------------*/
654
655void
656symbols_check_defined (void)
657{
0fb1efaf 658 symbols_do (symbol_check_defined_processor, NULL);
2f1afb73
AD
659}
660
661/*------------------------------------------------------------------.
662| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
663| number. |
664`------------------------------------------------------------------*/
665
666static void
667symbols_token_translations_init (void)
668{
a3714bce 669 bool num_256_available_p = true;
2f1afb73
AD
670 int i;
671
672 /* Find the highest user token number, and whether 256, the POSIX
673 preferred user token number for the error token, is used. */
674 max_user_token_number = 0;
675 for (i = 0; i < ntokens; ++i)
676 {
17ee7397 677 symbol *this = symbols[i];
2f1afb73
AD
678 if (this->user_token_number != USER_NUMBER_UNDEFINED)
679 {
680 if (this->user_token_number > max_user_token_number)
681 max_user_token_number = this->user_token_number;
682 if (this->user_token_number == 256)
a3714bce 683 num_256_available_p = false;
2f1afb73
AD
684 }
685 }
686
687 /* If 256 is not used, assign it to error, to follow POSIX. */
688 if (num_256_available_p
689 && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
690 errtoken->user_token_number = 256;
691
692 /* Set the missing user numbers. */
693 if (max_user_token_number < 256)
694 max_user_token_number = 256;
695
696 for (i = 0; i < ntokens; ++i)
697 {
17ee7397 698 symbol *this = symbols[i];
2f1afb73
AD
699 if (this->user_token_number == USER_NUMBER_UNDEFINED)
700 this->user_token_number = ++max_user_token_number;
701 if (this->user_token_number > max_user_token_number)
702 max_user_token_number = this->user_token_number;
703 }
704
da2a7671
PE
705 token_translations = xnmalloc (max_user_token_number + 1,
706 sizeof *token_translations);
2f1afb73
AD
707
708 /* Initialize all entries for literal tokens to 2, the internal
88bce5a2
AD
709 token number for $undefined, which represents all invalid inputs.
710 */
2f1afb73
AD
711 for (i = 0; i < max_user_token_number + 1; i++)
712 token_translations[i] = undeftoken->number;
0fb1efaf 713 symbols_do (symbol_translation_processor, NULL);
2f1afb73
AD
714}
715
716
717/*----------------------------------------------------------------.
718| Assign symbol numbers, and write definition of token names into |
719| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
720`----------------------------------------------------------------*/
721
722void
723symbols_pack (void)
724{
0fb1efaf 725 symbols_do (symbol_check_alias_consistency_processor, NULL);
6d0ef4ec
JD
726
727 symbols = xcalloc (nsyms, sizeof *symbols);
0fb1efaf 728 symbols_do (symbol_pack_processor, NULL);
2f1afb73 729
6d0ef4ec
JD
730 /* Aliases leave empty slots in symbols, so remove them. */
731 {
732 int writei;
733 int readi;
734 int nsyms_old = nsyms;
735 for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
736 {
737 if (symbols[readi] == NULL)
738 {
739 nsyms -= 1;
740 ntokens -= 1;
741 }
742 else
743 {
744 symbols[writei] = symbols[readi];
745 symbols[writei]->number = writei;
746 if (symbols[writei]->alias)
747 symbols[writei]->alias->number = writei;
748 writei += 1;
749 }
750 }
751 }
752 symbols = xnrealloc (symbols, nsyms, sizeof *symbols);
753
2f1afb73
AD
754 symbols_token_translations_init ();
755
756 if (startsymbol->class == unknown_sym)
ee000ba4 757 fatal_at (startsymbol_location,
dafdc66f 758 _("the start symbol %s is undefined"),
97650f4e 759 startsymbol->tag);
2f1afb73 760 else if (startsymbol->class == token_sym)
ee000ba4 761 fatal_at (startsymbol_location,
dafdc66f 762 _("the start symbol %s is a token"),
97650f4e 763 startsymbol->tag);
2f1afb73 764}
ec5479ce
JD
765
766
767/*-----------------------------------.
768| Set default %destructor/%printer. |
769`-----------------------------------*/
770
771void
772default_destructor_set (const char *destructor, location loc)
773{
774 if (default_destructor != NULL)
775 {
776 complain_at (loc, _("redeclaration for default %%destructor"));
777 complain_at (default_destructor_location, _("previous declaration"));
778 }
779 default_destructor = destructor;
780 default_destructor_location = loc;
781}
782
783void
784default_printer_set (const char *printer, location loc)
785{
786 if (default_printer != NULL)
787 {
788 complain_at (loc, _("redeclaration for default %%printer"));
789 complain_at (default_printer_location, _("previous declaration"));
790 }
791 default_printer = printer;
792 default_printer_location = loc;
793}