]> git.saurik.com Git - bison.git/blobdiff - src/symtab.c
* ro.po: New.
[bison.git] / src / symtab.c
index 57bb79657065ef9964de53ebddcea61559af826e..53c9f677431b86b79d471357c40aac06869fdbf1 100644 (file)
@@ -1,4 +1,5 @@
-/* Symbol table manager for Bison,
+/* Symbol table manager for Bison.
+
    Copyright (C) 1984, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
    Copyright (C) 1984, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
 #include "system.h"
 
 
 #include "system.h"
-#include "quotearg.h"
-#include "hash.h"
+
+#include <hash.h>
+#include <quotearg.h>
+
 #include "complain.h"
 #include "complain.h"
-#include "symtab.h"
 #include "gram.h"
 #include "gram.h"
+#include "symtab.h"
 
 /*------------------------.
 | Distinguished symbols.  |
 `------------------------*/
 
 
 /*------------------------.
 | Distinguished symbols.  |
 `------------------------*/
 
-symbol_t *errtoken = NULL;
-symbol_t *undeftoken = NULL;
-symbol_t *eoftoken = NULL;
-symbol_t *axiom = NULL;
-symbol_t *startsymbol = NULL;
-location_t startsymbol_location;
+symbol *errtoken = NULL;
+symbol *undeftoken = NULL;
+symbol *endtoken = NULL;
+symbol *accept = NULL;
+symbol *startsymbol = NULL;
+location startsymbol_location;
 
 /*---------------------------------.
 | Create a new symbol, named TAG.  |
 `---------------------------------*/
 
 
 /*---------------------------------.
 | Create a new symbol, named TAG.  |
 `---------------------------------*/
 
