]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
* src/symtab.h (SALIAS, SUNDEF): Rename as...
[bison.git] / src / reader.c
index a37f2d4a29c62bbb8c5585b653c2de337fed0821..75957010632f83d9c95c4132521535c48eaec0a3 100644 (file)
 typedef struct symbol_list
 {
   struct symbol_list *next;
-  bucket *sym;
+  symbol_t *sym;
   int line;
 
   /* The action is attached to the LHS of a rule. */
   const char *action;
   int action_line;
 
-  /* The guard is attached to the LHS of a rule. */
-  const char *guard;
-  int guard_line;
-  bucket *ruleprec;
+  symbol_t *ruleprec;
 } symbol_list;
 
 int lineno;
 static symbol_list *grammar = NULL;
 static int start_flag = 0;
-static bucket *startval = NULL;
+static symbol_t *startval = NULL;
 
 /* Nonzero if components of semantic values are used, implying
    they must be unions.  */
@@ -66,13 +63,13 @@ static int typed = 0;
 /* Incremented for each %left, %right or %nonassoc seen */
 static int lastprec = 0;
 
-bucket *errtoken = NULL;
-bucket *undeftoken = NULL;
-bucket *eoftoken = NULL;
-bucket *axiom = NULL;
+symbol_t *errtoken = NULL;
+symbol_t *undeftoken = NULL;
+symbol_t *eoftoken = NULL;
+symbol_t *axiom = NULL;
 
 static symbol_list *
-symbol_list_new (bucket *sym)
+symbol_list_new (symbol_t *sym)
 {
   symbol_list *res = XMALLOC (symbol_list, 1);
   res->next = NULL;
@@ -80,14 +77,12 @@ symbol_list_new (bucket *sym)
   res->line = lineno;
   res->action = NULL;
   res->action_line = 0;
-  res->guard = NULL;
-  res->guard_line = 0;
   res->ruleprec = NULL;
   return res;
 }
 
 /*------------------------.
-| Operations on buckets.  |
+| Operations on symbols.  |
 `------------------------*/
 
 
@@ -97,7 +92,7 @@ symbol_list_new (bucket *sym)
 `-----------------------------------------------------------*/
 
 static bool
-bucket_check_defined (bucket *this)
+symbol_check_defined (symbol_t *this)
 {
   if (this->class == unknown_sym)
     {
@@ -118,7 +113,7 @@ bucket_check_defined (bucket *this)
 `-------------------------------------------------------------------*/
 
 static bool
