/[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.24 by akim, Sat May 4 08:48:04 2002 UTC revision 1.25 by akim, Mon Jun 10 08:35:39 2002 UTC
# Line 21  Line 21 
21    
22  #include "system.h"  #include "system.h"
23  #include "hash.h"  #include "hash.h"
24    #include "complain.h"
25  #include "symtab.h"  #include "symtab.h"
26  #include "gram.h"  #include "gram.h"
27    
28    /*------------------------.
29    | Distinguished symbols.  |
30    `------------------------*/
31    
32    symbol_t *errtoken = NULL;
33    symbol_t *undeftoken = NULL;
34    symbol_t *eoftoken = NULL;
35    symbol_t *axiom = NULL;
36    symbol_t *startsymbol = NULL;
37    
38  /*---------------------------------.  /*---------------------------------.
39  | Create a new symbol, named TAG.  |  | Create a new symbol, named TAG.  |
40  `---------------------------------*/  `---------------------------------*/
# Line 65  symbol_free (symbol_t *this) Line 76  symbol_free (symbol_t *this)
76  }  }
77    
78    
79    /*-----------------------------------------------------------.
80    | If THIS is not defined, report an error, and consider it a |
81    | nonterminal.                                               |
82    `-----------------------------------------------------------*/
83    
84    static bool
85    symbol_check_defined (symbol_t *this)
86    {
87      if (this->class == unknown_sym)
88        {
89          complain
90            (_("symbol %s is used, but is not defined as a token and has no rules"),
91             this->tag);
92          this->class = nterm_sym;
93          this->number = nvars++;
94        }
95    
96      return TRUE;
97    }
98    
99    
100    /*-------------------------------------------------------------------.
101    | Declare the new SYMBOL.  Make it an alias of SYMVAL, and type them |
102    | with TYPENAME.                                                     |
103    `-------------------------------------------------------------------*/
104    
105    void
106    symbol_make_alias (symbol_t *symbol, symbol_t *symval, char *typename)
107    {
108      if (symval->alias)
109        warn (_("symbol `%s' used more than once as a literal string"),
110              symval->tag);
111      else if (symbol->alias)
112        warn (_("symbol `%s' given more than one literal string"),
113              symbol->tag);
114      else
115        {
116          symval->class = token_sym;
117          symval->type_name = typename;
118          symval->user_token_number = symbol->user_token_number;
119          symbol->user_token_number = USER_NUMBER_ALIAS;
120          symval->alias = symbol;
121          symbol->alias = symval;
122          /* symbol and symval combined are only one symbol */
123          nsyms--;
124          ntokens--;
125          assert (ntokens == symbol->number || ntokens == symval->number);
126          symbol->number = symval->number =
127            (symval->number < symbol->number) ? symval->number : symbol->number;
128        }
129    }
130    
131    
132    /*---------------------------------------------------------.
133    | Check that THIS, and its alias, have same precedence and |
134    | associativity.                                           |
135    `---------------------------------------------------------*/
136    
137    static bool
138    symbol_check_alias_consistence (symbol_t *this)
139    {
140      /* Check only those who _are_ the aliases. */
141      if (this->alias && this->user_token_number == USER_NUMBER_ALIAS)
142        {
143          if (this->prec != this->alias->prec)
144            {
145              if (this->prec != 0 && this->alias->prec != 0)
146                complain (_("conflicting precedences for %s and %s"),
147                          this->tag, this->alias->tag);
148              if (this->prec != 0)
149                this->alias->prec = this->prec;
150              else
151                this->prec = this->alias->prec;
152            }
153    
154          if (this->assoc != this->alias->assoc)
155            {
156              if (this->assoc != 0 && this->alias->assoc != 0)
157                complain (_("conflicting assoc values for %s and %s"),
158                          this->tag, this->alias->tag);
159              if (this->assoc != 0)
160                this->alias->assoc = this->assoc;
161              else
162                this->assoc = this->alias->assoc;
163            }
164        }
165      return TRUE;
166    }
167    
168    
169    /*-------------------------------------------------------------------.
170    | Assign a symbol number, and write the definition of the token name |
171    | into FDEFINES.  Put in SYMBOLS.                                    |
172    `-------------------------------------------------------------------*/
173    
174    static bool
175    symbol_pack (symbol_t *this)
176    {
177      if (this->class == nterm_sym)
178        {
179          this->number += ntokens;
180        }
181      else if (this->alias)
182        {
183          /* This symbol and its alias are a single token defn.
184             Allocate a tokno, and assign to both check agreement of
185             prec and assoc fields and make both the same */
186          if (this->number == NUMBER_UNDEFINED)
187            {
188              if (this == eoftoken || this->alias == eoftoken)
189                this->number = this->alias->number = 0;
190              else
191                {
192                  assert (this->alias->number != NUMBER_UNDEFINED);
193                  this->number = this->alias->number;
194                }
195            }
196          /* Do not do processing below for USER_NUMBER_ALIASs.  */
197          if (this->user_token_number == USER_NUMBER_ALIAS)
198            return TRUE;
199        }
200      else /* this->class == token_sym */
201        {
202          assert (this->number != NUMBER_UNDEFINED);
203        }
204    
205      symbols[this->number] = this;
206      return TRUE;
207    }
208    
209    
210    
211    
212    /*--------------------------------------------------.
213    | Put THIS in TOKEN_TRANSLATIONS if it is a token.  |
214    `--------------------------------------------------*/
215    
216    static bool
217    symbol_translation (symbol_t *this)
218    {
219      /* Non-terminal? */
220      if (this->class == token_sym
221          && this->user_token_number != USER_NUMBER_ALIAS)
222        {
223          /* A token which translation has already been set? */
224          if (token_translations[this->user_token_number] != undeftoken->number)
225            complain (_("tokens %s and %s both assigned number %d"),
226                      symbols[token_translations[this->user_token_number]]->tag,
227                      this->tag, this->user_token_number);
228    
229          token_translations[this->user_token_number] = this->number;
230        }
231    
232      return TRUE;
233    }
234    
235    
236  /*----------------------.  /*----------------------.
237  | A symbol_t hash table.  |  | A symbol hash table.  |
238  `----------------------*/  `----------------------*/
239    
240  /* Initial capacity of symbols hash table.  */  /* Initial capacity of symbols hash table.  */
# Line 89  hash_symbol_t (const symbol_t *m, unsign Line 256  hash_symbol_t (const symbol_t *m, unsign
256    
257    
258  /*-------------------------------.  /*-------------------------------.
259  | Create the symbol_t hash table.  |  | Create the symbol hash table.  |
260  `-------------------------------*/  `-------------------------------*/
261    
262  void  void
# Line 150  symbols_do (symbol_processor processor, Line 317  symbols_do (symbol_processor processor,
317                      (Hash_processor) processor,                      (Hash_processor) processor,
318                      processor_data);                      processor_data);
319  }  }
320    
321    
322    /*--------------------------------------------------------------.
323    | Check that all the symbols are defined.  Report any undefined |
324    | symbols and consider them nonterminals.                       |
325    `--------------------------------------------------------------*/
326    
327    void
328    symbols_check_defined (void)
329    {
330      symbols_do (symbol_check_defined, NULL);
331    }
332    
333    /*------------------------------------------------------------------.
334    | Set TOKEN_TRANSLATIONS.  Check that no two symbols share the same |
335    | number.                                                           |
336    `------------------------------------------------------------------*/
337    
338    static void
339    symbols_token_translations_init (void)
340    {
341      int num_256_available_p = TRUE;
342      int i;
343    
344      /* Find the highest user token number, and whether 256, the POSIX
345         preferred user token number for the error token, is used.  */
346      max_user_token_number = 0;
347      for (i = 0; i < ntokens; ++i)
348        {
349          symbol_t *this = symbols[i];
350          if (this->user_token_number != USER_NUMBER_UNDEFINED)
351            {
352              if (this->user_token_number > max_user_token_number)
353                max_user_token_number = this->user_token_number;
354              if (this->user_token_number == 256)
355                num_256_available_p = FALSE;
356            }
357        }
358    
359      /* If 256 is not used, assign it to error, to follow POSIX.  */
360      if (num_256_available_p
361          && errtoken->user_token_number == USER_NUMBER_UNDEFINED)
362        errtoken->user_token_number = 256;
363    
364      /* Set the missing user numbers. */
365      if (max_user_token_number < 256)
366        max_user_token_number = 256;
367    
368      for (i = 0; i < ntokens; ++i)
369        {
370          symbol_t *this = symbols[i];
371          if (this->user_token_number == USER_NUMBER_UNDEFINED)
372            this->user_token_number = ++max_user_token_number;
373          if (this->user_token_number > max_user_token_number)
374            max_user_token_number = this->user_token_number;
375        }
376    
377      token_translations = XCALLOC (symbol_number_t, max_user_token_number + 1);
378    
379      /* Initialize all entries for literal tokens to 2, the internal
380         token number for $undefined., which represents all invalid
381         inputs.  */
382      for (i = 0; i < max_user_token_number + 1; i++)
383        token_translations[i] = undeftoken->number;
384      symbols_do (symbol_translation, NULL);
385    }
386    
387    
388    /*----------------------------------------------------------------.
389    | Assign symbol numbers, and write definition of token names into |
390    | FDEFINES.  Set up vectors SYMBOL_TABLE, TAGS of symbols.        |
391    `----------------------------------------------------------------*/
392    
393    void
394    symbols_pack (void)
395    {
396      symbols = XCALLOC (symbol_t *, nsyms);
397    
398      symbols_do (symbol_check_alias_consistence, NULL);
399      symbols_do (symbol_pack, NULL);
400    
401      symbols_token_translations_init ();
402    
403      if (startsymbol->class == unknown_sym)
404        fatal (_("the start symbol %s is undefined"), startsymbol->tag);
405      else if (startsymbol->class == token_sym)
406        fatal (_("the start symbol %s is a token"), startsymbol->tag);
407    }

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25

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