]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
* src/reader.c (grammar_midrule_action): New, Eved out from
[bison.git] / src / reader.c
index da97aa415ff179fa6c0e87487a06f4691f72cb9d..949d74bb26cc657d2b3ebe09e64631c8fff05232 100644 (file)
@@ -51,11 +51,6 @@ typedef struct symbol_list
 int lineno;
 static symbol_list *grammar = NULL;
 static int start_flag = 0;
-static symbol_t *startval = NULL;
-
-/* Nonzero if components of semantic values are used, implying
-   they must be unions.  */
-static int value_components_used;
 
 /* Nonzero if %union has been seen.  */
 static int typed = 0;
@@ -63,11 +58,6 @@ static int typed = 0;
 /* Incremented for each %left, %right or %nonassoc seen */
 static int lastprec = 0;
 
-symbol_t *errtoken = NULL;
-symbol_t *undeftoken = NULL;
-symbol_t *eoftoken = NULL;
-symbol_t *axiom = NULL;
-
 static symbol_list *
 symbol_list_new (symbol_t *sym)
 {
@@ -81,169 +71,6 @@ symbol_list_new (symbol_t *sym)
   return res;
 }
 
-/*------------------------.
-| 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 = SALIAS;
-      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 == SALIAS)
-    {
-      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 SALIASs.  */
-      if (this->user_token_number == SALIAS)
-       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 != SALIAS)
-    {
-      /* 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;
-}
-\f
-
 /*===================\
 | Low level lexing.  |
 \===================*/
@@ -547,7 +374,6 @@ copy_dollar (FILE *fin, struct obstack *oout,
     {
       read_type_name (fin);
       type_name = token_buffer;
-      value_components_used = 1;
       c = getc (fin);
     }
 
@@ -657,14 +483,12 @@ copy_definition (struct obstack *oout)
 }
 
 
-/*-------------------------------------------------------------------.
-| Parse what comes after %token or %nterm.  For %token, WHAT_IS is   |
-| token_sym and WHAT_IS_NOT is nterm_sym.  For %nterm, the arguments |
-| are reversed.                                                      |
-`-------------------------------------------------------------------*/
+/*------------------------------------------.
+| Parse what comes after %token or %nterm.  |
+`------------------------------------------*/
 
 static void
-parse_token_decl (symbol_class what_is, symbol_class what_is_not)
+parse_token_decl (symbol_class class)
 {
   token_t token = tok_undef;
   char *typename = NULL;
@@ -686,61 +510,40 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not)
        fatal (_("Premature EOF after %s"), token_buffer);
 
       token = lex ();
-      if (token == tok_comma)
+      switch (token)
        {
+       case tok_comma:
          symbol = NULL;
-         continue;
-       }
-      if (token == tok_typename)
-       {
+         break;
+
+       case tok_typename:
          typename = xstrdup (token_buffer);
-         value_components_used = 1;
          symbol = NULL;
-       }
-      else if (token == tok_identifier && *symval->tag == '\"' && symbol)
-       {
-         symbol_make_alias (symbol, typename);
-         symbol = NULL;
-       }
-      else if (token == tok_identifier)
-       {
-         int oldclass = symval->class;
-         symbol = symval;
-
-         if (symbol->class == what_is_not)
-           complain (_("symbol %s redefined"), symbol->tag);
-         symbol->class = what_is;
-         if (what_is == nterm_sym && oldclass != nterm_sym)
-           symbol->number = nvars++;
-         if (what_is == token_sym && symbol->number == NUMBER_UNDEFINED)
-           symbol->number = ntokens++;
-
-         if (typename)
+         break;
+
+       case tok_identifier:
+         if (*symval->tag == '\"' && symbol)
            {
-             if (symbol->type_name == NULL)
-               symbol->type_name = typename;
-             else if (strcmp (typename, symbol->type_name) != 0)
-               complain (_("type redeclaration for %s"), symbol->tag);
+             symbol_make_alias (symbol, symval, typename);
+             symbol = NULL;
            }
-       }
-      else if (symbol && token == tok_number)
-       {
-         symbol->user_token_number = numval;
-         /* User defined EOF token? */
-         if (numval == 0)
+         else
            {
-             eoftoken = symbol;
-             eoftoken->number = 0;
-             /* It is always mapped to 0, so it was already counted in
-                NTOKENS.  */
-             --ntokens;
+             symbol = symval;
+             symbol_class_set (symbol, class);
+             if (typename)
+               symbol_type_set (symbol, typename);
            }
-       }
-      else
-       {
+         break;
+
+       case tok_number:
+         symbol_user_token_number_set (symbol, numval);
+         break;
+
+       default:
          complain (_("`%s' is invalid in %s"),
                    token_buffer,
-                   (what_is == token_sym) ? "%token" : "%nterm");
+                   (class == token_sym) ? "%token" : "%nterm");
          skip_to_char ('%');
        }
     }