-bucket_make_alias (bucket *symbol, char *typename)
+symbol_make_alias (symbol_t *symbol, char *typename)
 {
   if (symval->alias)
     warn (_("symbol `%s' used more than once as a literal string"),
@@ -131,7 +126,7 @@ bucket_make_alias (bucket *symbol, char *typename)
       symval->class = token_sym;
       symval->type_name = typename;
       symval->user_token_number = symbol->user_token_number;
-      symbol->user_token_number = SALIAS;
+      symbol->user_token_number = USER_NUMBER_ALIAS;
       symval->alias = symbol;
       symbol->alias = symval;
       /* symbol and symval combined are only one symbol */
@@ -151,10 +146,10 @@ bucket_make_alias (bucket *symbol, char *typename)
 `---------------------------------------------------------*/
 
 static bool
-bucket_check_alias_consistence (bucket *this)
+symbol_check_alias_consistence (symbol_t *this)
 {
   /* Check only those who _are_ the aliases. */
-  if (this->alias && this->user_token_number == SALIAS)
+  if (this->alias && this->user_token_number == USER_NUMBER_ALIAS)
     {
       if (this->prec != this->alias->prec)
        {
@@ -188,13 +183,8 @@ bucket_check_alias_consistence (bucket *this)
 `-------------------------------------------------------------------*/
 
 static bool
-bucket_pack (bucket *this)
+symbol_pack (symbol_t *this)
 {
-  if (getenv ("DEBUG"))
-    fprintf (stderr, "Packing %s, %s, number = %d\n",
-            this->tag,
-            this->class == nterm_sym ? "nterm" : "TERM",
-            this->number);
   if (this->class == nterm_sym)
     {
       this->number += ntokens;
@@ -204,27 +194,25 @@ bucket_pack (bucket *this)
       /* 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 == -1)
+      if (this->number == NUMBER_UNDEFINED)
        {
          if (this == eoftoken || this->alias == eoftoken)
            this->number = this->alias->number = 0;
          else
            {
-             assert (this->alias->number != -1);
+             assert (this->alias->number != NUMBER_UNDEFINED);
              this->number = this->alias->number;
            }
        }
-      /* Do not do processing below for SALIASs.  */
-      if (this->user_token_number == SALIAS)
+      /* 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 != -1);
+      assert (this->number != NUMBER_UNDEFINED);
     }
 
-  if (getenv ("DEBUG"))
-    fprintf (stderr, "Setting %d = %s\n", this->number, this->tag);
   symbols[this->number] = this;
   return TRUE;
 }
@@ -237,25 +225,18 @@ bucket_pack (bucket *this)
 `--------------------------------------------------*/
 
 static bool
-bucket_translation (bucket *this)
+symbol_translation (symbol_t *this)
 {
-  if (getenv ("DEBUG"))
-    fprintf (stderr, "Considering Setting UserVal %s = %d (val = %d)\n",
-            this->tag, this->user_token_number, this->number);
-
   /* Non-terminal? */
   if (this->class == token_sym
-      && this->user_token_number != SALIAS)
+      && this->user_token_number != USER_NUMBER_ALIAS)
     {
       /* A token which translation has already been set? */
-      if (token_translations[this->user_token_number] != 2)
+      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);
 
-      if (getenv ("DEBUG"))
-       fprintf (stderr, "Setting UserVal %s = %d (val = %d)\n",
-                this->tag, this->user_token_number, this->number);
       token_translations[this->user_token_number] = this->number;
     }
 
@@ -340,12 +321,34 @@ get_type_name (int n, symbol_list *rule)
          complain (_("invalid $ value"));
          return NULL;
        }
-      i++;
+      ++i;
     }
 
   return rp->sym->type_name;
 }
 \f
+/*------------------------------------------------------------------.
+| Copy the character C to OOUT, and insert quadigraphs when needed. |
+`------------------------------------------------------------------*/
+
+static inline void
+copy_character (struct obstack *oout, int c)
+{
+  switch (c)
+    {
+    case '[':
+      obstack_sgrow (oout, "@<:@");
+      break;
+
+    case ']':
+      obstack_sgrow (oout, "@:>@");
+      break;
+
+    default:
+      obstack_1grow (oout, c);
+    }
+}
+
 /*------------------------------------------------------------.
 | Dump the string from FIN to OOUT if non null.  MATCH is the |
 | delimiter of the string (either ' or ").                    |
@@ -373,17 +376,17 @@ copy_string2 (FILE *fin, struct obstack *oout, int match, int store)
          continue;
        }
 
-      obstack_1grow (oout, c);
+      copy_character (oout, c);
 
       if (c == '\\')
        {
          c = getc (fin);
          if (c == EOF)
            fatal (_("unterminated string at end of file"));
-         obstack_1grow (oout, c);
+         copy_character (oout, c);
 
          if (c == '\n')
-           lineno++;
+           ++lineno;
        }
 
       c = getc (fin);
@@ -466,7 +469,7 @@ copy_comment (FILE *fin, struct obstack *oout)
        }
       else if (c == '\n')
        {
-         lineno++;
+         ++lineno;
          obstack_1grow (oout, c);
          if (cplus_comment)
            ended = 1;
@@ -477,30 +480,29 @@ copy_comment (FILE *fin, struct obstack *oout)
        fatal (_("unterminated comment"));
       else
        {
-         obstack_1grow (oout, c);
+         copy_character (oout, c);
          c = getc (fin);
        }
     }
 }
 
 
-/*-----------------------------------------------------------------.
-| FIN is pointing to a location (i.e., a `@').  Output to OOUT a   |
-| reference to this location. STACK_OFFSET is the number of values |
-| in the current rule so far, which says where to find `$0' with   |
-| respect to the top of the stack.                                 |
-`-----------------------------------------------------------------*/
+/*-------------------------------------------------------------------.
+| FIN is pointing to a location (i.e., a `@').  Output to OOUT a     |
+| reference to this location. RULE_LENGTH is the number of values in |
+| the current rule so far, which says where to find `$0' with        |
+| respect to the top of the stack.                                   |
+`-------------------------------------------------------------------*/
 
 static inline void
-copy_at (FILE *fin, struct obstack *oout, int stack_offset)
+copy_at (FILE *fin, struct obstack *oout, int rule_length)
 {
-  int c;
+  int c = getc (fin);
+  locations_flag = 1;
 
-  c = getc (fin);
   if (c == '$')
     {
-      obstack_sgrow (oout, "yyloc");
-      locations_flag = 1;
+      obstack_sgrow (oout, "]b4_lhs_location[");
     }
   else if (isdigit (c) || c == '-')
     {
@@ -508,16 +510,11 @@ copy_at (FILE *fin, struct obstack *oout, int stack_offset)
 
       ungetc (c, fin);
       n = read_signed_integer (fin);
-      if (n > stack_offset)
+      if (n > rule_length)
        complain (_("invalid value: %s%d"), "@", n);
       else
-       {
-         /* Offset is always 0 if parser has already popped the stack
-            pointer.  */
-         obstack_fgrow1 (oout, "yylsp[%d]",
-                         n - (semantic_parser ? 0 : stack_offset));
-         locations_flag = 1;
-       }
+       obstack_fgrow2 (oout, "]b4_rhs_location([%d], [%d])[",
+                       rule_length, n);
     }
   else
     {
@@ -528,19 +525,19 @@ copy_at (FILE *fin, struct obstack *oout, int stack_offset)
 }
 
 
-/*-------------------------------------------------------------------.
-| FIN is pointing to a wannabee semantic value (i.e., a `$').        |
-|                                                                    |
-| Possible inputs: $[<TYPENAME>]($|integer)                          |
-|                                                                    |
-| Output to OOUT a reference to this semantic value. STACK_OFFSET is |
-| the number of values in the current rule so far, which says where  |
-| to find `$0' with respect to the top of the stack.                 |
-`-------------------------------------------------------------------*/
+/*------------------------------------------------------------------.
+| FIN is pointing to a wannabee semantic value (i.e., a `$').       |
+|                                                                   |
+| Possible inputs: $[<TYPENAME>]($|integer)                         |
+|                                                                   |
+| Output to OOUT a reference to this semantic value. RULE_LENGTH is |
+| the number of values in the current rule so far, which says where |
+| to find `$0' with respect to the top of the stack.                |
+`------------------------------------------------------------------*/
 
 static inline void
 copy_dollar (FILE *fin, struct obstack *oout,
-            symbol_list *rule, int stack_offset)
+            symbol_list *rule, int rule_length)
 {
   int c = getc (fin);
   const char *type_name = NULL;
@@ -556,15 +553,15 @@ copy_dollar (FILE *fin, struct obstack *oout,
 
   if (c == '$')
     {
-      obstack_sgrow (oout, "yyval");
-
       if (!type_name)
        type_name = get_type_name (0, rule);
-      if (type_name)
-       obstack_fgrow1 (oout, ".%s", type_name);
       if (!type_name && typed)
        complain (_("$$ of `%s' has no declared type"),
                  rule->sym->tag);
+      if (!type_name)
+       type_name = "";
+      obstack_fgrow1 (oout,
+                     "]b4_lhs_value([%s])[", type_name);
     }
   else if (isdigit (c) || c == '-')
     {
@@ -572,23 +569,19 @@ copy_dollar (FILE *fin, struct obstack *oout,
       ungetc (c, fin);
       n = read_signed_integer (fin);
 
-      if (n > stack_offset)
+      if (n > rule_length)
        complain (_("invalid value: %s%d"), "$", n);
       else
        {
          if (!type_name && n > 0)
            type_name = get_type_name (n, rule);
-
-         /* Offset is always 0 if parser has already popped the stack
-            pointer.  */
-         obstack_fgrow1 (oout, "yyvsp[%d]",
-                         n - (semantic_parser ? 0 : stack_offset));
-
-         if (type_name)
-           obstack_fgrow1 (oout, ".%s", type_name);
          if (!type_name && typed)
            complain (_("$%d of `%s' has no declared type"),
                      n, rule->sym->tag);
+         if (!type_name)
+           type_name = "";
+         obstack_fgrow3 (oout, "]b4_rhs_value([%d], [%d], [%s])[",
+                         rule_length, n, type_name);
        }
     }
   else
@@ -605,7 +598,7 @@ copy_dollar (FILE *fin, struct obstack *oout,
 `-------------------------------------------------------------------*/
 
 static void
-copy_definition (void)
+copy_definition (struct obstack *oout)
 {
   int c;
   /* -1 while reading a character if prev char was %. */
@@ -613,7 +606,7 @@ copy_definition (void)
 
   if (!no_lines_flag)
     {
-      obstack_fgrow2 (&attrs_obstack, muscle_find ("linef"),
+      obstack_fgrow2 (oout, muscle_find ("linef"),
                      lineno, quotearg_style (c_quoting_style,
                                              muscle_find ("filename")));
     }
@@ -627,8 +620,8 @@ copy_definition (void)
       switch (c)
        {
        case '\n':
-         obstack_1grow (&attrs_obstack, c);
-         lineno++;
+         obstack_1grow (oout, c);
+         ++lineno;
          break;
 
        case '%':
@@ -637,18 +630,18 @@ copy_definition (void)
 
        case '\'':
        case '"':
-         copy_string (finput, &attrs_obstack, c);
+         copy_string (finput, oout, c);
          break;
 
        case '/':
-         copy_comment (finput, &attrs_obstack);
+         copy_comment (finput, oout);
          break;
 
        case EOF:
          fatal ("%s", _("unterminated `%{' definition"));
 
        default:
-         obstack_1grow (&attrs_obstack, c);
+         copy_character (oout, c);
        }
 
       c = getc (finput);
@@ -657,7 +650,7 @@ copy_definition (void)
        {
          if (c == '}')
            return;
-         obstack_1grow (&attrs_obstack, '%');
+         obstack_1grow (oout, '%');
        }
       after_percent = 0;
     }
@@ -677,7 +670,7 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not)
   char *typename = NULL;
 
   /* The symbol being defined.  */
-  struct bucket *symbol = NULL;
+  symbol_t *symbol = NULL;
 
   /* After `%token' and `%nterm', any number of symbols maybe be
      defined.  */
@@ -706,7 +699,7 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not)
        }
       else if (token == tok_identifier && *symval->tag == '\"' && symbol)
        {
-         bucket_make_alias (symbol, typename);
+         symbol_make_alias (symbol, typename);
          symbol = NULL;
        }
       else if (token == tok_identifier)