-static symbol_t *
-symbol_new (const char *tag, location_t location)
+static symbol *
+symbol_new (uniqstr tag, location loc)
 {
 {
-  symbol_t *res = XMALLOC (symbol_t, 1);
+  symbol *res = MALLOC (res, 1);
 
 
-  res->tag = xstrdup (tag);
-  res->location = location;
+  uniqstr_assert (tag);
+  res->tag = tag;
+  res->location = loc;
 
   res->type_name = NULL;
   res->destructor = NULL;
 
   res->type_name = NULL;
   res->destructor = NULL;
+  res->printer = NULL;
 
   res->number = NUMBER_UNDEFINED;
   res->prec = 0;
 
   res->number = NUMBER_UNDEFINED;
   res->prec = 0;
-  res->assoc = right_assoc;
+  res->assoc = undef_assoc;
   res->user_token_number = USER_NUMBER_UNDEFINED;
   res->user_token_number = USER_NUMBER_UNDEFINED;
+
   res->alias = NULL;
   res->class = unknown_sym;
 
   res->alias = NULL;
   res->class = unknown_sym;
 
@@ -65,159 +71,119 @@ symbol_new (const char *tag, location_t location)
 
 
 /*-----------------------------------------------------------------.
 
 
 /*-----------------------------------------------------------------.
-| Return the tag of this SYMBOL in a printable form.  Warning: use |
-| the first QUOTEARG slot: 0.                                      |
+| Set the TYPE_NAME associated with SYM.  Does nothing if passed 0 |
+| as TYPE_NAME.                                                    |
 `-----------------------------------------------------------------*/
 
 `-----------------------------------------------------------------*/
 
-const char *
-symbol_tag_get (symbol_t *symbol)
-{
-  return quotearg_style (escape_quoting_style, symbol->tag);
-}
-
-
-/*------------------------------------------------------------.
-| Return the tag of this SYMBOL in a printable form.  Use the |
-| QUOTEARG slot number N.                                     |
-`------------------------------------------------------------*/
-
-const char *
-symbol_tag_get_n (symbol_t *symbol, int n)
-{
-  return quotearg_n_style (n, escape_quoting_style, symbol->tag);
-}
-
-
-/*-------------------------------.
-| Print the tag of this SYMBOL.  |
-`-------------------------------*/
-
 void
 void
-symbol_tag_print (symbol_t *symbol, FILE *out)
-{
-  fputs (symbol_tag_get (symbol), out);
-}
-
-
-/*------------------------------------------------------------------.
-| Set the TYPE_NAME associated to SYMBOL.  Does nothing if passed 0 |
-| as TYPE_NAME.                                                     |
-`------------------------------------------------------------------*/
-
-void
-symbol_type_set (symbol_t *symbol, location_t location, char *type_name)
+symbol_type_set (symbol *sym, uniqstr type_name, location loc)
 {
   if (type_name)
     {
 {
   if (type_name)
     {
-      if (symbol->type_name)
-       complain_at (location,
-                    _("type redeclaration for %s"), symbol_tag_get (symbol));
-      symbol->type_name = type_name;
+      if (sym->type_name)
+       complain_at (loc, _("type redeclaration for %s"), sym->tag);
+      uniqstr_assert (type_name);
+      sym->type_name = type_name;
     }
 }
 
 
     }
 }
 
 
-/*-------------------------------------------------------------------.
-| Set the DESTRUCTOR associated to SYMBOL.  Do nothing if passed 0.  |
-`-------------------------------------------------------------------*/
+/*------------------------------------------------------------------.
+| Set the DESTRUCTOR associated with SYM.  Do nothing if passed 0.  |
+`------------------------------------------------------------------*/
 
 void
 
 void
-symbol_destructor_set (symbol_t *symbol, location_t location, char *destructor)
+symbol_destructor_set (symbol *sym, char *destructor, location loc)
 {
   if (destructor)
     {
 {
   if (destructor)
     {
-      if (symbol->destructor)
-       complain_at (location,
-                    _("%s redeclaration for %s"),
-                    "%destructor", symbol_tag_get (symbol));
-      symbol->destructor = destructor;
-      symbol->destructor_location = location;
+      if (sym->destructor)
+       complain_at (loc, _("%s redeclaration for %s"),
+                    "%destructor", sym->tag);
+      sym->destructor = destructor;
+      sym->destructor_location = loc;
     }
 }
 
 
     }
 }
 
 
-/*----------------------------------------------------------------.
-| Set the PRITNER associated to SYMBOL.  Do nothing if passed 0.  |
-`----------------------------------------------------------------*/
+/*---------------------------------------------------------------.
+| Set the PRINTER associated with SYM.  Do nothing if passed 0.  |
+`---------------------------------------------------------------*/
 
 void
 
 void
-symbol_printer_set (symbol_t *symbol, char *printer, location_t location)
+symbol_printer_set (symbol *sym, char *printer, location loc)
 {
   if (printer)
     {
 {
   if (printer)
     {
-      if (symbol->printer)
-       complain_at (location,
-                    _("%s redeclaration for %s"),
-                    "%printer", symbol_tag_get (symbol));
-      symbol->printer = printer;
-      symbol->printer_location = location;
+      if (sym->printer)
+       complain_at (loc, _("%s redeclaration for %s"),
+                    "%printer", sym->tag);
+      sym->printer = printer;
+      sym->printer_location = loc;
     }
 }
 
 
     }
 }
 
 
-/*------------------------------------------------------------------.
-| Set the PRECEDENCE associated to SYMBOL.  Does nothing if invoked |
-| with UNDEF_ASSOC as ASSOC.                                        |
-`------------------------------------------------------------------*/
+/*-----------------------------------------------------------------.
+| Set the PRECEDENCE associated with SYM.  Does nothing if invoked |
+| with UNDEF_ASSOC as ASSOC.                                       |
+`-----------------------------------------------------------------*/
 
 void
 
 void
-symbol_precedence_set (symbol_t *symbol, location_t location,
-                      int prec, associativity assoc)
+symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
 {
 {
-  if (assoc != undef_assoc)
+  if (a != undef_assoc)
     {
     {
-      if (symbol->prec != 0)
-       complain_at (location,
-                    _("redefining precedence of %s"),
-                    symbol_tag_get (symbol));
-      symbol->prec = prec;
-      symbol->assoc = assoc;
+      if (sym->prec != 0)
+       complain_at (loc, _("redefining precedence of %s"), sym->tag);
+      sym->prec = prec;
+      sym->assoc = a;
     }
 
   /* Only terminals have a precedence. */
     }
 
   /* Only terminals have a precedence. */
-  symbol_class_set (symbol, token_sym);
+  symbol_class_set (sym, token_sym, loc);
 }
 
 
 }
 
 
-/*-------------------------------------.
-| Set the CLASS associated to SYMBOL.  |
-`-------------------------------------*/
+/*------------------------------------.
+| Set the CLASS associated with SYM.  |
+`------------------------------------*/
 
 void
 
 void
-symbol_class_set (symbol_t *symbol, symbol_class class)
+symbol_class_set (symbol *sym, symbol_class class, location loc)
 {
 {
-  if (symbol->class != unknown_sym && symbol->class != class)
-    complain (_("symbol %s redefined"), symbol_tag_get (symbol));
+  if (sym->class != unknown_sym && sym->class != class)
+    complain_at (loc, _("symbol %s redefined"), sym->tag);
 
 
-  if (class == nterm_sym && symbol->class != nterm_sym)
-    symbol->number = nvars++;
-  else if (class == token_sym && symbol->number == NUMBER_UNDEFINED)
-    symbol->number = ntokens++;
+  if (class == nterm_sym && sym->class != nterm_sym)
+    sym->number = nvars++;
+  else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
+    sym->number = ntokens++;
 
 
-  symbol->class = class;
+  sym->class = class;
 }
 
 
 }
 
 
-/*-------------------------------------------------.
-| Set the USER_TOKEN_NUMBER associated to SYMBOL.  |
-`-------------------------------------------------*/
+/*------------------------------------------------.
+| Set the USER_TOKEN_NUMBER associated with SYM.  |
+`------------------------------------------------*/
 
 void
 
 void
-symbol_user_token_number_set (symbol_t *symbol, int user_token_number)
+symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
 {
 {
-  assert (symbol->class == token_sym);
+  if (sym->class != token_sym)
+    abort ();
 
 
-  if (symbol->user_token_number != USER_NUMBER_UNDEFINED
-      && symbol->user_token_number != user_token_number)
-    complain (_("redefining user token number of %s"),
-             symbol_tag_get (symbol));
+  if (sym->user_token_number != USER_NUMBER_UNDEFINED
+      && sym->user_token_number != user_token_number)
+    complain_at (loc, _("redefining user token number of %s"), sym->tag);
 
 
-  symbol->user_token_number = user_token_number;
-  /* User defined EOF token? */
+  sym->user_token_number = user_token_number;
+  /* User defined $end token? */
   if (user_token_number == 0)
     {
   if (user_token_number == 0)
     {
-      eoftoken = symbol;
-      eoftoken->number = 0;
+      endtoken = sym;
+      endtoken->number = 0;
       /* It is always mapped to 0, so it was already counted in
         NTOKENS.  */
       --ntokens;
       /* It is always mapped to 0, so it was already counted in
         NTOKENS.  */
       --ntokens;
@@ -225,72 +191,63 @@ symbol_user_token_number_set (symbol_t *symbol, int user_token_number)
 }
 
 
 }
 
 
-/*------------.
-| Free THIS.  |
-`------------*/
-
-static void
-symbol_free (symbol_t *this)
-{
-#if 0
-  /* This causes crashes because one string can appear more
-     than once.  */
-  XFREE (this->type_name);
-#endif
-  XFREE (this->tag);
-  XFREE (this);
-}
-
-
-/*-----------------------------------------------------------.
-| If THIS is not defined, report an error, and consider it a |
-| nonterminal.                                               |
-`-----------------------------------------------------------*/
+/*----------------------------------------------------------.
+| If SYM is not defined, report an error, and consider it a |
+| nonterminal.                                              |
+`----------------------------------------------------------*/
 
 
-static bool
-symbol_check_defined (symbol_t *this)
+static inline bool
+symbol_check_defined (symbol *sym)
 {
 {
-  if (this->class == unknown_sym)
+  if (sym->class == unknown_sym)
     {
       complain_at
     {
       complain_at
-       (this->location,
+       (sym->location,
         _("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"),
-        symbol_tag_get (this));
-      this->class = nterm_sym;
-      this->number = nvars++;
+        sym->tag);
+      sym->class = nterm_sym;
+      sym->number = nvars++;
     }
 
     }
 
-  return TRUE;
+  return true;
 }
 
 }
 
+static bool
+symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
+{
+  return symbol_check_defined (sym);
+}
 
 
-/*-------------------------------------------------------------------.
-| Declare the new SYMBOL.  Make it an alias of SYMVAL, and type them |
-| with TYPENAME.                                                     |
-`-------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------.
+| Declare the new symbol SYM.  Make it an alias of SYMVAL, and type |
+| SYMVAL with SYM's type.                                           |
+`------------------------------------------------------------------*/
 
 void
 
 void
-symbol_make_alias (symbol_t *symbol, symbol_t *symval)
+symbol_make_alias (symbol *sym, symbol *symval, location loc)
 {
   if (symval->alias)
 {
   if (symval->alias)
-    warn (_("symbol `%s' used more than once as a literal string"),
-         symbol_tag_get (symval));
-  else if (symbol->alias)
-    warn (_("symbol `%s' given more than one literal string"),
-         symbol_tag_get (symbol));
+    warn_at (loc, _("symbol `%s' used more than once as a literal string"),
+         symval->tag);
+  else if (sym->alias)
+    warn_at (loc, _("symbol `%s' given more than one literal string"),
+         sym->tag);
   else
     {
       symval->class = token_sym;
   else
     {
       symval->class = token_sym;
-      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 */
+      symval->user_token_number = sym->user_token_number;
+      sym->user_token_number = USER_NUMBER_ALIAS;
+      symval->alias = sym;
+      sym->alias = symval;
+      /* sym and symval combined are only one symbol.  */
       nsyms--;
       ntokens--;
       nsyms--;
       ntokens--;
-      assert (ntokens == symbol->number || ntokens == symval->number);
-      symbol->number = symval->number =
-       (symval->number < symbol->number) ? symval->number : symbol->number;
+      if (ntokens != sym->number && ntokens != symval->number)
+       abort ();
+      sym->number = symval->number =
+       (symval->number < sym->number) ? symval->number : sym->number;
+      symbol_type_set (symval, sym->type_name, loc);
     }
 }
 
     }
 }
 
@@ -300,8 +257,8 @@ symbol_make_alias (symbol_t *symbol, symbol_t *symval)
 | associativity.                                           |
 `---------------------------------------------------------*/
 
 | associativity.                                           |
 `---------------------------------------------------------*/
 
-static bool
-symbol_check_alias_consistence (symbol_t *this)
+static inline bool
+symbol_check_alias_consistency (symbol *this)
 {
   /* Check only those who _are_ the aliases. */
   if (this->alias && this->user_token_number == USER_NUMBER_ALIAS)
 {
   /* Check only those who _are_ the aliases. */
   if (this->alias && this->user_token_number == USER_NUMBER_ALIAS)
@@ -309,8 +266,9 @@ symbol_check_alias_consistence (symbol_t *this)
       if (this->prec != this->alias->prec)
        {
          if (this->prec != 0 && this->alias->prec != 0)
       if (this->prec != this->alias->prec)
        {
          if (this->prec != 0 && this->alias->prec != 0)
-           complain (_("conflicting precedences for %s and %s"),
-                     symbol_tag_get (this), symbol_tag_get (this->alias));
+           complain_at (this->alias->location,
+                        _("conflicting precedences for %s and %s"),
+                        this->tag, this->alias->tag);
          if (this->prec != 0)
            this->alias->prec = this->prec;
          else
          if (this->prec != 0)
            this->alias->prec = this->prec;
          else
@@ -319,20 +277,25 @@ symbol_check_alias_consistence (symbol_t *this)
 
       if (this->assoc != this->alias->assoc)
        {
 
       if (this->assoc != this->alias->assoc)
        {
-         /* FIXME: For some reason (probably the S/R => keep the S),
-            the right assoc is chosen has the ``not set''.  This is
-            not nice, fix this!  */
-         if (this->assoc != right_assoc
-             && this->alias->assoc != right_assoc)
-           complain (_("conflicting associativities for %s and %s"),
-                     symbol_tag_get (this), symbol_tag_get (this->alias));
-         if (this->assoc != 0)
+         if (this->assoc != undef_assoc && this->alias->assoc != undef_assoc)
+           complain_at (this->alias->location,
+                        _("conflicting associativities for %s (%s) and %s (%s)"),
+                        this->tag, assoc_to_string (this->assoc),
+                        this->alias->tag, assoc_to_string (this->alias->assoc));
+         if (this->assoc != undef_assoc)
            this->alias->assoc = this->assoc;
          else
            this->assoc = this->alias->assoc;
        }
     }
            this->alias->assoc = this->assoc;
          else
            this->assoc = this->alias->assoc;
        }
     }
-  return TRUE;
+  return true;
+}
+
+static bool
+symbol_check_alias_consistency_processor (void *this,
+                                         void *null ATTRIBUTE_UNUSED)
+{
+  return symbol_check_alias_consistency (this);
 }
 
 
 }
 
 
@@ -341,8 +304,8 @@ symbol_check_alias_consistence (symbol_t *this)
 | into FDEFINES.  Put in SYMBOLS.                                    |
 `-------------------------------------------------------------------*/
 
 | into FDEFINES.  Put in SYMBOLS.                                    |
 `-------------------------------------------------------------------*/
 
-static bool
-symbol_pack (symbol_t *this)
+static inline bool
+symbol_pack (symbol *this)
 {
   if (this->class == nterm_sym)
     {
 {
   if (this->class == nterm_sym)
     {
@@ -355,25 +318,33 @@ symbol_pack (symbol_t *this)
         prec and assoc fields and make both the same */
       if (this->number == NUMBER_UNDEFINED)
        {
         prec and assoc fields and make both the same */
       if (this->number == NUMBER_UNDEFINED)
        {
-         if (this == eoftoken || this->alias == eoftoken)
+         if (this == endtoken || this->alias == endtoken)
            this->number = this->alias->number = 0;
          else
            {
            this->number = this->alias->number = 0;
          else
            {
-             assert (this->alias->number != NUMBER_UNDEFINED);
+             if (this->alias->number == NUMBER_UNDEFINED)
+               abort ();
              this->number = this->alias->number;
            }
        }
              this->number = this->alias->number;
            }
        }
-      /* Do not do processing below for USER_NUMBER_ALIASs.  */
+      /* Do not do processing below for USER_NUMBER_ALIASes.  */
       if (this->user_token_number == USER_NUMBER_ALIAS)
       if (this->user_token_number == USER_NUMBER_ALIAS)
-       return TRUE;
+       return true;
     }
   else /* this->class == token_sym */
     {
     }
   else /* this->class == token_sym */
     {
-      assert (this->number != NUMBER_UNDEFINED);
+      if (this->number == NUMBER_UNDEFINED)
+       abort ();
     }
 
   symbols[this->number] = this;
     }
 
   symbols[this->number] = this;
-  return TRUE;
+  return true;
+}
+
+static bool
+symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
+{
+  return symbol_pack (this);
 }
 
 
 }
 
 
@@ -383,8 +354,8 @@ symbol_pack (symbol_t *this)
 | Put THIS in TOKEN_TRANSLATIONS if it is a token.  |
 `--------------------------------------------------*/
 
 | Put THIS in TOKEN_TRANSLATIONS if it is a token.  |
 `--------------------------------------------------*/
 
-static bool
-symbol_translation (symbol_t *this)
+static inline bool
+symbol_translation (symbol *this)
 {
   /* Non-terminal? */
   if (this->class == token_sym
 {
   /* Non-terminal? */
   if (this->class == token_sym
@@ -392,14 +363,21 @@ symbol_translation (symbol_t *this)
     {
       /* A token which translation has already been set? */
       if (token_translations[this->user_token_number] != undeftoken->number)
     {
       /* 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"),
-                 symbol_tag_get (symbols[token_translations[this->user_token_number]]),
-                 symbol_tag_get (this), this->user_token_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;
     }
 
 
       token_translations[this->user_token_number] = this->number;
     }
 
-  return TRUE;
+  return true;
+}
+
+static bool
+symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
+{
+  return symbol_translation (this);
 }
 
 
 }
 
 
@@ -412,16 +390,30 @@ symbol_translation (symbol_t *this)
 
 static struct hash_table *symbol_table = NULL;
 
 
 static struct hash_table *symbol_table = NULL;
 
+static inline bool
+hash_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 bool
 static bool
-hash_compare_symbol_t (const symbol_t *m1, const symbol_t *m2)
+hash_symbol_comparator (void const *m1, void const *m2)
 {
 {
-  return strcmp (m1->tag, m2->tag) ? FALSE : TRUE;
+  return hash_compare_symbol (m1, m2);
+}
+
+static inline unsigned int
+hash_symbol (const symbol *m, unsigned int tablesize)
+{
+  /* Since tags are unique, we can hash the pointer itself.  */
+  return ((uintptr_t) m->tag) % tablesize;
 }
 
 static unsigned int
 }
 
 static unsigned int
-hash_symbol_t (const symbol_t *m, unsigned int tablesize)
+hash_symbol_hasher (void const *m, unsigned int tablesize)
 {
 {
-  return hash_string (m->tag, tablesize);
+  return hash_symbol (m, tablesize);
 }
 
 
 }
 
 
@@ -434,9 +426,9 @@ symbols_new (void)
 {
   symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
                                  NULL,
 {
   symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
                                  NULL,
-                                 (Hash_hasher) hash_symbol_t,
-                                 (Hash_comparator) hash_compare_symbol_t,
-                                 (Hash_data_freer) symbol_free);
+                                 hash_symbol_hasher,
+                                 hash_symbol_comparator,
+                                 free);
 }
 
 
 }
 
 
@@ -445,25 +437,49 @@ symbols_new (void)
 | yet, create it.                                                 |
 `----------------------------------------------------------------*/
 
 | yet, create it.                                                 |
 `----------------------------------------------------------------*/
 
-symbol_t *
-getsym (const char *key, location_t location)
+symbol *
+symbol_get (const char *key, location loc)
 {
 {
-  symbol_t probe;
-  symbol_t *entry;
+  symbol probe;
+  symbol *entry;
 
 
-  (const char *) probe.tag = key;
+  /* Keep the symbol in a printable form.  */
+  key = uniqstr_new (quotearg_style (escape_quoting_style, key));
+  probe.tag = key;
   entry = hash_lookup (symbol_table, &probe);
 
   if (!entry)
     {
       /* First insertion in the hash. */
   entry = hash_lookup (symbol_table, &probe);
 
   if (!entry)
     {
       /* First insertion in the hash. */
-      entry = symbol_new (key, location);
+      entry = symbol_new (key, loc);
       hash_insert (symbol_table, entry);
     }
   return entry;
 }
 
 
       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.  |
 `-------------------*/
 /*-------------------.
 | Free the symbols.  |
 `-------------------*/
@@ -472,6 +488,7 @@ void
 symbols_free (void)
 {
   hash_free (symbol_table);
 symbols_free (void)
 {
   hash_free (symbol_table);
+  free (symbols);
 }
 
 
 }
 
 
@@ -480,12 +497,10 @@ symbols_free (void)
 | terminals.                                                     |
 `---------------------------------------------------------------*/
 
 | terminals.                                                     |
 `---------------------------------------------------------------*/
 
-void
-symbols_do (symbol_processor processor, void *processor_data)
+static void
+symbols_do (Hash_processor processor, void *processor_data)
 {
 {
-  hash_do_for_each (symbol_table,
-                   (Hash_processor) processor,
-                   processor_data);
+  hash_do_for_each (symbol_table, processor, processor_data);
 }
 
 
 }
 
 
@@ -497,7 +512,7 @@ symbols_do (symbol_processor processor, void *processor_data)
 void
 symbols_check_defined (void)
 {
 void
 symbols_check_defined (void)
 {
-  symbols_do (symbol_check_defined, NULL);
+  symbols_do (symbol_check_defined_processor, NULL);
 }
 
 /*------------------------------------------------------------------.
 }
 
 /*------------------------------------------------------------------.
@@ -508,7 +523,7 @@ symbols_check_defined (void)
 static void
 symbols_token_translations_init (void)
 {
 static void
 symbols_token_translations_init (void)
 {
-  int num_256_available_p = TRUE;
+  bool num_256_available_p = true;
   int i;
 
   /* Find the highest user token number, and whether 256, the POSIX
   int i;
 
   /* Find the highest user token number, and whether 256, the POSIX
@@ -516,13 +531,13 @@ symbols_token_translations_init (void)
   max_user_token_number = 0;
   for (i = 0; i < ntokens; ++i)
     {
   max_user_token_number = 0;
   for (i = 0; i < ntokens; ++i)
     {
-      symbol_t *this = symbols[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)
       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;
+           num_256_available_p = false;
        }
     }
 
        }
     }
 
@@ -537,21 +552,21 @@ symbols_token_translations_init (void)
 
   for (i = 0; i < ntokens; ++i)
     {
 
   for (i = 0; i < ntokens; ++i)
     {
-      symbol_t *this = symbols[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;
     }
 
       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);
+  CALLOC (token_translations, max_user_token_number + 1);
 
   /* Initialize all entries for literal tokens to 2, the internal
 
   /* Initialize all entries for literal tokens to 2, the internal
-     token number for $undefined., which represents all invalid
-     inputs.  */
+     token number for $undefined, which represents all invalid inputs.
+     */
   for (i = 0; i < max_user_token_number + 1; i++)
     token_translations[i] = undeftoken->number;
   for (i = 0; i < max_user_token_number + 1; i++)
     token_translations[i] = undeftoken->number;
-  symbols_do (symbol_translation, NULL);
+  symbols_do (symbol_translation_processor, NULL);
 }
 
 
 }
 
 
@@ -563,19 +578,19 @@ symbols_token_translations_init (void)
 void
 symbols_pack (void)
 {
 void
 symbols_pack (void)
 {
-  symbols = XCALLOC (symbol_t *, nsyms);
+  CALLOC (symbols, nsyms);
 
 
-  symbols_do (symbol_check_alias_consistence, NULL);
-  symbols_do (symbol_pack, NULL);
+  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"),
 
   symbols_token_translations_init ();
 
   if (startsymbol->class == unknown_sym)
     fatal_at (startsymbol_location,
              _("the start symbol %s is undefined"),
-             symbol_tag_get (startsymbol));
+             startsymbol->tag);
   else if (startsymbol->class == token_sym)
     fatal_at (startsymbol_location,
              _("the start symbol %s is a token"),
   else if (startsymbol->class == token_sym)
     fatal_at (startsymbol_location,
              _("the start symbol %s is a token"),
-             symbol_tag_get (startsymbol));
+             startsymbol->tag);
 }
 }