/[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.158 by akim, Sun Apr 7 17:42:49 2002 UTC revision 1.159 by akim, Sun Apr 7 17:43:21 2002 UTC
# Line 86  symbol_list_new (bucket *sym) Line 86  symbol_list_new (bucket *sym)
86    return res;    return res;
87  }  }
88    
89    /*------------------------.
90    | Operations on buckets.  |
91    `------------------------*/
92    
93    
94    /*-----------------------------------------------------------.
95    | If THIS is not defined, report an error, and consider it a |
96    | nonterminal.                                               |
97    `-----------------------------------------------------------*/
98    
99    static bool
100    bucket_check_defined (bucket *this)
101    {
102      if (this->class == unknown_sym)
103        {
104          complain
105            (_("symbol %s is used, but is not defined as a token and has no rules"),
106             this->tag);
107          this->class = nterm_sym;
108          this->number = nvars++;
109        }
110    
111      return TRUE;
112    }
113    
114    
115    /*-------------------------------------------------------------------.
116    | Assign a symbol number, and write the definition of the token name |
117    | into FDEFINES.  Put in SYMBOLS.                                    |
118    `-------------------------------------------------------------------*/
119    
120    static bool
121    bucket_make_alias (bucket *symbol, char *typename)
122    {
123      if (symval->alias)
124        warn (_("symbol `%s' used more than once as a literal string"),
125              symval->tag);
126      else if (symbol->alias)
127        warn (_("symbol `%s' given more than one literal string"),
128              symbol->tag);
129      else
130        {
131          symval->class = token_sym;
132          symval->type_name = typename;
133          symval->user_token_number = symbol->user_token_number;
134          symbol->user_token_number = SALIAS;
135          symval->alias = symbol;
136          symbol->alias = symval;
137          /* symbol and symval combined are only one symbol */
138          nsyms--;
139          ntokens--;
140          assert (ntokens == symbol->number || ntokens == symval->number);
141          symbol->number = symval->number =
142            (symval->number < symbol->number) ? symval->number : symbol->number;
143        }
144    
145      return TRUE;
146    }
147    
148    /*---------------------------------------------------------.
149    | Check that THIS, and its alias, have same precedence and |
150    | associativity.                                           |
151    `---------------------------------------------------------*/
152    
153    static bool
154    bucket_check_alias_consistence (bucket *this)
155    {
156      /* Check only those who _are_ the aliases. */
157      if (this->alias && this->user_token_number == SALIAS)
158        {
159          if (this->prec != this->alias->prec)
160            {
161              if (this->prec != 0 && this->alias->prec != 0)
162                complain (_("conflicting precedences for %s and %s"),
163                          this->tag, this->alias->tag);
164              if (this->prec != 0)
165                this->alias->prec = this->prec;
166              else
167                this->prec = this->alias->prec;
168            }
169    
170          if (this->assoc != this->alias->assoc)
171            {
172              if (this->assoc != 0 && this->alias->assoc != 0)
173                complain (_("conflicting assoc values for %s and %s"),
174                          this->tag, this->alias->tag);
175              if (this->assoc != 0)
176                this->alias->assoc = this->assoc;
177              else
178                this->assoc = this->alias->assoc;
179            }
180        }
181      return TRUE;
182    }
183    
184    
185    /*-------------------------------------------------------------------.
186    | Assign a symbol number, and write the definition of the token name |
187    | into FDEFINES.  Put in SYMBOLS.                                    |
188    `-------------------------------------------------------------------*/
189    
190    static bool
191    bucket_pack (bucket *this)
192    {
193      if (getenv ("DEBUG"))
194        fprintf (stderr, "Packing %s, %s, number = %d\n",
195                 this->tag,
196                 this->class == nterm_sym ? "nterm" : "TERM",
197                 this->number);
198      if (this->class == nterm_sym)
199        {
200          this->number += ntokens;
201        }
202      else if (this->alias)
203        {
204          /* This symbol and its alias are a single token defn.
205             Allocate a tokno, and assign to both check agreement of
206             prec and assoc fields and make both the same */
207          if (this->number == -1)
208            {
209              if (this == eoftoken || this->alias == eoftoken)
210                this->number = this->alias->number = 0;
211              else
212                {
213                  assert (this->alias->number != -1);
214                  this->number = this->alias->number;
215                }
216            }
217          /* Do not do processing below for SALIASs.  */
218          if (this->user_token_number == SALIAS)
219            return TRUE;
220        }
221      else /* this->class == token_sym */
222        {
223          assert (this->number != -1);
224        }
225    
226      if (getenv ("DEBUG"))
227        fprintf (stderr, "Setting %d = %s\n", this->number, this->tag);
228      symbols[this->number] = this;
229      return TRUE;
230    }
231    
232    
233    
234    
235    /*--------------------------------------------------.
236    | Put THIS in TOKEN_TRANSLATIONS if it is a token.  |
237    `--------------------------------------------------*/
238    
239    static bool
240    bucket_translation (bucket *this)
241    {
242      if (getenv ("DEBUG"))
243        fprintf (stderr, "Considering Setting UserVal %s = %d (val = %d)\n",
244                 this->tag, this->user_token_number, this->number);
245    
246      /* Non-terminal? */
247      if (this->class == token_sym
248          && this->user_token_number != SALIAS)
249        {
250          /* A token which translation has already been set? */
251          if (token_translations[this->user_token_number] != 2)
252            complain (_("tokens %s and %s both assigned number %d"),
253                      symbols[token_translations[this->user_token_number]]->tag,
254                      this->tag, this->user_token_number);
255    
256          if (getenv ("DEBUG"))
257            fprintf (stderr, "Setting UserVal %s = %d (val = %d)\n",
258                     this->tag, this->user_token_number, this->number);
259          token_translations[this->user_token_number] = this->number;
260        }
261    
262      return TRUE;
263    }
264    
265    
266  /*===================\  /*===================\
# Line 531  parse_token_decl (symbol_class what_is, Line 706  parse_token_decl (symbol_class what_is,
706          }          }
707        else if (token == tok_identifier && *symval->tag == '\"' && symbol)        else if (token == tok_identifier && *symval->tag == '\"' && symbol)
708          {          {
709            if (symval->alias)            bucket_make_alias (symbol, typename);
             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 = SALIAS;  
               symval->alias = symbol;  
               symbol->alias = symval;  
               /* symbol and symval combined are only one symbol */  
               nsyms--;  
             }  
