]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
Update.
[bison.git] / src / reader.c
index 7e23c0ef94a6537c4554bc9b29928734e6635eda..5abb46edaeb3b7f3fb8bcf819766edc3b1164fe8 100644 (file)
@@ -1,5 +1,5 @@
 /* Input parser for bison
 /* Input parser for bison
-   Copyright 1984, 1986, 1989, 1992, 1998, 2000
+   Copyright 1984, 1986, 1989, 1992, 1998, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 #include "quote.h"
 #include "getargs.h"
 #include "files.h"
 #include "quote.h"
 #include "getargs.h"
 #include "files.h"
-#include "xalloc.h"
 #include "symtab.h"
 #include "symtab.h"
+#include "options.h"
 #include "lex.h"
 #include "gram.h"
 #include "complain.h"
 #include "output.h"
 #include "reader.h"
 #include "conflicts.h"
 #include "lex.h"
 #include "gram.h"
 #include "complain.h"
 #include "output.h"
 #include "reader.h"
 #include "conflicts.h"
+#include "muscle_tab.h"
 
 /* Number of slots allocated (but not necessarily used yet) in `rline'  */
 static int rline_allocated;
 
 /* Number of slots allocated (but not necessarily used yet) in `rline'  */
 static int rline_allocated;
@@ -156,11 +157,12 @@ get_type_name (int n, symbol_list * rule)
 `------------------------------------------------------------*/
 
 static inline void
 `------------------------------------------------------------*/
 
 static inline void
-copy_string (FILE *fin, struct obstack *oout, int match)
+copy_string2 (FILE *fin, struct obstack *oout, int match, int store)
 {
   int c;
 
 {
   int c;
 
-  obstack_1grow (oout, match);
+  if (store)
+    obstack_1grow (oout, match);
 
   c = getc (fin);
 
 
   c = getc (fin);
 
@@ -192,9 +194,30 @@ copy_string (FILE *fin, struct obstack *oout, int match)
       c = getc (fin);
     }
 
       c = getc (fin);
     }
 
-  obstack_1grow (oout, c);
+  if (store)
+    obstack_1grow (oout, c);
+}
+
+/* FIXME. */
+
+static inline void
+copy_string (FILE *fin, struct obstack *oout, int match)
+{
+  copy_string2 (fin, oout, match, 1);
 }
 
 }
 
+/* FIXME. */
+
+static inline void
+copy_identifier (FILE *fin, struct obstack *oout)
+{
+  int c;
+
+  while (isalnum (c = getc (fin)) || c == '_')
+    obstack_1grow (oout, c);
+
+  ungetc (c, fin);
+}
 
 /*-----------------------------------------------------------------.
 | Dump the wannabee comment from IN to OUT1 and OUT2 (which can be |
 
 /*-----------------------------------------------------------------.
 | Dump the wannabee comment from IN to OUT1 and OUT2 (which can be |
@@ -403,9 +426,14 @@ copy_definition (void)
   /* -1 while reading a character if prev char was %. */
   int after_percent;
 
   /* -1 while reading a character if prev char was %. */
   int after_percent;
 
+#if 0
   if (!no_lines_flag)
   if (!no_lines_flag)
-    obstack_fgrow2 (&attrs_obstack, "#line %d %s\n",
-                   lineno, quotearg_style (c_quoting_style, infile));
+    {
+      obstack_fgrow2 (&attrs_obstack, muscle_find ("linef"),
+                     lineno, quotearg_style (c_quoting_style,
+                                             muscle_find("filename")));
+    }
+#endif
 
   after_percent = 0;
 
 
   after_percent = 0;
 
@@ -462,8 +490,8 @@ copy_definition (void)
 static void
 parse_token_decl (symbol_class what_is, symbol_class what_is_not)
 {
 static void
 parse_token_decl (symbol_class what_is, symbol_class what_is_not)
 {
-  token_t token = 0;
-  char *typename = 0;
+  token_t token = tok_undef;
+  char *typename = NULL;
 
   /* The symbol being defined.  */
   struct bucket *symbol = NULL;
 
   /* The symbol being defined.  */
   struct bucket *symbol = NULL;
@@ -512,7 +540,6 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not)
              /* symbol and symval combined are only one symbol */
              nsyms--;
            }
              /* symbol and symval combined are only one symbol */
              nsyms--;
            }
