⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symtab.c

📁 GNU的词法/语法分析器bison源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (orig->printer || alias->printer)    {      if (orig->printer)	symbol_printer_set (alias, orig->printer, orig->printer_location);      else	symbol_printer_set (orig, alias->printer, alias->printer_location);    }  if (alias->prec || orig->prec)    {      if (orig->prec)	symbol_precedence_set (alias, orig->prec, orig->assoc,			       orig->prec_location);      else	symbol_precedence_set (orig, alias->prec, alias->assoc,			       alias->prec_location);    }}static boolsymbol_check_alias_consistency_processor (void *this,					  void *null ATTRIBUTE_UNUSED){  symbol_check_alias_consistency (this);  return true;}/*-------------------------------------------------------------------.| Assign a symbol number, and write the definition of the token name || into FDEFINES.  Put in SYMBOLS.                                    |`-------------------------------------------------------------------*/static inline boolsymbol_pack (symbol *this){  if (this->class == nterm_sym)    {      this->number += ntokens;    }  else if (this->alias)    {      /* This symbol and its alias are a single token defn.	 Allocate a tokno, and assign to both check agreement of	 prec and assoc fields and make both the same */      if (this->number == NUMBER_UNDEFINED)	{	  if (this == endtoken || this->alias == endtoken)	    this->number = this->alias->number = 0;	  else	    {	      if (this->alias->number == NUMBER_UNDEFINED)		abort ();	      this->number = this->alias->number;	    }	}      /* Do not do processing below for USER_NUMBER_ALIASes.  */      if (this->user_token_number == USER_NUMBER_ALIAS)	return true;    }  else /* this->class == token_sym */    {      if (this->number == NUMBER_UNDEFINED)	abort ();    }  symbols[this->number] = this;  return true;}static boolsymbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED){  return symbol_pack (this);}/*--------------------------------------------------.| Put THIS in TOKEN_TRANSLATIONS if it is a token.  |`--------------------------------------------------*/static inline boolsymbol_translation (symbol *this){  /* Non-terminal? */  if (this->class == token_sym      && this->user_token_number != USER_NUMBER_ALIAS)    {      /* A token which translation has already been set? */      if (token_translations[this->user_token_number] != undeftoken->number)	complain_at (this->location,		     _("tokens %s and %s both assigned number %d"),		     symbols[token_translations[this->user_token_number]]->tag,		     this->tag, this->user_token_number);      token_translations[this->user_token_number] = this->number;    }  return true;}static boolsymbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED){  return symbol_translation (this);}/*----------------------.| A symbol hash table.  |`----------------------*//* Initial capacity of symbols hash table.  */#define HT_INITIAL_CAPACITY 257static struct hash_table *symbol_table = NULL;static inline boolhash_compare_symbol (const symbol *m1, const symbol *m2){  /* Since tags are unique, we can compare the pointers themselves.  */  return UNIQSTR_EQ (m1->tag, m2->tag);}static boolhash_symbol_comparator (void const *m1, void const *m2){  return hash_compare_symbol (m1, m2);}static inline size_thash_symbol (const symbol *m, size_t tablesize){  /* Since tags are unique, we can hash the pointer itself.  */  return ((uintptr_t) m->tag) % tablesize;}static size_thash_symbol_hasher (void const *m, size_t tablesize){  return hash_symbol (m, tablesize);}/*-------------------------------.| Create the symbol hash table.  |`-------------------------------*/voidsymbols_new (void){  symbol_table = hash_initialize (HT_INITIAL_CAPACITY,				  NULL,				  hash_symbol_hasher,				  hash_symbol_comparator,				  free);}/*----------------------------------------------------------------.| Find the symbol named KEY, and return it.  If it does not exist || yet, create it.                                                 |`----------------------------------------------------------------*/symbol *symbol_get (const char *key, location loc){  symbol probe;  symbol *entry;  key = uniqstr_new (key);  probe.tag = key;  entry = hash_lookup (symbol_table, &probe);  if (!entry)    {      /* First insertion in the hash. */      entry = symbol_new (key, loc);      hash_insert (symbol_table, entry);    }  return entry;}/*------------------------------------------------------------------.| Generate a dummy nonterminal, whose name cannot conflict with the || user's names.                                                     |`------------------------------------------------------------------*/symbol *dummy_symbol_get (location loc){  /* Incremented for each generated symbol.  */  static int dummy_count = 0;  static char buf[256];  symbol *sym;  sprintf (buf, "@%d", ++dummy_count);  sym = symbol_get (buf, loc);  sym->class = nterm_sym;  sym->number = nvars++;  return sym;}/*-------------------.| Free the symbols.  |`-------------------*/voidsymbols_free (void){  hash_free (symbol_table);  free (symbols);}/*---------------------------------------------------------------.| Look for undefined symbols, report an error, and consider them || terminals.                                                     |`---------------------------------------------------------------*/static voidsymbols_do (Hash_processor processor, void *processor_data){  hash_do_for_each (symbol_table, processor, processor_data);}/*--------------------------------------------------------------.| Check that all the symbols are defined.  Report any undefined || symbols and consider them nonterminals.                       |`--------------------------------------------------------------*/voidsymbols_check_defined (void){  symbols_do (symbol_check_defined_processor, NULL);}/*------------------------------------------------------------------.| Set TOKEN_TRANSLATIONS.  Check that no two symbols share the same || number.                                                           |`------------------------------------------------------------------*/static voidsymbols_token_translations_init (void){  bool num_256_available_p = true;  int i;  /* Find the highest user token number, and whether 256, the POSIX     preferred user token number for the error token, is used.  */  max_user_token_number = 0;  for (i = 0; i < ntokens; ++i)    {      symbol *this = symbols[i];      if (this->user_token_number != USER_NUMBER_UNDEFINED)	{	  if (this->user_token_number > max_user_token_number)	    max_user_token_number = this->user_token_number;	  if (this->user_token_number == 256)	    num_256_available_p = false;	}    }  /* If 256 is not used, assign it to error, to follow POSIX.  */  if (num_256_available_p      && errtoken->user_token_number == USER_NUMBER_UNDEFINED)    errtoken->user_token_number = 256;  /* Set the missing user numbers. */  if (max_user_token_number < 256)    max_user_token_number = 256;  for (i = 0; i < ntokens; ++i)    {      symbol *this = symbols[i];      if (this->user_token_number == USER_NUMBER_UNDEFINED)	this->user_token_number = ++max_user_token_number;      if (this->user_token_number > max_user_token_number)	max_user_token_number = this->user_token_number;    }  token_translations = xnmalloc (max_user_token_number + 1,				 sizeof *token_translations);  /* Initialize all entries for literal tokens to 2, the internal     token number for $undefined, which represents all invalid inputs.     */  for (i = 0; i < max_user_token_number + 1; i++)    token_translations[i] = undeftoken->number;  symbols_do (symbol_translation_processor, NULL);}/*----------------------------------------------------------------.| Assign symbol numbers, and write definition of token names into || FDEFINES.  Set up vectors SYMBOL_TABLE, TAGS of symbols.        |`----------------------------------------------------------------*/voidsymbols_pack (void){  symbols = xcalloc (nsyms, sizeof *symbols);  symbols_do (symbol_check_alias_consistency_processor, NULL);  symbols_do (symbol_pack_processor, NULL);  symbols_token_translations_init ();  if (startsymbol->class == unknown_sym)    fatal_at (startsymbol_location,	      _("the start symbol %s is undefined"),	      startsymbol->tag);  else if (startsymbol->class == token_sym)    fatal_at (startsymbol_location,	      _("the start symbol %s is a token"),	      startsymbol->tag);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -