/[bison]/bison/src/symtab.c
ViewVC logotype

Diff of /bison/src/symtab.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.52 by eggert, Thu Nov 21 05:23:46 2002 UTC revision 1.53 by eggert, Wed Dec 11 06:52:55 2002 UTC
# Line 20  Line 20 
20    
21    
22  #include "system.h"  #include "system.h"
23  #include "quotearg.h"  
24  #include "hash.h"  #include <hash.h>
25    #include <quotearg.h>
26    
27  #include "complain.h"  #include "complain.h"
 #include "symtab.h"  
28  #include "gram.h"  #include "gram.h"
29    #include "symtab.h"
30    
31  /*------------------------.  /*------------------------.
32  | Distinguished symbols.  |  | Distinguished symbols.  |
33  `------------------------*/  `------------------------*/
34    
35  symbol_t *errtoken = NULL;  symbol *errtoken = NULL;
36  symbol_t *undeftoken = NULL;  symbol *undeftoken = NULL;
37  symbol_t *endtoken = NULL;  symbol *endtoken = NULL;
38  symbol_t *accept = NULL;  symbol *accept = NULL;
39  symbol_t *startsymbol = NULL;  symbol *startsymbol = NULL;
40  location_t startsymbol_location;  location startsymbol_location;
41    
42  /*---------------------------------.  /*---------------------------------.
43  | Create a new symbol, named TAG.  |  | Create a new symbol, named TAG.  |
44  `---------------------------------*/  `---------------------------------*/
45    
46  static symbol_t *  static symbol *
47  symbol_new (struniq_t tag, location_t location)  symbol_new (uniqstr tag, location loc)
48  {  {
49    symbol_t *res = XMALLOC (symbol_t, 1);    symbol *res = XMALLOC (symbol, 1);
50    
51    struniq_assert (tag);    uniqstr_assert (tag);
52    res->tag = tag;    res->tag = tag;
53    res->location = location;    res->location = loc;
54    
55    res->type_name = NULL;    res->type_name = NULL;
56    res->destructor = NULL;    res->destructor = NULL;
# Line 67  symbol_new (struniq_t tag, location_t lo Line 69  symbol_new (struniq_t tag, location_t lo
69  }  }
70    
71    
72  /*------------------------------------------------------------------.  /*-----------------------------------------------------------------.
73  | Set the TYPE_NAME associated to SYMBOL.  Does nothing if passed 0 |  | Set the TYPE_NAME associated with SYM.  Does nothing if passed 0 |
74  | as TYPE_NAME.                                                     |  | as TYPE_NAME.                                                    |
75  `------------------------------------------------------------------*/  `-----------------------------------------------------------------*/
76    
77  void  void
78  symbol_type_set (symbol_t *symbol, struniq_t type_name, location_t location)  symbol_type_set (symbol *sym, uniqstr type_name, location loc)
79  {  {
80    if (type_name)    if (type_name)
81      {      {
82        if (symbol->type_name)        if (sym->type_name)
83          complain_at (location,          complain_at (loc, _("type redeclaration for %s"), sym->tag);
84                       _("type redeclaration for %s"), symbol->tag);        uniqstr_assert (type_name);
85        struniq_assert (type_name);        sym->type_name = type_name;
       symbol->type_name = type_name;  
86      }      }
87  }  }
88    
89    
90  /*-------------------------------------------------------------------.  /*------------------------------------------------------------------.
91  | Set the DESTRUCTOR associated to SYMBOL.  Do nothing if passed 0.  |  | Set the DESTRUCTOR associated with SYM.  Do nothing if passed 0.  |
92  `-------------------------------------------------------------------*/  `------------------------------------------------------------------*/
93    
94  void  void
95  symbol_destructor_set (symbol_t *symbol, char *destructor, location_t location)  symbol_destructor_set (symbol *sym, char *destructor, location loc)
96  {  {
97    if (destructor)    if (destructor)
98      {      {
99        if (symbol->destructor)        if (sym->destructor)
100          complain_at (location,          complain_at (loc, _("%s redeclaration for %s"),
101                       _("%s redeclaration for %s"),                       "%destructor", sym->tag);
102                       "%destructor", symbol->tag);        sym->destructor = destructor;
103        symbol->destructor = destructor;        sym->destructor_location = loc;
       symbol->destructor_location = location;  
104      }      }
105  }  }
106    
107    
108  /*----------------------------------------------------------------.  /*---------------------------------------------------------------.
109  | Set the PRINTER associated to SYMBOL.  Do nothing if passed 0.  |  | Set the PRINTER associated with SYM.  Do nothing if passed 0.  |
110  `----------------------------------------------------------------*/  `---------------------------------------------------------------*/
111    
112  void  void
113  symbol_printer_set (symbol_t *symbol, char *printer, location_t location)  symbol_printer_set (symbol *sym, char *printer, location loc)
114  {  {
115    if (printer)    if (printer)
116      {      {
117        if (symbol->printer)        if (sym->printer)
118          complain_at (location,          complain_at (loc, _("%s redeclaration for %s"),
119                       _("%s redeclaration for %s"),                       "%printer", sym->tag);
120                       "%printer", symbol->tag);        sym->printer = printer;
121        symbol->printer = printer;        sym->printer_location = loc;
       symbol->printer_location = location;  
122      }      }
123  }  }
124    
125    
126  /*------------------------------------------------------------------.  /*-----------------------------------------------------------------.
127  | Set the PRECEDENCE associated to SYMBOL.  Does nothing if invoked |  | Set the PRECEDENCE associated with SYM.  Does nothing if invoked |
128  | with UNDEF_ASSOC as ASSOC.                                        |  | with UNDEF_ASSOC as ASSOC.                                       |
129  `------------------------------------------------------------------*/  `-----------------------------------------------------------------*/
130    
131  void  void
132  symbol_precedence_set (symbol_t *symbol,  symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
                        int prec, assoc_t assoc, location_t location)  
133  {  {
134    if (assoc != undef_assoc)    if (a != undef_assoc)
135      {      {
136        if (symbol->prec != 0)        if (sym->prec != 0)
137          complain_at (location,          complain_at (loc, _("redefining precedence of %s"), sym->tag);
138                       _("redefining precedence of %s"),        sym->prec = prec;
139                       symbol->tag);        sym->assoc = a;
       symbol->prec = prec;  
       symbol->assoc = assoc;  
140      }      }
141    
142    /* Only terminals have a precedence. */    /* Only terminals have a precedence. */
143    symbol_class_set (symbol, token_sym, location);    symbol_class_set (sym, token_sym, loc);
144  }  }
145    
146    
147  /*-------------------------------------.  /*------------------------------------.
148  | Set the CLASS associated to SYMBOL.  |  | Set the CLASS associated with SYM.  |
149  `-------------------------------------*/  `------------------------------------*/
150    
151  void  void
152  symbol_class_set (symbol_t *symbol, symbol_class class, location_t location)  symbol_class_set (symbol *sym, symbol_class class, location loc)
153  {  {
154    if (symbol->class != unknown_sym && symbol->class != class)    if (sym->class != unknown_sym && sym->class != class)
155      complain_at (location, _("symbol %s redefined"), symbol->tag);      complain_at (loc, _("symbol %s redefined"), sym->tag);
156    
157    if (class == nterm_sym && symbol->class != nterm_sym)    if (class == nterm_sym && sym->class != nterm_sym)
158      symbol->number = nvars++;      sym->number = nvars++;
159    else if (class == token_sym && symbol->number == NUMBER_UNDEFINED)    else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
160      symbol->number = ntokens++;      sym->number = ntokens++;
161    
162    symbol->class = class;    sym->class = class;
163  }  }
164    
165    
166  /*-------------------------------------------------.  /*------------------------------------------------.
167  | Set the USER_TOKEN_NUMBER associated to SYMBOL.  |  | Set the USER_TOKEN_NUMBER associated with SYM.  |
168  `-------------------------------------------------*/  `------------------------------------------------*/
169    
170  void  void
171  symbol_user_token_number_set (symbol_t *symbol,  symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
                               int user_token_number, location_t location)  
172  {  {
173    if (symbol->class != token_sym)    if (sym->class != token_sym)
174      abort ();      abort ();
175    
176    if (symbol->user_token_number != USER_NUMBER_UNDEFINED    if (sym->user_token_number != USER_NUMBER_UNDEFINED
177        && symbol->user_token_number != user_token_number)        && sym->user_token_number != user_token_number)
178      complain_at (location, _("redefining user token number of %s"),      complain_at (loc, _("redefining user token number of %s"), sym->tag);
                  symbol->tag);  
179    
180    symbol->user_token_number = user_token_number;    sym->user_token_number = user_token_number;
181    /* User defined $end token? */    /* User defined $end token? */
182    if (user_token_number == 0)    if (user_token_number == 0)
183      {      {
184        endtoken = symbol;        endtoken = sym;
185        endtoken->number = 0;        endtoken->number = 0;
186        /* It is always mapped to 0, so it was already counted in        /* It is always mapped to 0, so it was already counted in
187           NTOKENS.  */           NTOKENS.  */
# Line 196  symbol_user_token_number_set (symbol_t * Line 190  symbol_user_token_number_set (symbol_t *
190  }  }
191    
192    
193  /*------------.  /*-----------.
194  | Free THIS.  |  | Free SYM.  |
195  `------------*/  `-----------*/
196    
197  static void  static void
198  symbol_free (symbol_t *this)  symbol_free (symbol *sym)
199  {  {
200    free (this);    free (sym);
201  }  }
202    
203    
204  /*-----------------------------------------------------------.  /*----------------------------------------------------------.
205  | If THIS is not defined, report an error, and consider it a |  | If SYM is not defined, report an error, and consider it a |
206  | nonterminal.                                               |  | nonterminal.                                              |
207  `-----------------------------------------------------------*/  `----------------------------------------------------------*/
208    
209  static bool  static bool
210  symbol_check_defined (symbol_t *this)  symbol_check_defined (symbol *sym)
211  {  {
212    if (this->class == unknown_sym)    if (sym->class == unknown_sym)
213      {      {
214        complain_at        complain_at
215          (this->location,          (sym->location,
216           _("symbol %s is used, but is not defined as a token and has no rules"),           _("symbol %s is used, but is not defined as a token and has no rules"),
217           this->tag);           sym->tag);
218        this->class = nterm_sym;        sym->class = nterm_sym;
219        this->number = nvars++;        sym->number = nvars++;
220      }      }
221    
222    return true;    return true;
223  }  }
224    
225    
226  /*-------------------------------------------------------------------.  /*------------------------------------------------------------------.
227  | Declare the new SYMBOL.  Make it an alias of SYMVAL, and type them |  | Declare the new symbol SYM.  Make it an alias of SYMVAL, and type |
228  | with TYPENAME.                                                     |  | them with TYPENAME.                                               |
229  `-------------------------------------------------------------------*/  `------------------------------------------------------------------*/
230    
231  void  void
232  symbol_make_alias (symbol_t *symbol, symbol_t *symval, location_t loc)  symbol_make_alias (symbol *sym, symbol *symval, location loc)
233  {  {
234    if (symval->alias)    if (symval->alias)
235      warn_at (loc, _("symbol `%s' used more than once as a literal string"),      warn_at (loc, _("symbol `%s' used more than once as a literal string"),
236            symval->tag);            symval->tag);
237    else if (symbol->alias)    else if (sym->alias)
238      warn_at (loc, _("symbol `%s' given more than one literal string"),      warn_at (loc, _("symbol `%s' given more than one literal string"),
239            symbol->tag);            sym->tag);
240    else    else
241      {      {
242        symval->class = token_sym;        symval->class = token_sym;
243        symval->user_token_number = symbol->user_token_number;        symval->user_token_number = sym->user_token_number;
244        symbol->user_token_number = USER_NUMBER_ALIAS;        sym->user_token_number = USER_NUMBER_ALIAS;
245        symval->alias = symbol;        symval->alias = sym;
246        symbol->alias = symval;        sym->alias = symval;
247        /* symbol and symval combined are only one symbol */        /* sym and symval combined are only one symbol.  */
248        nsyms--;        nsyms--;
249        ntokens--;        ntokens--;
250        if (ntokens != symbol->number && ntokens != symval->number)        if (ntokens != sym->number && ntokens != symval->number)
251          abort ();          abort ();
252        symbol->number = symval->number =        sym->number = symval->number =
253          (symval->number < symbol->number) ? symval->number : symbol->number;          (symval->number < sym->number) ? symval->number : sym->number;
254      }      }
255  }  }
256    
# Line 267  symbol_make_alias (symbol_t *symbol, sym Line 261  symbol_make_alias (symbol_t *symbol, sym
261  `---------------------------------------------------------*/  `---------------------------------------------------------*/
262    
263  static bool  static bool
264  symbol_check_alias_consistence (symbol_t *this)  symbol_check_alias_consistence (symbol *this)
265  {  {
266    /* Check only those who _are_ the aliases. */    /* Check only those who _are_ the aliases. */
267    if (this->alias && this->user_token_number == USER_NUMBER_ALIAS)    if (this->alias && this->user_token_number == USER_NUMBER_ALIAS)
# Line 307  symbol_check_alias_consistence (symbol_t Line 301  symbol_check_alias_consistence (symbol_t
301  `-------------------------------------------------------------------*/  `-------------------------------------------------------------------*/
302    
303  static bool  static bool
304  symbol_pack (symbol_t *this)  symbol_pack (symbol *this)
305  {  {
306    if (this->class == nterm_sym)    if (this->class == nterm_sym)
307      {      {
# Line 351  symbol_pack (symbol_t *this) Line 345  symbol_pack (symbol_t *this)
345  `--------------------------------------------------*/  `--------------------------------------------------*/
346    
347  static bool  static bool
348  symbol_translation (symbol_t *this)  symbol_translation (symbol *this)
349  {  {
350    /* Non-terminal? */    /* Non-terminal? */
351    if (this->class == token_sym    if (this->class == token_sym
# Line 381  symbol_translation (symbol_t *this) Line 375  symbol_translation (symbol_t *this)
375  static struct hash_table *symbol_table = NULL;  static struct hash_table *symbol_table = NULL;
376    
377  static bool  static bool
378  hash_compare_symbol (const symbol_t *m1, const symbol_t *m2)  hash_compare_symbol (const symbol *m1, const symbol *m2)
379  {  {
380    /* Since tags are unique, we can compare the pointers themselves.  */    /* Since tags are unique, we can compare the pointers themselves.  */
381    return STRUNIQ_EQ (m1->tag, m2->tag);    return UNIQSTR_EQ (m1->tag, m2->tag);
382  }  }
383    
384  static unsigned int  static unsigned int
385  hash_symbol (const symbol_t *m, unsigned int tablesize)  hash_symbol (const symbol *m, unsigned int tablesize)
386  {  {
387    /* Since tags are unique, we can hash the pointer itself.  */    /* Since tags are unique, we can hash the pointer itself.  */
388    return ((size_t) m->tag) % tablesize;    return ((size_t) m->tag) % tablesize;
# Line 415  symbols_new (void) Line 409  symbols_new (void)
409  | yet, create it.                                                 |  | yet, create it.                                                 |
410  `----------------------------------------------------------------*/  `----------------------------------------------------------------*/
411    
412  symbol_t *  symbol *
413  symbol_get (const char *key, location_t location)  symbol_get (const char *key, location loc)
414  {  {
415    symbol_t probe;    symbol probe;
416    symbol_t *entry;    symbol *entry;
417    
418    /* Keep the symbol in a printable form.  */    /* Keep the symbol in a printable form.  */
419    key = struniq_new (quotearg_style (escape_quoting_style, key));    key = uniqstr_new (quotearg_style (escape_quoting_style, key));
420    *(char const **) &probe.tag = key;    *(char const **) &probe.tag = key;
421    entry = hash_lookup (symbol_table, &probe);    entry = hash_lookup (symbol_table, &probe);
422    
423    if (!entry)    if (!entry)
424      {      {
425        /* First insertion in the hash. */        /* First insertion in the hash. */
426        entry = symbol_new (key, location);        entry = symbol_new (key, loc);
427        hash_insert (symbol_table, entry);        hash_insert (symbol_table, entry);
428      }      }
429    return entry;    return entry;
# Line 441  symbol_get (const char *key, location_t Line 435  symbol_get (const char *key, location_t
435  | user's names.                                                     |  | user's names.                                                     |
436  `------------------------------------------------------------------*/  `------------------------------------------------------------------*/
437    
438  symbol_t *  symbol *
439  dummy_symbol_get (location_t location)  dummy_symbol_get (location loc)
440  {  {
441    /* Incremented for each generated symbol.  */    /* Incremented for each generated symbol.  */
442    static int dummy_count = 0;    static int dummy_count = 0;
443    static char buf[256];    static char buf[256];
444    
445    symbol_t *sym;    symbol *sym;
446    
447    sprintf (buf, "@%d", ++dummy_count);    sprintf (buf, "@%d", ++dummy_count);
448    sym = symbol_get (buf, location);    sym = symbol_get (buf, loc);
449    sym->class = nterm_sym;    sym->class = nterm_sym;
450    sym->number = nvars++;    sym->number = nvars++;
451    return sym;    return sym;
# Line 511  symbols_token_translations_init (void) Line 505  symbols_token_translations_init (void)
505    max_user_token_number = 0;    max_user_token_number = 0;
506    for (i = 0; i < ntokens; ++i)    for (i = 0; i < ntokens; ++i)
507      {      {
508        symbol_t *this = symbols[i];        symbol *this = symbols[i];
509        if (this->user_token_number != USER_NUMBER_UNDEFINED)        if (this->user_token_number != USER_NUMBER_UNDEFINED)
510          {          {
511            if (this->user_token_number > max_user_token_number)            if (this->user_token_number > max_user_token_number)
# Line 532  symbols_token_translations_init (void) Line 526  symbols_token_translations_init (void)
526    
527    for (i = 0; i < ntokens; ++i)    for (i = 0; i < ntokens; ++i)
528      {      {
529        symbol_t *this = symbols[i];        symbol *this = symbols[i];
530        if (this->user_token_number == USER_NUMBER_UNDEFINED)        if (this->user_token_number == USER_NUMBER_UNDEFINED)
531          this->user_token_number = ++max_user_token_number;          this->user_token_number = ++max_user_token_number;
532        if (this->user_token_number > max_user_token_number)        if (this->user_token_number > max_user_token_number)
533          max_user_token_number = this->user_token_number;          max_user_token_number = this->user_token_number;
534      }      }
535    
536    token_translations = XCALLOC (symbol_number_t, max_user_token_number + 1);    token_translations = XCALLOC (symbol_number, max_user_token_number + 1);
537    
538    /* Initialize all entries for literal tokens to 2, the internal    /* Initialize all entries for literal tokens to 2, the internal
539       token number for $undefined, which represents all invalid inputs.       token number for $undefined, which represents all invalid inputs.
# Line 558  symbols_token_translations_init (void) Line 552  symbols_token_translations_init (void)
552  void  void
553  symbols_pack (void)  symbols_pack (void)
554  {  {
555    symbols = XCALLOC (symbol_t *, nsyms);    symbols = XCALLOC (symbol *, nsyms);
556    
557    symbols_do (symbol_check_alias_consistence, NULL);    symbols_do (symbol_check_alias_consistence, NULL);
558    symbols_do (symbol_pack, NULL);    symbols_do (symbol_pack, NULL);

Legend:
Removed from v.1.52  
changed lines
  Added in v.1.53

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26