-         translations = 1;
          symbol = NULL;
        }
       else if (token == tok_identifier)
          symbol = NULL;
        }
       else if (token == tok_identifier)
@@ -537,7 +564,6 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not)
       else if (symbol && token == tok_number)
        {
          symbol->user_token_number = numval;
       else if (symbol && token == tok_number)
        {
          symbol->user_token_number = numval;
-         translations = 1;
        }
       else
        {
        }
       else
        {
@@ -679,7 +705,6 @@ parse_assoc_decl (associativity assoc)
          if (prev == tok_identifier)
            {
              symval->user_token_number = numval;
          if (prev == tok_identifier)
            {
              symval->user_token_number = numval;
-             translations = 1;
            }
          else
            {
            }
          else
            {
@@ -699,16 +724,15 @@ token_buffer);
        }
 
       prev = t;
        }
 
       prev = t;
-
     }
 }
 
 
 
 /*--------------------------------------------------------------.
     }
 }
 
 
 
 /*--------------------------------------------------------------.
-| Copy the union declaration into ATTRS_OBSTACK (and fdefines), |
-| where it is made into the definition of YYSTYPE, the type of  |
-| elements of the parser value stack.                           |
+| Copy the union declaration into the stype muscle             |
+| (and fdefines),  where it is made into the definition of     |
+| YYSTYPE, the type of elements of the parser value stack.     |
 `--------------------------------------------------------------*/
 
 static void
 `--------------------------------------------------------------*/
 
 static void
@@ -716,29 +740,43 @@ parse_union_decl (void)
 {
   int c;
   int count = 0;
 {
   int c;
   int count = 0;
+  struct obstack union_obstack;
+  const char *prologue = "\
+#ifndef YYSTYPE\n\
+typedef union";
+  const char *epilogue = "\
+ yystype;\n\
+# define YYSTYPE yystype\n\
+#endif\n";
 
   if (typed)
     complain (_("multiple %s declarations"), "%union");
 
   typed = 1;
 
 
   if (typed)
     complain (_("multiple %s declarations"), "%union");
 
   typed = 1;
 
-  if (!no_lines_flag)
-    obstack_fgrow2 (&attrs_obstack, "\n#line %d %s\n",
-                   lineno, quotearg_style (c_quoting_style, infile));
-  else
+  /* FIXME: I'm worried: are you sure attrs_obstack is properly
+     filled?  */
+  /* I don't see any reasons to keep this line, because we should
+     create a special skeleton for this option.  */
+  if (no_lines_flag)
     obstack_1grow (&attrs_obstack, '\n');
 
     obstack_1grow (&attrs_obstack, '\n');
 
-  obstack_sgrow (&attrs_obstack, "typedef union");
+  obstack_init (&union_obstack);
+  obstack_sgrow (&union_obstack, "union");
   if (defines_flag)
   if (defines_flag)
-    obstack_sgrow (&defines_obstack, "typedef union");
+    obstack_sgrow (&defines_obstack, prologue);
 
   c = getc (finput);
 
   while (c != EOF)
     {
 
   c = getc (finput);
 
   while (c != EOF)
     {
-      obstack_1grow (&attrs_obstack, c);
-      if (defines_flag)
-       obstack_1grow (&defines_obstack, c);
+      /* If C contains '/', it is output by copy_comment ().  */
+      if (c != '/')
+       {
+         obstack_1grow (&union_obstack, c);
+         if (defines_flag)
+           obstack_1grow (&defines_obstack, c);
+       }
 
       switch (c)
        {
 
       switch (c)
        {
@@ -747,7 +785,7 @@ parse_union_decl (void)
          break;
 
        case '/':
          break;
 
        case '/':
-         copy_comment2 (finput, &defines_obstack, &attrs_obstack);
+         copy_comment2 (finput, &defines_obstack, &union_obstack);
          break;
 
        case '{':
          break;
 
        case '{':
@@ -760,19 +798,21 @@ parse_union_decl (void)
          count--;
          if (count <= 0)
            {
          count--;
          if (count <= 0)
            {
-             obstack_sgrow (&attrs_obstack, " YYSTYPE;\n");
              if (defines_flag)
              if (defines_flag)
-               obstack_sgrow (&defines_obstack, " YYSTYPE;\n");
+               obstack_sgrow (&defines_obstack, epilogue);
              /* JF don't choke on trailing semi */
              c = skip_white_space ();
              if (c != ';')
                ungetc (c, finput);
              /* JF don't choke on trailing semi */
              c = skip_white_space ();
              if (c != ';')
                ungetc (c, finput);
+             obstack_1grow (&union_obstack, 0);
+             muscle_insert ("stype", obstack_finish (&union_obstack));
              return;
            }
        }
 
       c = getc (finput);
     }
              return;
            }
        }
 
       c = getc (finput);
     }
+
 }
 
 
 }
 
 
@@ -820,9 +860,8 @@ parse_thong_decl (void)
   token_t token;
   struct bucket *symbol;
   char *typename = 0;
   token_t token;
   struct bucket *symbol;
   char *typename = 0;
-  int usrtoknum;
+  int usrtoknum = SUNDEF;
 
 
-  translations = 1;
   token = lex ();              /* fetch typename or first token */
   if (token == tok_typename)
     {
   token = lex ();              /* fetch typename or first token */
   if (token == tok_typename)
     {
@@ -852,8 +891,6 @@ parse_thong_decl (void)
       usrtoknum = numval;
       token = lex ();          /* okay, did number, now get literal */
     }
       usrtoknum = numval;
       token = lex ();          /* okay, did number, now get literal */
     }
-  else
-    usrtoknum = 0;
 
   /* process literal string token */
 
 
   /* process literal string token */
 
@@ -874,34 +911,55 @@ parse_thong_decl (void)
   nsyms--;
 }
 
   nsyms--;
 }
 
-/*------------------------------------------.
-| Parse what comes after %header_extension. |
-`------------------------------------------*/
-
 static void
 static void
-parse_header_extension_decl (void)
+parse_muscle_decl (void)
 {
 {
-  char buff[32];
+  int ch = ungetc (skip_white_space (), finput);
+  char* muscle_key;
+  char* muscle_value;
+
+  /* Read key. */
+  if (!isalpha (ch) && ch != '_')
+    {
+      complain (_("invalid %s declaration"), "%define");
+      skip_to_char ('%');
+      return;
+    }
+  copy_identifier (finput, &muscle_obstack);
+  obstack_1grow (&muscle_obstack, 0);
+  muscle_key = obstack_finish (&muscle_obstack);
 
 
-  if (header_extension)
-    complain (_("multiple %%header_extension declarations"));
-  fscanf (finput, "%s", buff);
-  header_extension = xstrdup (buff);
+  /* Read value. */
+  ch = skip_white_space ();
+  if (ch != '"')
+    {
+      ungetc (ch, finput);
+      if (ch != EOF)
+       {
+         complain (_("invalid %s declaration"), "%define");
+         skip_to_char ('%');
+         return;
+       }
+      else
+       fatal (_("Premature EOF after %s"), "\"");
+    }
+  copy_string2 (finput, &muscle_obstack, '"', 0);
+  obstack_1grow (&muscle_obstack, 0);
+  muscle_value = obstack_finish (&muscle_obstack);
+
+  /* Store the (key, value) pair in the environment. */
+  muscle_insert (muscle_key, muscle_value);
 }
 
 }
 
-/*------------------------------------------.
-| Parse what comes after %source_extension. |
-`------------------------------------------*/
 
 
-static void
-parse_source_extension_decl (void)
-{
-  char buff[32];
+/*----------------------------------.
+| Parse what comes after %skeleton. |
+`----------------------------------*/
 
 
-  if (src_extension)
-    complain (_("multiple %%source_extension declarations"));
-  fscanf (finput, "%s", buff);
-  src_extension = xstrdup (buff);
+void
+parse_skel_decl (void)
+{
+  /* Complete with parse_dquoted_param () on the CVS branch 1.29.  */
 }
 
 /*----------------------------------------------------------------.
 }
 
 /*----------------------------------------------------------------.
@@ -913,16 +971,13 @@ parse_source_extension_decl (void)
 static void
 read_declarations (void)
 {
 static void
 read_declarations (void)
 {
-  int c;
-  int tok;
-
   for (;;)
     {
   for (;;)
     {
-      c = skip_white_space ();
+      int c = skip_white_space ();
 
       if (c == '%')
        {
 
       if (c == '%')
        {
-         tok = parse_percent_token ();
+         token_t tok = parse_percent_token ();
 
          switch (tok)
            {
 
          switch (tok)
            {
@@ -973,17 +1028,24 @@ read_declarations (void)
              parse_assoc_decl (non_assoc);
              break;
 
              parse_assoc_decl (non_assoc);
              break;
 
-           case tok_hdrext:
-             parse_header_extension_decl ();
+           case tok_define:
+             parse_muscle_decl ();
              break;
 
              break;
 
-           case tok_srcext:
-             parse_source_extension_decl ();
+           case tok_skel:
+             parse_skel_decl ();
              break;
 
            case tok_noop:
              break;
 
              break;
 
            case tok_noop:
              break;
 
+           case tok_stropt:
+           case tok_intopt:
+           case tok_obsolete:
+           case tok_illegal:
+             abort ();
+             break;
+
            default:
              complain (_("unrecognized: %s"), token_buffer);
              skip_to_char ('%');
            default:
              complain (_("unrecognized: %s"), token_buffer);
              skip_to_char ('%');
@@ -1019,14 +1081,13 @@ copy_action (symbol_list *rule, int stack_offset)
   if (semantic_parser)
     stack_offset = 0;
 
   if (semantic_parser)
     stack_offset = 0;
 
-  sprintf (buf, "\ncase %d:\n", nrules);
-  obstack_grow (&action_obstack, buf, strlen (buf));
+  obstack_fgrow1 (&action_obstack, "\ncase %d:\n", nrules);
 
   if (!no_lines_flag)
     {
 
   if (!no_lines_flag)
     {
-      sprintf (buf, "#line %d %s\n",
-              lineno, quotearg_style (c_quoting_style, infile));
-      obstack_grow (&action_obstack, buf, strlen (buf));
+      obstack_fgrow2 (&action_obstack, muscle_find ("linef"),
+                     lineno, quotearg_style (c_quoting_style,
+                                             muscle_find ("filename")));
     }
   obstack_1grow (&action_obstack, '{');
 
     }
   obstack_1grow (&action_obstack, '{');
 
@@ -1112,8 +1173,9 @@ copy_guard (symbol_list *rule, int stack_offset)
 
   obstack_fgrow1 (&guard_obstack, "\ncase %d:\n", nrules);
   if (!no_lines_flag)
 
   obstack_fgrow1 (&guard_obstack, "\ncase %d:\n", nrules);
   if (!no_lines_flag)
-    obstack_fgrow2 (&guard_obstack, "#line %d %s\n",
-                   lineno, quotearg_style (c_quoting_style, infile));
+    obstack_fgrow2 (&guard_obstack, muscle_find ("linef"),
+                   lineno, quotearg_style (c_quoting_style,
+                                           muscle_find ("filename")));
   obstack_1grow (&guard_obstack, '{');
 
   count = 0;
   obstack_1grow (&guard_obstack, '{');
 
   count = 0;
@@ -1189,20 +1251,6 @@ copy_guard (symbol_list *rule, int stack_offset)
 }
 \f
 
 }
 \f
 
-static void
-record_rule_line (void)
-{
-  /* Record each rule's source line number in rline table.  */
-
-  if (nrules >= rline_allocated)
-    {
-      rline_allocated = nrules * 2;
-      rline = XREALLOC (rline, short, rline_allocated);
-    }
-  rline[nrules] = lineno;
-}
-
-
 /*-------------------------------------------------------------------.
 | Generate a dummy symbol, a nonterminal, whose name cannot conflict |
 | with the user's names.                                             |
 /*-------------------------------------------------------------------.
 | Generate a dummy symbol, a nonterminal, whose name cannot conflict |
 | with the user's names.                                             |
@@ -1345,8 +1393,6 @@ readgram (void)
          nrules++;
          nitems++;
 
          nrules++;
          nitems++;
 
-         record_rule_line ();
-
          p = XCALLOC (symbol_list, 1);
          p->sym = lhs;
 
          p = XCALLOC (symbol_list, 1);
          p->sym = lhs;
 
@@ -1424,7 +1470,6 @@ readgram (void)
                     just read can belong to it.  */
                  nrules++;
                  nitems++;
                     just read can belong to it.  */
                  nrules++;
                  nitems++;
-                 record_rule_line ();
                  p = XCALLOC (symbol_list, 1);
                  if (crule1)
                    crule1->next = p;
                  p = XCALLOC (symbol_list, 1);
                  if (crule1)
                    crule1->next = p;
@@ -1432,9 +1477,10 @@ readgram (void)
                    grammar = p;
                  p->sym = sdummy;
                  crule1 = XCALLOC (symbol_list, 1);
                    grammar = p;
                  p->sym = sdummy;
                  crule1 = XCALLOC (symbol_list, 1);
-                 p->next = crule1;
                  crule1->next = crule;
 
                  crule1->next = crule;
 
+                 p->next = crule1;
+
                  /* Insert the dummy generated by that rule into this
                     rule.  */
                  nitems++;
                  /* Insert the dummy generated by that rule into this
                     rule.  */
                  nitems++;
@@ -1564,22 +1610,6 @@ readgram (void)
   if (nrules == 0)
     fatal (_("no rules in the input grammar"));
 
   if (nrules == 0)
     fatal (_("no rules in the input grammar"));
 
-  /* JF put out same default YYSTYPE as YACC does */
-  if (typed == 0
-      && !value_components_used)
-    {
-      /* We used to use `unsigned long' as YYSTYPE on MSDOS,
-         but it seems better to be consistent.
-         Most programs should declare their own type anyway.  */
-      obstack_sgrow (&attrs_obstack,
-                          "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
-      if (defines_flag)
-       obstack_sgrow (&defines_obstack, "\
-# ifndef YYSTYPE\n\
-#  define YYSTYPE int\n\
-# endif\n");
-    }
-
   /* Report any undefined symbols and consider them nonterminals.  */
 
   for (bp = firstsymbol; bp; bp = bp->next)
   /* Report any undefined symbols and consider them nonterminals.  */
 
   for (bp = firstsymbol; bp; bp = bp->next)
@@ -1594,6 +1624,25 @@ readgram (void)
 
   ntokens = nsyms - nvars;
 }
 
   ntokens = nsyms - nvars;
 }
+
+/* At the end of the grammar file, some C source code must
+   be stored. It is going to be associated to the epilogue
+   directive.  */
+static void
+read_additionnal_code (void)
+{
+  char c;
+  struct obstack el_obstack;
+
+  obstack_init (&el_obstack);
+
+  while ((c = getc (finput)) != EOF)
+    obstack_1grow (&el_obstack, c);
+
+  obstack_1grow (&el_obstack, 0);
+  muscle_insert ("epilogue", obstack_finish (&el_obstack));
+}
+
 \f
 /*--------------------------------------------------------------.
 | For named tokens, but not literal ones, define the name.  The |
 \f
 /*--------------------------------------------------------------.
 | For named tokens, but not literal ones, define the name.  The |
@@ -1635,13 +1684,52 @@ output_token_defines (struct obstack *oout)
        continue;
 
       obstack_fgrow2 (oout, "# define\t%s\t%d\n",
        continue;
 
       obstack_fgrow2 (oout, "# define\t%s\t%d\n",
-                     symbol,
-                     (translations ? bp->user_token_number : bp->value));
+                     symbol, bp->user_token_number);
       if (semantic_parser)
       if (semantic_parser)
+       /* FIXME: This is certainly dead wrong, and should be just as
+          above. --akim.  */
        obstack_fgrow2 (oout, "# define\tT%s\t%d\n", symbol, bp->value);
     }
        obstack_fgrow2 (oout, "# define\tT%s\t%d\n", symbol, bp->value);
     }
+}
 
 
-  obstack_1grow (oout, '\n');
+
+/*------------------------------------------------------------------.
+| Set TOKEN_TRANSLATIONS.  Check that no two symbols share the same |
+| number.                                                           |
+`------------------------------------------------------------------*/
+
+static void
+token_translations_init (void)
+{
+  bucket *bp = NULL;
+  int i;
+
+  token_translations = XCALLOC (short, 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; i++)
+    token_translations[i] = 2;
+
+  for (bp = firstsymbol; bp; bp = bp->next)
+    {
+      /* Non-terminal? */
+      if (bp->value >= ntokens)
+       continue;
+      /* A token string alias? */
+      if (bp->user_token_number == SALIAS)
+       continue;
+
+      assert (bp->user_token_number != SUNDEF);
+
+      /* A token which translation has already been set? */
+      if (token_translations[bp->user_token_number] != 2)
+       complain (_("tokens %s and %s both assigned number %d"),
+                 tags[token_translations[bp->user_token_number]],
+                 bp->tag, bp->user_token_number);
+      token_translations[bp->user_token_number] = bp->value;
+    }
 }
 
 
 }
 
 
@@ -1654,22 +1742,21 @@ output_token_defines (struct obstack *oout)
 static void
 packsymbols (void)
 {
 static void
 packsymbols (void)
 {
-  bucket *bp;
+  bucket *bp = NULL;
   int tokno = 1;
   int tokno = 1;
-  int i;
   int last_user_token_number;
   static char DOLLAR[] = "$";
 
   int last_user_token_number;
   static char DOLLAR[] = "$";
 
-  /* int lossage = 0; JF set but not used */
-
   tags = XCALLOC (char *, nsyms + 1);
   tags = XCALLOC (char *, nsyms + 1);
-  tags[0] = DOLLAR;
   user_toknums = XCALLOC (short, nsyms + 1);
   user_toknums = XCALLOC (short, nsyms + 1);
-  user_toknums[0] = 0;
 
   sprec = XCALLOC (short, nsyms);
   sassoc = XCALLOC (short, nsyms);
 
 
   sprec = XCALLOC (short, nsyms);
   sassoc = XCALLOC (short, nsyms);
 
+  /* The EOF token. */
+  tags[0] = DOLLAR;
+  user_toknums[0] = 0;
+
   max_user_token_number = 256;
   last_user_token_number = 256;
 
   max_user_token_number = 256;
   last_user_token_number = 256;
 
@@ -1722,7 +1809,7 @@ packsymbols (void)
 
       if (bp->class == token_sym)
        {
 
       if (bp->class == token_sym)
        {
-         if (translations && !(bp->user_token_number))
+         if (bp->user_token_number == SUNDEF)
            bp->user_token_number = ++last_user_token_number;
          if (bp->user_token_number > max_user_token_number)
            max_user_token_number = bp->user_token_number;
            bp->user_token_number = ++last_user_token_number;
          if (bp->user_token_number > max_user_token_number)
            max_user_token_number = bp->user_token_number;
@@ -1732,46 +1819,41 @@ packsymbols (void)
       user_toknums[bp->value] = bp->user_token_number;
       sprec[bp->value] = bp->prec;
       sassoc[bp->value] = bp->assoc;
       user_toknums[bp->value] = bp->user_token_number;
       sprec[bp->value] = bp->prec;
       sassoc[bp->value] = bp->assoc;
-
     }
 
     }
 
-  if (translations)
-    {
-      int j;
-
-      token_translations = XCALLOC (short, 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 (j = 0; j <= max_user_token_number; j++)
-       token_translations[j] = 2;
-
-      for (bp = firstsymbol; bp; bp = bp->next)
-       {
-         if (bp->value >= ntokens)
-           continue;           /* non-terminal */
-         if (bp->user_token_number == SALIAS)
-           continue;
-         if (token_translations[bp->user_token_number] != 2)
-           complain (_("tokens %s and %s both assigned number %d"),
-                     tags[token_translations[bp->user_token_number]],
-                     bp->tag, bp->user_token_number);
-         token_translations[bp->user_token_number] = bp->value;
-       }
-    }
+  token_translations_init ();
 
   error_token_number = errtoken->value;
 
 
   error_token_number = errtoken->value;
 
-  if (!no_parser_flag)
-    output_token_defines (&table_obstack);
-
   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->value;
   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->value;
+}
+
+
+/*-----------------------------------.
+| Output definition of token names.  |
+`-----------------------------------*/
+
+static void
+symbols_output (void)
+{
+  {
+    struct obstack tokendefs;
+    obstack_init (&tokendefs);
+    output_token_defines (&tokendefs);
+    obstack_1grow (&tokendefs, 0);
+    muscle_insert ("tokendef", xstrdup (obstack_finish (&tokendefs)));
+    obstack_free (&tokendefs, NULL);
+  }
+
+#if 0
+  if (!no_parser_flag)
+    output_token_defines (&table_obstack);
+#endif
 
   if (defines_flag)
     {
 
   if (defines_flag)
     {
@@ -1788,19 +1870,23 @@ packsymbols (void)
        }
 
       if (semantic_parser)
        }
 
       if (semantic_parser)
-       for (i = ntokens; i < nsyms; i++)
-         {
-           /* don't make these for dummy nonterminals made by gensym.  */
-           if (*tags[i] != '@')
-              obstack_fgrow2 (&defines_obstack,
-                              "# define\tNT%s\t%d\n", tags[i], i);
-         }
+       {
+         int i;
+
+         for (i = ntokens; i < nsyms; i++)
+           {
+             /* don't make these for dummy nonterminals made by gensym.  */
+             if (*tags[i] != '@')
+               obstack_fgrow2 (&defines_obstack,
+                               "# define\tNT%s\t%d\n", tags[i], i);
+           }
 #if 0
 #if 0
-      /* `fdefines' is now a temporary file, so we need to copy its
-         contents in `done', so we can't close it here.  */
-      fclose (fdefines);
-      fdefines = NULL;
+         /* `fdefines' is now a temporary file, so we need to copy its
+            contents in `done', so we can't close it here.  */
+         fclose (fdefines);
+         fdefines = NULL;
 #endif
 #endif
+       }
     }
 }
 
     }
 }
 
@@ -1820,11 +1906,7 @@ packgram (void)
   bucket *ruleprec;
 
   ritem = XCALLOC (short, nitems + 1);
   bucket *ruleprec;
 
   ritem = XCALLOC (short, nitems + 1);
-  rlhs = XCALLOC (short, nrules) - 1;
-  rrhs = XCALLOC (short, nrules) - 1;
-  rprec = XCALLOC (short, nrules) - 1;
-  rprecsym = XCALLOC (short, nrules) - 1;
-  rassoc = XCALLOC (short, nrules) - 1;
+  rule_table = XCALLOC (rule_t, nrules) - 1;
 
   itemno = 0;
   ruleno = 1;
 
   itemno = 0;
   ruleno = 1;
@@ -1832,8 +1914,9 @@ packgram (void)
   p = grammar;
   while (p)
     {
   p = grammar;
   while (p)
     {
-      rlhs[ruleno] = p->sym->value;
-      rrhs[ruleno] = itemno;
+      rule_table[ruleno].lhs = p->sym->value;
+      rule_table[ruleno].rhs = itemno;
+      rule_table[ruleno].line = p->sym->line;
       ruleprec = p->ruleprec;
 
       p = p->next;
       ruleprec = p->ruleprec;
 
       p = p->next;
@@ -1844,8 +1927,8 @@ packgram (void)
             of the last token in it.  */
          if (p->sym->class == token_sym)
            {
             of the last token in it.  */
          if (p->sym->class == token_sym)
            {
-             rprec[ruleno] = p->sym->prec;
-             rassoc[ruleno] = p->sym->assoc;
+             rule_table[ruleno].prec = p->sym->prec;
+             rule_table[ruleno].assoc = p->sym->assoc;
            }
          if (p)
            p = p->next;
            }
          if (p)
            p = p->next;
@@ -1855,9 +1938,9 @@ packgram (void)
          the specified symbol's precedence replaces the default.  */
       if (ruleprec)
        {
          the specified symbol's precedence replaces the default.  */
       if (ruleprec)
        {
-         rprec[ruleno] = ruleprec->prec;
-         rassoc[ruleno] = ruleprec->assoc;
-         rprecsym[ruleno] = ruleprec->value;
+         rule_table[ruleno].prec = ruleprec->prec;
+         rule_table[ruleno].assoc = ruleprec->assoc;
+         rule_table[ruleno].precsym = ruleprec->value;
        }
 
       ritem[itemno++] = -ruleno;
        }
 
       ritem[itemno++] = -ruleno;
@@ -1884,21 +1967,10 @@ reader (void)
   start_flag = 0;
   startval = NULL;             /* start symbol not specified yet. */
 
   start_flag = 0;
   startval = NULL;             /* start symbol not specified yet. */
 
-#if 0
-  /* initially assume token number translation not needed.  */
-  translations = 0;
-#endif
-  /* Nowadays translations is always set to 1, since we give `error' a
-     user-token-number to satisfy the Posix demand for YYERRCODE==256.
-   */
-  translations = 1;
-
   nsyms = 1;
   nvars = 0;
   nrules = 0;
   nitems = 0;
   nsyms = 1;
   nvars = 0;
   nrules = 0;
   nitems = 0;
-  rline_allocated = 10;
-  rline = XCALLOC (short, rline_allocated);
 
   typed = 0;
   lastprec = 0;
 
   typed = 0;
   lastprec = 0;
@@ -1908,15 +1980,20 @@ reader (void)
 
   grammar = NULL;
 
 
   grammar = NULL;
 
-  init_lex ();
+  lex_init ();
   lineno = 1;
 
   lineno = 1;
 
+  /* Initialize the muscle obstack.  */
+  obstack_init (&muscle_obstack);
+
   /* Initialize the symbol table.  */
   tabinit ();
   /* Initialize the symbol table.  */
   tabinit ();
+
   /* Construct the error token */
   errtoken = getsym ("error");
   errtoken->class = token_sym;
   errtoken->user_token_number = 256;   /* Value specified by POSIX.  */
   /* Construct the error token */
   errtoken = getsym ("error");
   errtoken->class = token_sym;
   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.");
   /* Construct a token that represents all undefined literal tokens.
      It is always token number 2.  */
   undeftoken = getsym ("$undefined.");
@@ -1926,63 +2003,23 @@ reader (void)
   /* Read the declaration section.  Copy %{ ... %} groups to
      TABLE_OBSTACK and FDEFINES file.  Also notice any %token, %left,
      etc. found there.  */
   /* Read the declaration section.  Copy %{ ... %} groups to
      TABLE_OBSTACK and FDEFINES file.  Also notice any %token, %left,
      etc. found there.  */
-  obstack_1grow (&table_obstack, '\n');
-  obstack_fgrow3 (&table_obstack, "\
-/* %s, made from %s\n\
-   by GNU bison %s.  */\n\
-\n",
-                 no_parser_flag ? "Bison-generated parse tables" : "A Bison parser",
-                 infile, VERSION);
-
-  obstack_sgrow (&table_obstack,
-                      "#define YYBISON 1  /* Identify Bison output.  */\n\n");
   read_declarations ();
   read_declarations ();
-  /* Start writing the guard and action files, if they are needed.  */
-  output_headers ();
   /* Read in the grammar, build grammar in list form.  Write out
      guards and actions.  */
   readgram ();
   /* Read in the grammar, build grammar in list form.  Write out
      guards and actions.  */
   readgram ();
+  /* Some C code is given at the end of the grammar file. */
+  read_additionnal_code ();
+
   /* Now we know whether we need the line-number stack.  If we do,
   /* Now we know whether we need the line-number stack.  If we do,
-     write its type into the .tab.h file.  */
-  if (defines_flag)
-    reader_output_yylsp (&defines_obstack);
-  /* Write closing delimiters for actions and guards.  */
-  output_trailers ();
-  if (locations_flag)
-    obstack_sgrow (&table_obstack, "#define YYLSP_NEEDED 1\n\n");
+     write its type into the .tab.h file.
+     This is no longer need with header skeleton.  */
+
   /* Assign the symbols their symbol numbers.  Write #defines for the
      token symbols into FDEFINES if requested.  */
   packsymbols ();
   /* Assign the symbols their symbol numbers.  Write #defines for the
      token symbols into FDEFINES if requested.  */
   packsymbols ();
+  symbols_output ();
   /* Convert the grammar into the format described in gram.h.  */
   packgram ();
   /* Convert the grammar into the format described in gram.h.  */
   packgram ();
-  /* Free the symbol table data structure since symbols are now all
-     referred to by symbol number.  */
-  free_symtab ();
-}
-
-
-/*------------------------------------------------------------------.
-| Define YYLTYPE.  Cannot be in the skeleton since we might have to |
-| output it in the headers if --defines is used.                    |
-`------------------------------------------------------------------*/
-
-void
-reader_output_yylsp (struct obstack *oout)
-{
-  if (locations_flag)
-    obstack_sgrow (oout, "\
-\n\
-#ifndef YYLTYPE\n\
-typedef struct yyltype\n\
-{\n\
-  int first_line;\n\
-  int first_column;\n\
-\n\
-  int last_line;\n\
-  int last_column;\n\
-} yyltype;\n\
-\n\
-# define YYLTYPE yyltype\n\
-#endif\n\
-\n");
+  /* Output the headers. */
+  symbols_output ();
 }
 }