@@ -762,7 +565,7 @@ parse_start_decl (void)
   else
     {
       start_flag = 1;
-      startval = symval;
+      startsymbol = symval;
     }
 }
 
@@ -799,17 +602,12 @@ parse_type_decl (void)
 
       switch (t)
        {
-
        case tok_comma:
        case tok_semicolon:
          break;
 
        case tok_identifier:
-         if (symval->type_name == NULL)
-           symval->type_name = name;
-         else if (strcmp (name, symval->type_name) != 0)
-           complain (_("type redeclaration for %s"), symval->tag);
-
+         symbol_type_set (symval, name);
          break;
 
        default:
@@ -858,30 +656,16 @@ parse_assoc_decl (associativity assoc)
          break;
 
        case tok_identifier:
-         if (symval->prec != 0)
-           complain (_("redefining precedence of %s"), symval->tag);
-         symval->prec = lastprec;
-         symval->assoc = assoc;
-         if (symval->class == nterm_sym)
-           complain (_("symbol %s redefined"), symval->tag);
-         if (symval->number == NUMBER_UNDEFINED)
-           {
-             symval->number = ntokens++;
-             symval->class = token_sym;
-           }
+         symbol_class_set (symval, token_sym);
+         symbol_precedence_set (symval, lastprec, assoc);
          if (name)
-           {                   /* record the type, if one is specified */
-             if (symval->type_name == NULL)
-               symval->type_name = name;
-             else if (strcmp (name, symval->type_name) != 0)
-               complain (_("type redeclaration for %s"), symval->tag);
-           }
+           symbol_type_set (symval, name);
          break;
 
        case tok_number:
          if (prev == tok_identifier)
            {
-             symval->user_token_number = numval;
+             symbol_user_token_number_set (symval, numval);
            }
          else
            {
@@ -988,84 +772,6 @@ parse_expect_decl (void)
 }
 
 
-/*-------------------------------------------------------------------.
-| Parse what comes after %thong.  the full syntax is                 |
-|                                                                    |
-|                %thong <type> token number literal                  |
-|                                                                    |
-| the <type> or number may be omitted.  The number specifies the     |
-| user_token_number.                                                 |
-|                                                                    |
-| Two symbols are entered in the table, one for the token symbol and |
-| one for the literal.  Both are given the <type>, if any, from the  |
-| declaration.  The ->user_token_number of the first is SALIAS and   |
-| the ->user_token_number of the second is set to the number, if     |
-| any, from the declaration.  The two symbols are linked via         |
-| pointers in their ->alias fields.                                  |
-|                                                                    |
-| During OUTPUT_DEFINES_TABLE, the symbol is reported thereafter,    |
-| only the literal string is retained it is the literal string that  |
-| is output to yytname                                               |
-`-------------------------------------------------------------------*/
-
-static void
-parse_thong_decl (void)
-{
-  token_t token;
-  symbol_t *symbol;
-  char *typename = 0;
-  int usrtoknum = SUNDEF;
-
-  token = lex ();              /* fetch typename or first token */
-  if (token == tok_typename)
-    {
-      typename = xstrdup (token_buffer);
-      value_components_used = 1;
-      token = lex ();          /* fetch first token */
-    }
-
-  /* process first token */
-
-  if (token != tok_identifier)
-    {
-      complain (_("unrecognized item %s, expected an identifier"),
-               token_buffer);
-      skip_to_char ('%');
-      return;
-    }
-  symval->class = token_sym;
-  symval->type_name = typename;
-  symval->user_token_number = SALIAS;
-  symbol = symval;
-
-  token = lex ();              /* get number or literal string */
-
-  if (token == tok_number)
-    {
-      usrtoknum = numval;
-      token = lex ();          /* okay, did number, now get literal */
-    }
-
-  /* process literal string token */
-
-  if (token != tok_identifier || *symval->tag != '\"')
-    {
-      complain (_("expected string constant instead of %s"), token_buffer);
-      skip_to_char ('%');
-      return;
-    }
-  symval->class = token_sym;
-  symval->type_name = typename;
-  symval->user_token_number = usrtoknum;
-
-  symval->alias = symbol;
-  symbol->alias = symval;
-
-  /* symbol and symval combined are only one symbol.  */
-  nsyms--;
-}
-
-
 static void
 parse_muscle_decl (void)
 {
@@ -1188,11 +894,11 @@ read_declarations (void)
              break;
 
            case tok_token:
-             parse_token_decl (token_sym, nterm_sym);
+             parse_token_decl (token_sym);
              break;
 
            case tok_nterm:
-             parse_token_decl (nterm_sym, token_sym);
+             parse_token_decl (nterm_sym);
              break;
 
            case tok_type:
@@ -1211,10 +917,6 @@ read_declarations (void)
              parse_expect_decl ();
              break;
 
-           case tok_thong:
-             parse_thong_decl ();
-             break;
-
            case tok_left:
              parse_assoc_decl (left_assoc);
              break;
@@ -1286,12 +988,12 @@ parse_action (symbol_list *rule, int rule_length)
        switch (c)
          {
          case '\n':
-           obstack_1grow (&action_obstack, c);
+           copy_character (&action_obstack, c);
            ++lineno;
            break;
 
          case '{':
-           obstack_1grow (&action_obstack, c);
+           copy_character (&action_obstack, c);
            ++count;
            break;
 
@@ -1316,12 +1018,12 @@ parse_action (symbol_list *rule, int rule_length)
            fatal (_("unmatched %s"), "`{'");
 
          default:
-           obstack_1grow (&action_obstack, c);
+           copy_character (&action_obstack, c);
          }
 
       /* Above loop exits when C is '}'.  */
       if (--count)
-       obstack_1grow (&action_obstack, c);
+       copy_character (&action_obstack, c);
     }
 
   obstack_1grow (&action_obstack, '\0');
@@ -1370,19 +1072,109 @@ gensym (void)
 | in the rules section.                                              |
 `-------------------------------------------------------------------*/
 
+/* The (currently) last symbol of GRAMMAR. */
+symbol_list *grammar_end = NULL;
+
+/* Append S to the GRAMMAR. */
+static void
+grammar_symbol_append (symbol_t *s)
+{
+  symbol_list *p = symbol_list_new (s);
+
+  if (grammar_end)
+    grammar_end->next = p;
+  else
+    grammar = p;
+
+  grammar_end = p;
+}
+
+/* The rule currently being defined, and the previous rule.  Point to
+   the first symbol of each list: their lhs.  */
+symbol_list *current_rule = NULL;
+symbol_list *previous_rule = NULL;
+
+
+/* Create a new rule for LHS in to the GRAMMAR. */
+
+static void
+grammar_rule_begin (symbol_t *lhs)
+{
+  if (!start_flag)
+    {
+      startsymbol = lhs;
+      start_flag = 1;
+    }
+
+  /* Start a new rule and record its lhs.  */
+  ++nrules;
+  ++nritems;
+
+  previous_rule = grammar_end;
+  grammar_symbol_append (lhs);
+  current_rule = grammar_end;
+
+  /* Mark the rule's lhs as a nonterminal if not already so.  */
+
+  if (lhs->class == unknown_sym)
+    {
+      lhs->class = nterm_sym;
+      lhs->number = nvars;
+      ++nvars;
+    }
+  else if (lhs->class == token_sym)
+    complain (_("rule given for %s, which is a token"), lhs->tag);
+}
+
+/* The previous action turns out the be a mid-rule action.  Attach it
+   to the current rule, i.e., create a dummy symbol, attach it this
+   mid-rule action, and append this dummy nonterminal to the current
+   rule.  */
+
+static void
+grammar_midrule_action (void)
+{
+  /* Since the action was written out with this rule's number, we must
+     give the new rule this number by inserting the new rule before
+     it.  */
+
+  /* Make a dummy nonterminal, a gensym.  */
+  symbol_t *sdummy = gensym ();
+  symbol_list *midrule_action = symbol_list_new (sdummy);
+
+  /* Make a new rule, whose body is empty, before the current one, so
+     that the action just read can belong to it.  */
+  ++nrules;
+  ++nritems;
+  /* Attach its lineno to that of the host rule.  */
+  midrule_action->line = current_rule->line;
+  /* Move the action from the host rule to this one.  */
+  midrule_action->action = current_rule->action;
+  midrule_action->action_line = current_rule->action_line;
+  current_rule->action = NULL;
+
+  if (previous_rule)
+    previous_rule->next = midrule_action;
+  else
+    grammar = midrule_action;
+
+  /* End of the rule. */
+  previous_rule = symbol_list_new (NULL);
+  previous_rule->next = current_rule;
+
+  midrule_action->next = previous_rule;
+
+  /* Insert the dummy generated by that rule into this rule.  */
+  ++nritems;
+  grammar_symbol_append (sdummy);
+}
+
+
 static void
 readgram (void)
 {
   token_t t;
   symbol_t *lhs = NULL;
-  symbol_list *p = NULL;
-  symbol_list *p1 = NULL;
-
-  /* Points to first symbol_list of current rule. its symbol is the
-     lhs of the rule.  */
-  symbol_list *crule = NULL;
-  /* Points to the symbol_list preceding crule.  */
-  symbol_list *crule1 = NULL;
 
   t = lex ();
 
@@ -1399,12 +1191,6 @@ readgram (void)
          {
            lhs = symval;
 
-           if (!start_flag)
-             {
-               startval = lhs;
-               start_flag = 1;
-             }
-
            t = lex ();
            if (t != tok_colon)
              {
@@ -1412,39 +1198,13 @@ readgram (void)
                unlex (t);
              }
          }
-
        if (nrules == 0 && t == tok_bar)
          {
            complain (_("grammar starts with vertical bar"));
            lhs = symval;       /* BOGUS: use a random symval */
          }
-       /* start a new rule and record its lhs.  */
-
-       ++nrules;
-       ++nritems;
-
-       p = symbol_list_new (lhs);
-
-       crule1 = p1;
-       if (p1)
-         p1->next = p;
-       else
-         grammar = p;
-
-       p1 = p;
-       crule = p;
-
-       /* mark the rule's lhs as a nonterminal if not already so.  */
-
-       if (lhs->class == unknown_sym)
-         {
-           lhs->class = nterm_sym;
-           lhs->number = nvars;
-           ++nvars;
-         }
-       else if (lhs->class == token_sym)
-         complain (_("rule given for %s, which is a token"), lhs->tag);
 
+       grammar_rule_begin (lhs);
        /* read the rhs of the rule.  */
 
        for (;;)
@@ -1453,7 +1213,7 @@ readgram (void)
            if (t == tok_prec)
              {
                t = lex ();
-               crule->ruleprec = symval;
+               current_rule->ruleprec = symval;
                t = lex ();
              }
 
@@ -1488,56 +1248,18 @@ readgram (void)
               non-terminal.  */
            if (action_flag)
              {
-               /* Since the action was written out with this rule's
-                  number, we must give the new rule this number by
-                  inserting the new rule before it.  */
-
-               /* Make a dummy nonterminal, a gensym.  */
-               symbol_t *sdummy = gensym ();
-
-               /* Make a new rule, whose body is empty, before the
-                  current one, so that the action just read can
-                  belong to it.  */
-               ++nrules;
-               ++nritems;
-               p = symbol_list_new (sdummy);
-               /* Attach its lineno to that of the host rule. */
-               p->line = crule->line;
-               /* Move the action from the host rule to this one. */
-               p->action = crule->action;
-               p->action_line = crule->action_line;
-               crule->action = NULL;
-
-               if (crule1)
-                 crule1->next = p;
-               else
-                 grammar = p;
-               /* End of the rule. */
-               crule1 = symbol_list_new (NULL);
-               crule1->next = crule;
-
-               p->next = crule1;
-
-               /* Insert the dummy generated by that rule into this
-                  rule.  */
-               ++nritems;
-               p = symbol_list_new (sdummy);
-               p1->next = p;
-               p1 = p;
-
+               grammar_midrule_action ();
                action_flag = 0;
              }
 
            if (t == tok_identifier)
              {
                ++nritems;
-               p = symbol_list_new (symval);
-               p1->next = p;
-               p1 = p;
+               grammar_symbol_append (symval);
              }
            else                /* handle an action.  */
              {
-               parse_action (crule, rulelength);
+               parse_action (current_rule, rulelength);
                action_flag = 1;
                ++xactions;     /* JF */
              }
@@ -1545,15 +1267,13 @@ readgram (void)
          }                     /* end of  read rhs of rule */
 
        /* Put an empty link in the list to mark the end of this rule  */
-       p = symbol_list_new (NULL);
-       p1->next = p;
-       p1 = p;
+       grammar_symbol_append (NULL);
 
        if (t == tok_prec)
          {
            complain (_("two @prec's in a row"));
            t = lex ();
-           crule->ruleprec = symval;
+           current_rule->ruleprec = symval;
            t = lex ();
          }
 
@@ -1562,7 +1282,7 @@ readgram (void)
            /* This case never occurs -wjh */
            if (action_flag)
              complain (_("two actions at end of one rule"));
-           parse_action (crule, rulelength);
+           parse_action (current_rule, rulelength);
            action_flag = 1;
            ++xactions; /* -wjh */
            t = lex ();
@@ -1599,22 +1319,23 @@ readgram (void)
     fatal (_("no rules in the input grammar"));
 
   /* Report any undefined symbols and consider them nonterminals.  */
-  symbols_do (symbol_check_defined, NULL);
+  symbols_check_defined ();
 
   /* Insert the initial rule, which line is that of the first rule
      (not that of the start symbol):
 
      axiom: %start EOF.  */
-  p = symbol_list_new (axiom);
-  p->line = grammar->line;
-  p->next = symbol_list_new (startval);
-  p->next->next = symbol_list_new (eoftoken);
-  p->next->next->next = symbol_list_new (NULL);
-  p->next->next->next->next = grammar;
-  nrules += 1;
-  nritems += 3;
-  grammar = p;
-  startval = axiom;
+  {
+    symbol_list *p = symbol_list_new (axiom);
+    p->line = grammar->line;
+    p->next = symbol_list_new (startsymbol);
+    p->next->next = symbol_list_new (eoftoken);
+    p->next->next->next = symbol_list_new (NULL);
+    p->next->next->next->next = grammar;
+    nrules += 1;
+    nritems += 3;
+    grammar = p;
+  }
 
   if (nsyms > SHRT_MAX)
     fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
@@ -1649,84 +1370,6 @@ read_additionnal_code (void)
 }
 
 \f
-/*------------------------------------------------------------------.
-| 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 != SUNDEF)
-       {
-         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 == SUNDEF)
-    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 == SUNDEF)
-       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 (token_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;
-}
-
-
 /*---------------------------------------------------------------.
 | Convert the rules into the representation using RRHS, RLHS and |
 | RITEM.                                                         |
@@ -1735,11 +1378,11 @@ packsymbols (void)
 static void
 packgram (void)
 {
-  int itemno;
+  unsigned int itemno;
   int ruleno;
   symbol_list *p;
 
-  ritem = XCALLOC (item_number_t, nritems + 1);
+  ritem = XCALLOC (item_number_t, nritems);
   rules = XCALLOC (rule_t, nrules) - 1;
 
   itemno = 0;
@@ -1761,9 +1404,9 @@ packgram (void)
       p = p->next;
       while (p && p->sym)
        {
-         /* item_number_t = token_number_t.
+         /* item_number_t = symbol_number_t.
             But the former needs to contain more: negative rule numbers. */
-         ritem[itemno++] = token_number_as_item_number (p->sym->number);
+         ritem[itemno++] = symbol_number_as_item_number (p->sym->number);
          /* A rule gets by default the precedence and associativity
             of the last token in it.  */
          if (p->sym->class == token_sym)
@@ -1786,7 +1429,6 @@ packgram (void)
        p = p->next;
     }
 
-  ritem[itemno] = 0;
   assert (itemno == nritems);
 
   if (trace_flag)
@@ -1862,7 +1504,7 @@ reader (void)
 
   /* Assign the symbols their symbol numbers.  Write #defines for the
      token symbols into FDEFINES if requested.  */
-  packsymbols ();
+  symbols_pack ();
 
   /* Convert the grammar into the format described in gram.h.  */
   packgram ();
@@ -1870,12 +1512,3 @@ reader (void)
   /* The grammar as a symbol_list is no longer needed. */
   LIST_FREE (symbol_list, grammar);
 }
-
-void
-grammar_free (void)
-{
-  XFREE (ritem);
-  free (rules + 1);
-  /* Free the symbol table data structure.  */
-  symbols_free ();
-}