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

Diff of /bison/src/reader.c

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

revision 1.179 by akim, Sun May 26 18:39:05 2002 UTC revision 1.180 by akim, Mon Jun 10 08:35:39 2002 UTC
# Line 51  typedef struct symbol_list Line 51  typedef struct symbol_list
51  int lineno;  int lineno;
52  static symbol_list *grammar = NULL;  static symbol_list *grammar = NULL;
53  static int start_flag = 0;  static int start_flag = 0;
 static symbol_t *startval = NULL;  
54    
55  /* Nonzero if components of semantic values are used, implying  /* Nonzero if components of semantic values are used, implying
56     they must be unions.  */     they must be unions.  */
# Line 63  static int typed = 0; Line 62  static int typed = 0;
62  /* Incremented for each %left, %right or %nonassoc seen */  /* Incremented for each %left, %right or %nonassoc seen */
63  static int lastprec = 0;  static int lastprec = 0;
64    
 symbol_t *errtoken = NULL;  
 symbol_t *undeftoken = NULL;  
 symbol_t *eoftoken = NULL;  
 symbol_t *axiom = NULL;  
   
65  static symbol_list *  static symbol_list *
66  symbol_list_new (symbol_t *sym)  symbol_list_new (symbol_t *sym)
67  {  {
# Line 81  symbol_list_new (symbol_t *sym) Line 75  symbol_list_new (symbol_t *sym)
75    return res;    return res;
76  }  }
77    
 /*------------------------.  
 | Operations on symbols.  |  
 `------------------------*/  
   
   
 /*-----------------------------------------------------------.  
 | If THIS is not defined, report an error, and consider it a |  
 | nonterminal.                                               |  
 `-----------------------------------------------------------*/  
   
 static bool  
 symbol_check_defined (symbol_t *this)  
 {  
   if (this->class == unknown_sym)  
     {  
       complain  
         (_("symbol %s is used, but is not defined as a token and has no rules"),  
          this->tag);  
       this->class = nterm_sym;  
       this->number = nvars++;  
     }  
   
   return TRUE;  
 }  
   
   
 /*-------------------------------------------------------------------.  
 | Assign a symbol number, and write the definition of the token name |  
 | into FDEFINES.  Put in SYMBOLS.                                    |  
 `-------------------------------------------------------------------*/  
   
 static bool  
 symbol_make_alias (symbol_t *symbol, char *typename)  
 {  
   if (symval->alias)  
     warn (_("symbol `%s' used more than once as a literal string"),  
           symval->tag);  
   else if (symbol->alias)  
     warn (_("symbol `%s' given more than one literal string"),  
           symbol->tag);  
   else  
     {  
       symval->class = token_sym;  
       symval->type_name = typename;  
       symval->user_token_number = symbol->user_token_number;  
       symbol->user_token_number = USER_NUMBER_ALIAS;  
       symval->alias = symbol;  
       symbol->alias = symval;  
       /* symbol and symval combined are only one symbol */  
       nsyms--;  
       ntokens--;  
       assert (ntokens == symbol->number || ntokens == symval->number);  
       symbol->number = symval->number =  
         (symval->number < symbol->number) ? symval->number : symbol->number;  
     }  
   
   return TRUE;  
 }  
   
 /*---------------------------------------------------------.  
 | Check that THIS, and its alias, have same precedence and |  
 | associativity.                                           |  
 `---------------------------------------------------------*/  
   
 static bool  
 symbol_check_alias_consistence (symbol_t *this)  
 {  
   /* Check only those who _are_ the aliases. */  
   if (this->alias && this->user_token_number == USER_NUMBER_ALIAS)  
     {  
       if (this->prec != this->alias->prec)  
         {  
           if (this->prec != 0 && this->alias->prec != 0)  
             complain (_("conflicting precedences for %s and %s"),  
                       this->tag, this->alias->tag);  
           if (this->prec != 0)  
             this->alias->prec = this->prec;  
           else  
             this->prec = this->alias->prec;  
         }  
   
       if (this->assoc != this->alias->assoc)  
         {  
           if (this->assoc != 0 && this->alias->assoc != 0)  
             complain (_("conflicting assoc values for %s and %s"),  
                       this->tag, this->alias->tag);  
           if (this->assoc != 0)  
             this->alias->assoc = this->assoc;  
           else  
             this->assoc = this->alias->assoc;  
         }  
     }  
   return TRUE;  
 }  
   
   
 /*-------------------------------------------------------------------.  
 | Assign a symbol number, and write the definition of the token name |  
 | into FDEFINES.  Put in SYMBOLS.                                    |  
 `-------------------------------------------------------------------*/  
   
 static bool  
 symbol_pack (symbol_t *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 == eoftoken || this->alias == eoftoken)  
             this->number = this->alias->number = 0;  
           else  
             {  
               assert (this->alias->number != NUMBER_UNDEFINED);  
               this->number = this->alias->number;  
             }  
         }  
       /* Do not do processing below for USER_NUMBER_ALIASs.  */  
       if (this->user_token_number == USER_NUMBER_ALIAS)  
         return TRUE;  
     }  
   else /* this->class == token_sym */  
     {  
       assert (this->number != NUMBER_UNDEFINED);  
     }  
   
   symbols[this->number] = this;  
   return TRUE;  
 }  
   
   
   
   
 /*--------------------------------------------------.  
 | Put THIS in TOKEN_TRANSLATIONS if it is a token.  |  
 `--------------------------------------------------*/  
   
 static bool  
 symbol_translation (symbol_t *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 (_("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;  
 }  
   
   
78  /*===================\  /*===================\
79  | Low level lexing.  |  | Low level lexing.  |
80  \===================*/  \===================*/
# Line 699  parse_token_decl (symbol_class what_is, Line 530  parse_token_decl (symbol_class what_is,
530          }          }
531        else if (token == tok_identifier && *symval->tag == '\"' && symbol)        else if (token == tok_identifier && *symval->tag == '\"' && symbol)
532          {          {
533            symbol_make_alias (symbol, typename);            symbol_make_alias (symbol, symval, typename);
534            symbol = NULL;            symbol = NULL;
535          }          }
536        else if (token == tok_identifier)        else if (token == tok_identifier)
# Line 762  parse_start_decl (void) Line 593  parse_start_decl (void)
593    else    else
594      {      {
595        start_flag = 1;        start_flag = 1;
596        startval = symval;        startsymbol = symval;
597      }      }
598  }  }
599    
# Line 1401  readgram (void) Line 1232  readgram (void)
1232    
1233              if (!start_flag)              if (!start_flag)
1234                {                {
1235                  startval = lhs;                  startsymbol = lhs;
1236                  start_flag = 1;                  start_flag = 1;
1237                }                }
1238    
# Line 1599  readgram (void) Line 1430  readgram (void)
1430      fatal (_("no rules in the input grammar"));      fatal (_("no rules in the input grammar"));
1431    
1432    /* Report any undefined symbols and consider them nonterminals.  */    /* Report any undefined symbols and consider them nonterminals.  */
1433    symbols_do (symbol_check_defined, NULL);    symbols_check_defined ();
1434    
1435    /* Insert the initial rule, which line is that of the first rule    /* Insert the initial rule, which line is that of the first rule
1436       (not that of the start symbol):       (not that of the start symbol):
# Line 1607  readgram (void) Line 1438  readgram (void)
1438       axiom: %start EOF.  */       axiom: %start EOF.  */
1439    p = symbol_list_new (axiom);    p = symbol_list_new (axiom);
1440    p->line = grammar->line;    p->line = grammar->line;
1441    p->next = symbol_list_new (startval);    p->next = symbol_list_new (startsymbol);
1442    p->next->next = symbol_list_new (eoftoken);    p->next->next = symbol_list_new (eoftoken);
1443    p->next->next->next = symbol_list_new (NULL);    p->next->next->next = symbol_list_new (NULL);
1444    p->next->next->next->next = grammar;    p->next->next->next->next = grammar;
1445    nrules += 1;    nrules += 1;
1446    nritems += 3;    nritems += 3;
1447    grammar = p;    grammar = p;
   startval = axiom;  