@@ -719,13 +712,8 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not)
          symbol->class = what_is;
          if (what_is == nterm_sym && oldclass != nterm_sym)
            symbol->number = nvars++;
-         if (what_is == token_sym && symbol->number == -1)
-           {
-             symbol->number = ntokens++;
-             if (getenv ("DEBUG"))
-               fprintf (stderr, "Set %s to %d\n",
-                        symbol->tag, symbol->number);
-           }
+         if (what_is == token_sym && symbol->number == NUMBER_UNDEFINED)
+           symbol->number = ntokens++;
 
          if (typename)
            {
@@ -845,7 +833,8 @@ parse_assoc_decl (associativity assoc)
   char *name = NULL;
   int prev = 0;
 
-  lastprec++;                  /* Assign a new precedence level, never 0.  */
+  /* Assign a new precedence level, never 0.  */
+  ++lastprec;
 
   for (;;)
     {
@@ -875,7 +864,7 @@ parse_assoc_decl (associativity assoc)
          symval->assoc = assoc;
          if (symval->class == nterm_sym)
            complain (_("symbol %s redefined"), symval->tag);
-         if (symval->number == -1)
+         if (symval->number == NUMBER_UNDEFINED)
            {
              symval->number = ntokens++;
              symval->class = token_sym;
@@ -950,7 +939,7 @@ parse_union_decl (void)
       switch (c)
        {
        case '\n':
-         lineno++;
+         ++lineno;
          break;
 
        case '/':
@@ -958,7 +947,7 @@ parse_union_decl (void)
          break;
 
        case '{':
-         count++;
+         ++count;
          break;
 
        case '}':
@@ -1009,10 +998,10 @@ parse_expect_decl (void)
 |                                                                    |
 | 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.                                  |
+| declaration.  The ->user_token_number of the first is              |
+| USER_NUMBER_ALIAS 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  |
@@ -1023,9 +1012,9 @@ static void
 parse_thong_decl (void)
 {
   token_t token;
-  struct bucket *symbol;
+  symbol_t *symbol;
   char *typename = 0;
-  int usrtoknum = SUNDEF;
+  int usrtoknum = USER_NUMBER_UNDEFINED;
 
   token = lex ();              /* fetch typename or first token */
   if (token == tok_typename)
@@ -1046,7 +1035,7 @@ parse_thong_decl (void)
     }
   symval->class = token_sym;
   symval->type_name = typename;
-  symval->user_token_number = SALIAS;
+  symval->user_token_number = USER_NUMBER_ALIAS;
   symbol = symval;
 
   token = lex ();              /* get number or literal string */
@@ -1172,7 +1161,7 @@ parse_skel_decl (void)
 /*----------------------------------------------------------------.
 | Read from finput until `%%' is seen.  Discard the `%%'.  Handle |
 | any `%' declarations, and copy the contents of any `%{ ... %}'  |
-| groups to ATTRS_OBSTACK.                                        |
+| groups to PRE_PROLOGUE_OBSTACK or POST_PROLOGUE_OBSTACK.        |
 `----------------------------------------------------------------*/
 
 static void
@@ -1192,7 +1181,10 @@ read_declarations (void)
              return;
 
            case tok_percent_left_curly:
-             copy_definition ();
+              if (!typed)
+               copy_definition (&pre_prologue_obstack);
+             else
+               copy_definition (&post_prologue_obstack);
              break;
 
            case tok_token:
@@ -1270,37 +1262,37 @@ read_declarations (void)
     }
 }
 \f
-/*-------------------------------------------------------------------.
-| Assuming that a `{' has just been seen, copy everything up to the  |
-| matching `}' into the actions file.  STACK_OFFSET is the number of |
-| values in the current rule so far, which says where to find `$0'   |
-| with respect to the top of the stack.                              |
-|                                                                    |
-| This routine is used both for actions and guards.  Only            |
-| ACTION_OBSTACK is used, but this is fine, since we use only        |
-| pointers to relevant portions inside this obstack.                 |
-`-------------------------------------------------------------------*/
+/*------------------------------------------------------------------.
+| Assuming that a `{' has just been seen, copy everything up to the |
+| matching `}' into ACTION_OBSTACK.                                 |
+|                                                                   |
+| RULE_LENGTH is the number of values in the current rule so far,   |
+| which says where to find `$0' with respect to the top of the      |
+| stack.  It is not the same as the rule->length in the case of mid |
+| rule actions.                                                     |
+|                                                                   |
+| This routine is used for actions.                                 |
+`------------------------------------------------------------------*/
 
 static void
-parse_braces (symbol_list *rule, int stack_offset)
+parse_action (symbol_list *rule, int rule_length)
 {
-  int c;
-  int count;
-
-  count = 1;
+  int count = 1;
+  rule->action_line = lineno;
   while (count > 0)
     {
+      int c;
       while ((c = getc (finput)) != '}')
        switch (c)
          {
          case '\n':
            obstack_1grow (&action_obstack, c);
-           lineno++;
+           ++lineno;
            break;
 
          case '{':
            obstack_1grow (&action_obstack, c);
-           count++;
+           ++count;
            break;
 
          case '\'':
@@ -1313,13 +1305,11 @@ parse_braces (symbol_list *rule, int stack_offset)
            break;
 
          case '$':
-           copy_dollar (finput, &action_obstack,
-                        rule, stack_offset);
+           copy_dollar (finput, &action_obstack, rule, rule_length);
            break;
 
          case '@':
-           copy_at (finput, &action_obstack,
-                    stack_offset);
+           copy_at (finput, &action_obstack, rule_length);
            break;
 
          case EOF:
@@ -1335,29 +1325,9 @@ parse_braces (symbol_list *rule, int stack_offset)
     }
 
   obstack_1grow (&action_obstack, '\0');
-}
-
-
-static void
-parse_action (symbol_list *rule, int stack_offset)
-{
-  rule->action_line = lineno;
-  parse_braces (rule, stack_offset);
   rule->action = obstack_finish (&action_obstack);
 }
 
-
-static void
-parse_guard (symbol_list *rule, int stack_offset)
-{
-  token_t t = lex ();
-  if (t != tok_left_curly)
-    complain (_("invalid %s declaration"), "%guard");
-  rule->guard_line = lineno;
-  parse_braces (rule, stack_offset);
-  rule->guard = obstack_finish (&action_obstack);
-}
-
 \f
 
 /*-------------------------------------------------------------------.
@@ -1365,14 +1335,14 @@ parse_guard (symbol_list *rule, int stack_offset)
 | with the user's names.                                             |
 `-------------------------------------------------------------------*/
 
-static bucket *
+static symbol_t *
 gensym (void)
 {
   /* Incremented for each generated symbol */
   static int gensym_count = 0;
   static char buf[256];
 
-  bucket *sym;
+  symbol_t *sym;
 
   sprintf (buf, "@%d", ++gensym_count);
   token_buffer = buf;
@@ -1389,8 +1359,8 @@ gensym (void)
 | null pointer instead of a symbol to terminate the rule.  The next  |
 | symbol is the lhs of the following rule.                           |
 |                                                                    |
-| All guards and actions are copied out to the appropriate files,    |
-| labelled by the rule number they apply to.                         |
+| All actions are copied out, labelled by the rule number they apply |
+| to.                                                                |
 |                                                                    |
 | Bison used to allow some %directives in the rules sections, but    |
 | this is no longer consider appropriate: (i) the documented grammar |
@@ -1404,7 +1374,7 @@ static void
 readgram (void)
 {
   token_t t;
-  bucket *lhs = NULL;
+  symbol_t *lhs = NULL;
   symbol_list *p = NULL;
   symbol_list *p1 = NULL;
 
@@ -1423,7 +1393,7 @@ readgram (void)
        /* Number of symbols in rhs of this rule so far */
        int rulelength = 0;
        int xactions = 0;       /* JF for error checking */
-       bucket *first_rhs = 0;
+       symbol_t *first_rhs = 0;
 
        if (t == tok_identifier)
          {
@@ -1450,8 +1420,8 @@ readgram (void)
          }
        /* start a new rule and record its lhs.  */
 
-       nrules++;
-       nitems++;
+       ++nrules;
+       ++nritems;
 
        p = symbol_list_new (lhs);
 
@@ -1470,7 +1440,7 @@ readgram (void)
          {
            lhs->class = nterm_sym;
            lhs->number = nvars;
-           nvars++;
+           ++nvars;
          }
        else if (lhs->class == token_sym)
          complain (_("rule given for %s, which is a token"), lhs->tag);
@@ -1494,7 +1464,7 @@ readgram (void)
               If one does, exit this rule now.  */
            if (t == tok_identifier)
              {
-               bucket *ssave;
+               symbol_t *ssave;
                token_t t1;
 
                ssave = symval;
@@ -1523,13 +1493,13 @@ readgram (void)
                   inserting the new rule before it.  */
 
                /* Make a dummy nonterminal, a gensym.  */
-               bucket *sdummy = 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++;
-               nitems++;
+               ++nrules;
+               ++nritems;
                p = symbol_list_new (sdummy);
                /* Attach its lineno to that of the host rule. */
                p->line = crule->line;
@@ -1550,7 +1520,7 @@ readgram (void)
 
                /* Insert the dummy generated by that rule into this
                   rule.  */
-               nitems++;
+               ++nritems;
                p = symbol_list_new (sdummy);
                p1->next = p;
                p1 = p;
@@ -1560,7 +1530,7 @@ readgram (void)
 
            if (t == tok_identifier)
              {
-               nitems++;
+               ++nritems;
                p = symbol_list_new (symval);
                p1->next = p;
                p1 = p;
@@ -1569,9 +1539,9 @@ readgram (void)
              {
                parse_action (crule, rulelength);
                action_flag = 1;
-               xactions++;     /* JF */
+               ++xactions;     /* JF */
              }
-           rulelength++;
+           ++rulelength;
          }                     /* end of  read rhs of rule */
 
        /* Put an empty link in the list to mark the end of this rule  */
@@ -1587,15 +1557,6 @@ readgram (void)
            t = lex ();
          }
 
-       if (t == tok_guard)
-         {
-           if (!semantic_parser)
-             complain (_("%%guard present but %%semantic_parser not specified"));
-
-           parse_guard (crule, rulelength);
-           t = lex ();
-         }
-
        if (t == tok_left_curly)
          {
            /* This case never occurs -wjh */
@@ -1603,7 +1564,7 @@ readgram (void)
              complain (_("two actions at end of one rule"));
            parse_action (crule, rulelength);
            action_flag = 1;
-           xactions++; /* -wjh */
+           ++xactions; /* -wjh */
            t = lex ();
          }
        /* If $$ is being set in default way, report if any type
@@ -1638,7 +1599,7 @@ readgram (void)
     fatal (_("no rules in the input grammar"));
 
   /* Report any undefined symbols and consider them nonterminals.  */
-  buckets_do (bucket_check_defined, NULL);
+  symbols_do (symbol_check_defined, NULL);
 
   /* Insert the initial rule, which line is that of the first rule
      (not that of the start symbol):
@@ -1651,17 +1612,14 @@ readgram (void)
   p->next->next->next = symbol_list_new (NULL);
   p->next->next->next->next = grammar;
   nrules += 1;
-  nitems += 3;
+  nritems += 3;
   grammar = p;
   startval = axiom;
 
-  if (nsyms > MAXSHORT)
+  if (nsyms > SHRT_MAX)
     fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
-          MAXSHORT);
+          SHRT_MAX);
 
-  if (getenv ("DEBUG"))
-    fprintf (stderr, "nsyms == ntokens + nvars: %d == %d + %d\n",
-            nsyms, ntokens, nvars);
   assert (nsyms == ntokens + nvars);
 }
 
@@ -1684,7 +1642,7 @@ read_additionnal_code (void)
     }
 
   while ((c = getc (finput)) != EOF)
-    obstack_1grow (&el_obstack, c);
+    copy_character (&el_obstack, c);
 
   obstack_1grow (&el_obstack, 0);
   muscle_insert ("epilogue", obstack_finish (&el_obstack));
@@ -1699,34 +1657,50 @@ read_additionnal_code (void)
 static void
 token_translations_init (void)
 {
-  int last_user_token_number = 256;
+  int num_256_available_p = TRUE;
   int i;
 
-  /* Set the user numbers. */
+  /* 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)
     {
-      bucket *this = symbols[i];
-      if (getenv ("DEBUG"))
-       fprintf (stderr, "UserVal %s = %d (val = %d)\n",
-                this->tag, this->user_token_number, this->number);
-      if (this->user_token_number == SUNDEF)
-       this->user_token_number = ++last_user_token_number;
+      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;
-      if (getenv ("DEBUG"))
-       fprintf (stderr, "Now: UserVal %s = %d (val = %d)\n",
-                this->tag, this->user_token_number, this->number);
     }
 
-  token_translations = XCALLOC (short, max_user_token_number + 1);
+  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] = 2;
-
-  buckets_do (bucket_translation, NULL);
+    token_translations[i] = undeftoken->number;
+  symbols_do (symbol_translation, NULL);
 }
 
 
@@ -1738,15 +1712,13 @@ token_translations_init (void)
 static void
 packsymbols (void)
 {
-  symbols = XCALLOC (bucket *, nsyms);
+  symbols = XCALLOC (symbol_t *, nsyms);
 
-  buckets_do (bucket_check_alias_consistence, NULL);
-  buckets_do (bucket_pack, NULL);
+  symbols_do (symbol_check_alias_consistence, NULL);
+  symbols_do (symbol_pack, NULL);
 
   token_translations_init ();
 
-  error_token_number = errtoken->number;
-
   if (startval->class == unknown_sym)
     fatal (_("the start symbol %s is undefined"), startval->tag);
   else if (startval->class == token_sym)
@@ -1768,11 +1740,7 @@ packgram (void)
   int ruleno;
   symbol_list *p;
 
-  /* We use short to index items.  */
-  if (nitems >= MAXSHORT)
-    fatal (_("too many items (max %d)"), MAXSHORT);
-
-  ritem = XCALLOC (short, nitems + 1);
+  ritem = XCALLOC (item_number_t, nritems + 1);
   rules = XCALLOC (rule_t, nrules) - 1;
 
   itemno = 0;
@@ -1781,7 +1749,7 @@ packgram (void)
   p = grammar;
   while (p)
     {
-      bucket *ruleprec = p->ruleprec;
+      symbol_t *ruleprec = p->ruleprec;
       rules[ruleno].user_number = ruleno;
       rules[ruleno].number = ruleno;
       rules[ruleno].lhs = p->sym;
@@ -1790,13 +1758,13 @@ packgram (void)
       rules[ruleno].useful = TRUE;
       rules[ruleno].action = p->action;
       rules[ruleno].action_line = p->action_line;
-      rules[ruleno].guard = p->guard;
-      rules[ruleno].guard_line = p->guard_line;
 
       p = p->next;
       while (p && p->sym)
        {
-         ritem[itemno++] = p->sym->number;
+         /* item_number_t = token_number_t.
+            But the former needs to contain more: negative rule numbers. */
+         ritem[itemno++] = token_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)
@@ -1813,27 +1781,25 @@ packgram (void)
          rules[ruleno].prec = ruleprec;
        }
       ritem[itemno++] = -ruleno;
-      ruleno++;
+      ++ruleno;
 
       if (p)
        p = p->next;
     }
 
   ritem[itemno] = 0;
-  nritems = itemno;
-  assert (nritems == nitems);
+  assert (itemno == nritems);
 
   if (trace_flag)
     ritem_print (stderr);
 }
 \f
-/*-------------------------------------------------------------------.
-| Read in the grammar specification and record it in the format      |
-| described in gram.h.  All guards are copied into the GUARD_OBSTACK |
-| and all actions into ACTION_OBSTACK, in each case forming the body |
-| of a C function (YYGUARD or YYACTION) which contains a switch      |
-| statement to decide which guard or action to execute.              |
-`-------------------------------------------------------------------*/
+/*------------------------------------------------------------------.
+| Read in the grammar specification and record it in the format     |
+| described in gram.h.  All actions are copied into ACTION_OBSTACK, |
+| in each case forming the body of a C function (YYACTION) which    |
+| contains a switch statement to decide which action to execute.    |
+`------------------------------------------------------------------*/
 
 void
 reader (void)
@@ -1845,7 +1811,7 @@ reader (void)
   obstack_init (&muscle_obstack);
 
   /* Initialize the symbol table.  */
-  buckets_new ();
+  symbols_new ();
 
   /* Construct the axiom symbol. */
   axiom = getsym ("$axiom");
@@ -1856,19 +1822,18 @@ reader (void)
   errtoken = getsym ("error");
   errtoken->class = token_sym;
   errtoken->number = ntokens++;
-  errtoken->user_token_number = 256;   /* Value specified by POSIX.  */
 
   /* Construct a token that represents all undefined literal tokens.
      It is always token number 2.  */
   undeftoken = getsym ("$undefined.");
   undeftoken->class = token_sym;
   undeftoken->number = ntokens++;
-  undeftoken->user_token_number = 2;
 
   /* Initialize the obstacks. */
   obstack_init (&action_obstack);
-  obstack_init (&attrs_obstack);
   obstack_init (&output_obstack);
+  obstack_init (&pre_prologue_obstack);
+  obstack_init (&post_prologue_obstack);
 
   finput = xfopen (infile, "r");
 
@@ -1888,7 +1853,7 @@ reader (void)
     }
 
   /* Read in the grammar, build grammar in list form.  Write out
-     guards and actions.  */
+     actions.  */
   readgram ();
   /* Some C code is given at the end of the grammar file. */
   read_additionnal_code ();
@@ -1913,5 +1878,5 @@ grammar_free (void)
   XFREE (ritem);
   free (rules + 1);
   /* Free the symbol table data structure.  */
-  buckets_free ();
+  symbols_free ();
 }