710            symbol = NULL;            symbol = NULL;
711          }          }
712        else if (token == tok_identifier)        else if (token == tok_identifier)
# Line 560  parse_token_decl (symbol_class what_is, Line 719  parse_token_decl (symbol_class what_is,
719            symbol->class = what_is;            symbol->class = what_is;
720            if (what_is == nterm_sym && oldclass != nterm_sym)            if (what_is == nterm_sym && oldclass != nterm_sym)
721              symbol->number = nvars++;              symbol->number = nvars++;
722              if (what_is == token_sym && symbol->number == -1)
723                {
724                  symbol->number = ntokens++;
725                  if (getenv ("DEBUG"))
726                    fprintf (stderr, "Set %s to %d\n",
727                             symbol->tag, symbol->number);
728                }
729    
730            if (typename)            if (typename)
731              {              {
# Line 574  parse_token_decl (symbol_class what_is, Line 740  parse_token_decl (symbol_class what_is,
740            symbol->user_token_number = numval;            symbol->user_token_number = numval;
741            /* User defined EOF token? */            /* User defined EOF token? */
742            if (numval == 0)            if (numval == 0)
743              eoftoken = symbol;              {
744                  eoftoken = symbol;
745                  eoftoken->number = 0;
746                  /* It is always mapped to 0, so it was already counted in
747                     NTOKENS.  */
748                  --ntokens;
749                }
750          }          }
751        else        else
752          {          {
# Line 703  parse_assoc_decl (associativity assoc) Line 875  parse_assoc_decl (associativity assoc)
875            symval->assoc = assoc;            symval->assoc = assoc;
876            if (symval->class == nterm_sym)            if (symval->class == nterm_sym)
877              complain (_("symbol %s redefined"), symval->tag);              complain (_("symbol %s redefined"), symval->tag);
878            symval->class = token_sym;            if (symval->number == -1)
879                {
880                  symval->number = ntokens++;
881                  symval->class = token_sym;
882                }
883            if (name)            if (name)
884              {                   /* record the type, if one is specified */              {                   /* record the type, if one is specified */
885                if (symval->type_name == NULL)                if (symval->type_name == NULL)
# Line 720  parse_assoc_decl (associativity assoc) Line 896  parse_assoc_decl (associativity assoc)
896              }              }
897            else            else
898              {              {
899                complain (_                complain
900                          ("invalid text (%s) - number should be after identifier"),                  (_("invalid text (%s) - number should be after identifier"),
901  token_buffer);                   token_buffer);
902                skip_to_char ('%');                skip_to_char ('%');
903              }              }
904            break;            break;
# Line 1073  read_declarations (void) Line 1249  read_declarations (void)
1249              case tok_stropt:              case tok_stropt:
1250              case tok_intopt:              case tok_intopt:
1251              case tok_obsolete:              case tok_obsolete:
1252                abort ();                assert (0);
1253                break;                break;
1254    
1255              case tok_illegal:              case tok_illegal:
# Line 1231  readgram (void) Line 1407  readgram (void)
1407    bucket *lhs = NULL;    bucket *lhs = NULL;
1408    symbol_list *p = NULL;    symbol_list *p = NULL;
1409    symbol_list *p1 = NULL;    symbol_list *p1 = NULL;
   bucket *bp;  
1410    
1411    /* Points to first symbol_list of current rule. its symbol is the    /* Points to first symbol_list of current rule. its symbol is the
1412       lhs of the rule.  */       lhs of the rule.  */
# Line 1463  readgram (void) Line 1638  readgram (void)
1638      fatal (_("no rules in the input grammar"));      fatal (_("no rules in the input grammar"));
1639    
1640    /* Report any undefined symbols and consider them nonterminals.  */    /* Report any undefined symbols and consider them nonterminals.  */
1641      buckets_do (bucket_check_defined, NULL);
   for (bp = firstsymbol; bp; bp = bp->next)  
     if (bp->class == unknown_sym)  
       {  
         complain (_  
                   ("symbol %s is used, but is not defined as a token and has no rules"),  
                   bp->tag);  
         bp->class = nterm_sym;  
         bp->number = nvars++;  
       }  
1642    
1643    /* Insert the initial rule, which line is that of the first rule    /* Insert the initial rule, which line is that of the first rule
1644       (not that of the start symbol):       (not that of the start symbol):
# Line 1493  readgram (void) Line 1659  readgram (void)
1659      fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),      fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
1660             MAXSHORT);             MAXSHORT);
1661    
1662    ntokens = nsyms - nvars;    if (getenv ("DEBUG"))
1663        fprintf (stderr, "nsyms == ntokens + nvars: %d == %d + %d\n",
1664                 nsyms, ntokens, nvars);
1665      assert (nsyms == ntokens + nvars);
1666  }  }
1667    
1668  /* At the end of the grammar file, some C source code must  /* At the end of the grammar file, some C source code must
# Line 1530  read_additionnal_code (void) Line 1699  read_additionnal_code (void)
1699  static void  static void
1700  token_translations_init (void)  token_translations_init (void)
1701  {  {
1702    bucket *bp = NULL;    int last_user_token_number = 256;
1703    int i;    int i;
1704    
1705      /* Set the user numbers. */
1706      for (i = 0; i < ntokens; ++i)
1707        {
1708          bucket *this = symbols[i];
1709          if (getenv ("DEBUG"))
1710            fprintf (stderr, "UserVal %s = %d (val = %d)\n",
1711                     this->tag, this->user_token_number, this->number);
1712          if (this->user_token_number == SUNDEF)
1713            this->user_token_number = ++last_user_token_number;
1714          if (this->user_token_number > max_user_token_number)
1715            max_user_token_number = this->user_token_number;
1716          if (getenv ("DEBUG"))
1717            fprintf (stderr, "Now: UserVal %s = %d (val = %d)\n",
1718                     this->tag, this->user_token_number, this->number);
1719        }
1720    
1721    token_translations = XCALLOC (short, max_user_token_number + 1);    token_translations = XCALLOC (short, max_user_token_number + 1);
1722    
1723    /* Initialize all entries for literal tokens to 2, the internal    /* Initialize all entries for literal tokens to 2, the internal
# Line 1541  token_translations_init (void) Line 1726  token_translations_init (void)
1726    for (i = 0; i < max_user_token_number + 1; i++)    for (i = 0; i < max_user_token_number + 1; i++)
1727      token_translations[i] = 2;      token_translations[i] = 2;
1728    
1729    for (bp = firstsymbol; bp; bp = bp->next)    buckets_do (bucket_translation, NULL);
     {  
       /* Non-terminal? */  
       if (bp->number >= ntokens)  
         continue;  
       /* A token string alias? */  
       if (bp->user_token_number == SALIAS)  
         continue;  
   
       assert (bp->user_token_number != SUNDEF);  
   
       /* A token which translation has already been set? */  
       if (token_translations[bp->user_token_number] != 2)  
         complain (_("tokens %s and %s both assigned number %d"),  
                   symbols[token_translations[bp->user_token_number]]->tag,  
                   bp->tag, bp->user_token_number);  
       token_translations[bp->user_token_number] = bp->number;  
     }  
1730  }  }
1731    
1732    
# Line 1570  token_translations_init (void) Line 1738  token_translations_init (void)
1738  static void  static void
1739  packsymbols (void)  packsymbols (void)
1740  {  {
   bucket *bp = NULL;  
   int tokno = 1;  
   int last_user_token_number;  
   
1741    symbols = XCALLOC (bucket *, nsyms);    symbols = XCALLOC (bucket *, nsyms);
1742    
1743    max_user_token_number = 256;    buckets_do (bucket_check_alias_consistence, NULL);
1744    last_user_token_number = 256;    buckets_do (bucket_pack, NULL);
   
   for (bp = firstsymbol; bp; bp = bp->next)  
     {  
       if (bp->class == nterm_sym)  
         {  
           bp->number += ntokens;  
         }  
       else if (bp->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 (bp->number == -1)  
             {  
               if (bp == eoftoken || bp->alias == eoftoken)  
                 bp->number = bp->alias->number = 0;  
               else  
                 {  
                   bp->number = bp->alias->number = tokno++;  
                 }  
             }  
   
           if (bp->prec != bp->alias->prec)  
             {  
               if (bp->prec != 0 && bp->alias->prec != 0  
                   && bp->user_token_number == SALIAS)  
                 complain (_("conflicting precedences for %s and %s"),  
                           bp->tag, bp->alias->tag);  
               if (bp->prec != 0)  
                 bp->alias->prec = bp->prec;  
               else  
                 bp->prec = bp->alias->prec;  
             }  
   
           if (bp->assoc != bp->alias->assoc)  
             {  
               if (bp->assoc != 0 && bp->alias->assoc != 0  
                   && bp->user_token_number == SALIAS)  
                 complain (_("conflicting assoc values for %s and %s"),  
                           bp->tag, bp->alias->tag);  
               if (bp->assoc != 0)  
                 bp->alias->assoc = bp->assoc;  
               else  
                 bp->assoc = bp->alias->assoc;  
             }  
   
           /* Do not do processing below for SALIASs.  */  
           if (bp->user_token_number == SALIAS)  
             continue;  
   
         }  
       else /* bp->class == token_sym */  
         {  
           if (bp == eoftoken)  
             bp->number = 0;  
           else  
             bp->number = tokno++;  
         }  
   
       if (bp->class == token_sym)  
         {  
           if (bp->user_token_number == SUNDEF)  
             bp->user_token_number = ++last_user_token_number;  
           if (bp->user_token_number > max_user_token_number)  
             max_user_token_number = bp->user_token_number;  
         }  
   
       symbols[bp->number] = bp;  
     }  
1745    
1746    token_translations_init ();    token_translations_init ();
1747    
# Line 1750  reader (void) Line 1845  reader (void)
1845    obstack_init (&muscle_obstack);    obstack_init (&muscle_obstack);
1846    
1847    /* Initialize the symbol table.  */    /* Initialize the symbol table.  */
1848    tabinit ();    buckets_new ();
1849    
1850    /* Construct the axiom symbol. */    /* Construct the axiom symbol. */
1851    axiom = getsym ("$axiom");    axiom = getsym ("$axiom");
# Line 1760  reader (void) Line 1855  reader (void)
1855    /* Construct the error token */    /* Construct the error token */
1856    errtoken = getsym ("error");    errtoken = getsym ("error");
1857    errtoken->class = token_sym;    errtoken->class = token_sym;
1858      errtoken->number = ntokens++;
1859    errtoken->user_token_number = 256;    /* Value specified by POSIX.  */    errtoken->user_token_number = 256;    /* Value specified by POSIX.  */
1860    
1861    /* Construct a token that represents all undefined literal tokens.    /* Construct a token that represents all undefined literal tokens.
1862       It is always token number 2.  */       It is always token number 2.  */
1863    undeftoken = getsym ("$undefined.");    undeftoken = getsym ("$undefined.");
1864    undeftoken->class = token_sym;    undeftoken->class = token_sym;
1865      undeftoken->number = ntokens++;
1866    undeftoken->user_token_number = 2;    undeftoken->user_token_number = 2;
1867    
1868    /* Initialize the obstacks. */    /* Initialize the obstacks. */
# Line 1785  reader (void) Line 1882  reader (void)
1882      {      {
1883        eoftoken = getsym ("$");        eoftoken = getsym ("$");
1884        eoftoken->class = token_sym;        eoftoken->class = token_sym;
1885          eoftoken->number = 0;
1886        /* Value specified by POSIX.  */        /* Value specified by POSIX.  */
1887        eoftoken->user_token_number = 0;        eoftoken->user_token_number = 0;
1888      }      }
# Line 1815  grammar_free (void) Line 1913  grammar_free (void)
1913    XFREE (ritem);    XFREE (ritem);
1914    free (rules + 1);    free (rules + 1);
1915    /* Free the symbol table data structure.  */    /* Free the symbol table data structure.  */
1916    free_symtab ();    buckets_free ();
1917  }  }

Legend:
Removed from v.1.158  
changed lines
  Added in v.1.159

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