1448    
1449    if (nsyms > SHRT_MAX)    if (nsyms > SHRT_MAX)
1450      fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),      fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
# Line 1649  read_additionnal_code (void) Line 1479  read_additionnal_code (void)
1479  }  }
1480    
1481    
 /*------------------------------------------------------------------.  
 | Set TOKEN_TRANSLATIONS.  Check that no two symbols share the same |  
 | number.                                                           |  
 `------------------------------------------------------------------*/  
   
 static void  
 token_translations_init (void)  
 {  
   int 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_t *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_t *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 = XCALLOC (symbol_number_t, max_user_token_number + 1);  
   
   /* 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, NULL);  
 }  
   
   
 /*----------------------------------------------------------------.  
 | Assign symbol numbers, and write definition of token names into |  
 | FDEFINES.  Set up vectors SYMBOL_TABLE, TAGS of symbols.        |  
 `----------------------------------------------------------------*/  
   
 static void  
 packsymbols (void)  
 {  
   symbols = XCALLOC (symbol_t *, nsyms);  
   
   symbols_do (symbol_check_alias_consistence, NULL);  
   symbols_do (symbol_pack, NULL);  
   
   token_translations_init ();  
   
   if (startval->class == unknown_sym)  
     fatal (_("the start symbol %s is undefined"), startval->tag);  
   else if (startval->class == token_sym)  
     fatal (_("the start symbol %s is a token"), startval->tag);  
   
   start_symbol = startval->number;  
 }  
   
   
1482  /*---------------------------------------------------------------.  /*---------------------------------------------------------------.
1483  | Convert the rules into the representation using RRHS, RLHS and |  | Convert the rules into the representation using RRHS, RLHS and |
1484  | RITEM.                                                         |  | RITEM.                                                         |
# Line 1862  reader (void) Line 1613  reader (void)
1613    
1614    /* Assign the symbols their symbol numbers.  Write #defines for the    /* Assign the symbols their symbol numbers.  Write #defines for the
1615       token symbols into FDEFINES if requested.  */       token symbols into FDEFINES if requested.  */
1616    packsymbols ();    symbols_pack ();
1617    
1618    /* Convert the grammar into the format described in gram.h.  */    /* Convert the grammar into the format described in gram.h.  */
1619    packgram ();    packgram ();

Legend:
Removed from v.1.179  
changed lines
  Added in v.1.180

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