]> git.saurik.com Git - bison.git/blobdiff - src/output.c
* src/output.c (output_skeleton): tempdir is const.
[bison.git] / src / output.c
index 37ce24cf89688fd58bd2d6012ac3faeed61476a6..140f220b59ba7932015bd1e5dacaf8e41858a392 100644 (file)
@@ -1,5 +1,5 @@
 /* Output the generated parsing program for bison,
 /* Output the generated parsing program for bison,
-   Copyright 1984, 1986, 1989, 1992, 2000, 2001
+   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
    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.
@@ -89,7 +89,9 @@
    negative short int.  Used to flag ??  */
 
 #include "system.h"
    negative short int.  Used to flag ??  */
 
 #include "system.h"
+#include "bitsetv.h"
 #include "quotearg.h"
 #include "quotearg.h"
+#include "error.h"
 #include "getargs.h"
 #include "files.h"
 #include "gram.h"
 #include "getargs.h"
 #include "files.h"
 #include "gram.h"
 #include "conflicts.h"
 #include "muscle_tab.h"
 
 #include "conflicts.h"
 #include "muscle_tab.h"
 
+/* From lib/readpipe.h.  */
+FILE *readpipe PARAMS ((const char *, ...));
+
+/* From src/scan-skel.l. */
+int skel_lex PARAMS ((void));
+extern FILE *skel_in;
 
 static int nvectors;
 static int nentries;
 
 static int nvectors;
 static int nentries;
@@ -125,7 +133,7 @@ static struct obstack format_obstack;
 int error_verbose = 0;
 
 /* Returns the number of lines of S.  */
 int error_verbose = 0;
 
 /* Returns the number of lines of S.  */
-static size_t
+size_t
 get_lines_number (const char *s)
 {
   size_t lines = 0;
 get_lines_number (const char *s)
 {
   size_t lines = 0;
@@ -185,7 +193,7 @@ output_gram (void)
     int i;
     short *values = XCALLOC (short, nrules + 1);
     for (i = 0; i < nrules + 1; ++i)
     int i;
     short *values = XCALLOC (short, nrules + 1);
     for (i = 0; i < nrules + 1; ++i)
-      values[i] = rule_table[i].rhs;
+      values[i] = rules[i].rhs;
     output_table_data (&format_obstack, values,
                       0, 1, nrules + 1);
     XFREE (values);
     output_table_data (&format_obstack, values,
                       0, 1, nrules + 1);
     XFREE (values);
@@ -219,10 +227,10 @@ output_gram (void)
 static void
 output_stos (void)
 {
 static void
 output_stos (void)
 {
-  int i;
+  size_t i;
   short *values = (short *) alloca (sizeof (short) * nstates);
   for (i = 0; i < nstates; ++i)
   short *values = (short *) alloca (sizeof (short) * nstates);
   for (i = 0; i < nstates; ++i)
-    values[i] = state_table[i]->accessing_symbol;
+    values[i] = states[i]->accessing_symbol;
   output_table_data (&format_obstack, values,
                     0, 1, nstates);
   muscle_insert ("stos", obstack_finish (&format_obstack));
   output_table_data (&format_obstack, values,
                     0, 1, nstates);
   muscle_insert ("stos", obstack_finish (&format_obstack));
@@ -239,7 +247,7 @@ output_rule_data (void)
   {
     short *values = XCALLOC (short, nrules + 1);
     for (i = 0; i < nrules + 1; ++i)
   {
     short *values = XCALLOC (short, nrules + 1);
     for (i = 0; i < nrules + 1; ++i)
-      values[i] = rule_table[i].line;
+      values[i] = rules[i].line;
     output_table_data (&format_obstack, values,
                       0, 1, nrules + 1);
     muscle_insert ("rline", obstack_finish (&format_obstack));
     output_table_data (&format_obstack, values,
                       0, 1, nrules + 1);
     muscle_insert ("rline", obstack_finish (&format_obstack));
@@ -268,8 +276,9 @@ output_rule_data (void)
       obstack_sgrow (&format_obstack, ", ");
       j += strsize;
     }
       obstack_sgrow (&format_obstack, ", ");
       j += strsize;
     }
-  /* add a NULL entry to list of tokens */
-  obstack_sgrow (&format_obstack, "NULL");
+  /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
+     defined).  */
+  obstack_sgrow (&format_obstack, "0");
 
   /* Finish table and store. */
   obstack_1grow (&format_obstack, 0);
 
   /* Finish table and store. */
   obstack_1grow (&format_obstack, 0);
@@ -291,7 +300,7 @@ output_rule_data (void)
   {
     short *values = XCALLOC (short, nrules + 1);
     for (i = 0; i < nrules + 1; ++i)
   {
     short *values = XCALLOC (short, nrules + 1);
     for (i = 0; i < nrules + 1; ++i)
-      values[i] = rule_table[i].lhs;
+      values[i] = rules[i].lhs;
     output_table_data (&format_obstack, values,
                       0, 1, nrules + 1);
     muscle_insert ("r1", obstack_finish (&format_obstack));
     output_table_data (&format_obstack, values,
                       0, 1, nrules + 1);
     muscle_insert ("r1", obstack_finish (&format_obstack));
@@ -301,8 +310,8 @@ output_rule_data (void)
   /* Output YYR2. */
   short_tab = XMALLOC (short, nrules + 1);
   for (i = 1; i < nrules; i++)
   /* Output YYR2. */
   short_tab = XMALLOC (short, nrules + 1);
   for (i = 1; i < nrules; i++)
-    short_tab[i] = rule_table[i + 1].rhs - rule_table[i].rhs - 1;
-  short_tab[nrules] =  nritems - rule_table[nrules].rhs - 1;
+    short_tab[i] = rules[i + 1].rhs - rules[i].rhs - 1;
+  short_tab[nrules] =  nritems - rules[nrules].rhs - 1;
   output_table_data (&format_obstack, short_tab,
                     0, 1, nrules + 1);
   muscle_insert ("r2", obstack_finish (&format_obstack));
   output_table_data (&format_obstack, short_tab,
                     0, 1, nrules + 1);
   muscle_insert ("r2", obstack_finish (&format_obstack));
@@ -348,7 +357,7 @@ action_row (state_t *state)
        for (j = 0; j < ntokens; j++)
          /* and record this rule as the rule to use if that
             token follows.  */
        for (j = 0; j < ntokens; j++)
          /* and record this rule as the rule to use if that
             token follows.  */
-         if (BITISSET (LA (state->lookaheadsp + i), j))
+         if (bitset_test (LA[state->lookaheadsp + i], j))
            actrow[j] = -LAruleno[state->lookaheadsp + i];
     }
 
            actrow[j] = -LAruleno[state->lookaheadsp + i];
     }
 
@@ -362,7 +371,7 @@ action_row (state_t *state)
       if (!shift_state)
        continue;
 
       if (!shift_state)
        continue;
 
-      symbol = state_table[shift_state]->accessing_symbol;
+      symbol = states[shift_state]->accessing_symbol;
 
       if (ISVAR (symbol))
        break;
 
       if (ISVAR (symbol))
        break;
@@ -480,13 +489,13 @@ save_row (int state)
 static void
 token_actions (void)
 {
 static void
 token_actions (void)
 {
-  int i;
+  size_t i;
   short *yydefact = XCALLOC (short, nstates);
 
   actrow = XCALLOC (short, ntokens);
   for (i = 0; i < nstates; ++i)
     {
   short *yydefact = XCALLOC (short, nstates);
 
   actrow = XCALLOC (short, ntokens);
   for (i = 0; i < nstates; ++i)
     {
-      yydefact[i] = action_row (state_table[i]);
+      yydefact[i] = action_row (states[i]);
       save_row (i);
     }
 
       save_row (i);
     }
 
@@ -503,34 +512,26 @@ token_actions (void)
 | Output the actions to OOUT.  |
 `-----------------------------*/
 
 | Output the actions to OOUT.  |
 `-----------------------------*/
 
-static void
-actions_output (FILE *out, size_t *line)
+void
+actions_output (FILE *out)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
-    if (rule_table[rule].action)
+    if (rules[rule].action)
       {
        fprintf (out, "  case %d:\n", rule);
 
        if (!no_lines_flag)
          fprintf (out, muscle_find ("linef"),
       {
        fprintf (out, "  case %d:\n", rule);
 
        if (!no_lines_flag)
          fprintf (out, muscle_find ("linef"),
-                  rule_table[rule].action_line,
+                  rules[rule].action_line,
                   quotearg_style (c_quoting_style,
                                   muscle_find ("filename")));
        /* As a Bison extension, add the ending semicolon.  Since some
           Yacc don't do that, help people using bison as a Yacc
           finding their missing semicolons.  */
        fprintf (out, "{ %s%s }\n    break;\n\n",
                   quotearg_style (c_quoting_style,
                                   muscle_find ("filename")));
        /* As a Bison extension, add the ending semicolon.  Since some
           Yacc don't do that, help people using bison as a Yacc
           finding their missing semicolons.  */
        fprintf (out, "{ %s%s }\n    break;\n\n",
-                rule_table[rule].action,
+                rules[rule].action,
                 yacc_flag ? ";" : "");
                 yacc_flag ? ";" : "");
-
-       /* We always output 4 '\n' per action.  */
-       *line += 4;
-       /* Plus one if !no_lines_flag.  */
-       if (!no_lines_flag)
-         ++*line;
-       /* Get the number of lines written by the user.  */
-       *line += get_lines_number (rule_table[rule].action);
       }
 }
 
       }
 }
 
@@ -539,34 +540,70 @@ actions_output (FILE *out, size_t *line)
 | Output the guards to OOUT.  |
 `----------------------------*/
 
 | Output the guards to OOUT.  |
 `----------------------------*/
 
-static void
-guards_output (FILE *out, size_t *line)
+void
+guards_output (FILE *out)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
 {
   int rule;
   for (rule = 1; rule < nrules + 1; ++rule)
-    if (rule_table[rule].action)
+    if (rules[rule].guard)
       {
        fprintf (out, "  case %d:\n", rule);
 
        if (!no_lines_flag)
          fprintf (out, muscle_find ("linef"),
       {
        fprintf (out, "  case %d:\n", rule);
 
        if (!no_lines_flag)
          fprintf (out, muscle_find ("linef"),
-                  rule_table[rule].guard_line,
+                  rules[rule].guard_line,
                   quotearg_style (c_quoting_style,
                                   muscle_find ("filename")));
        fprintf (out, "{ %s; }\n    break;\n\n",
                   quotearg_style (c_quoting_style,
                                   muscle_find ("filename")));
        fprintf (out, "{ %s; }\n    break;\n\n",
-                rule_table[rule].guard);
-
-       /* We always output 4 '\n' per action.  */
-       *line += 4;
-       /* Plus one if !no_lines_flag.  */
-       if (!no_lines_flag)
-         ++*line;
-       /* Get the number of lines written by the user.  */
-       *line += get_lines_number (rule_table[rule].guard);
+                rules[rule].guard);
       }
 }
 
 
       }
 }
 
 
+/*---------------------------------------.
+| Output the tokens definition to OOUT.  |
+`---------------------------------------*/
+
+void
+token_definitions_output (FILE *out)
+{
+  int i;
+  for (i = 0; i < ntokens; ++i)
+    {
+      bucket *symbol = symbols[i];
+      int number = symbol->user_token_number;
+
+      if (number == SALIAS)
+       continue;
+      /* Skip error token.  */
+      if (symbol->value == error_token_number)
+       continue;
+      if (symbol->tag[0] == '\'')
+       continue;               /* skip literal character */
+      if (symbol->tag[0] == '\"')
+       {
+         /* use literal string only if given a symbol with an alias */
+         if (symbol->alias)
+           symbol = symbol->alias;
+         else
+           continue;
+       }
+
+      /* Don't #define nonliteral tokens whose names contain periods
+        or '$' (as does the default value of the EOF token).  */
+      if (strchr (symbol->tag, '.') || strchr (symbol->tag, '$'))
+       continue;
+
+      fprintf (out, "# define %s\t%d\n",
+              symbol->tag, number);
+      if (semantic_parser)
+       /* FIXME: This is probably wrong, and should be just as
+          above. --akim.  */
+       fprintf (out, "# define T%s\t%d\n", symbol->tag, symbol->value);
+    }
+}
+
+
 static void
 save_column (int symbol, int default_state)
 {
 static void
 save_column (int symbol, int default_state)
 {
@@ -605,9 +642,9 @@ save_column (int symbol, int default_state)
 static int
 default_goto (int symbol)
 {
 static int
 default_goto (int symbol)
 {
-  int i;
-  int m = goto_map[symbol];
-  int n = goto_map[symbol + 1];
+  size_t i;
+  size_t m = goto_map[symbol];
+  size_t n = goto_map[symbol + 1];
   int default_state = -1;
   int max = 0;
 
   int default_state = -1;
   int max = 0;
 
@@ -705,7 +742,7 @@ matching_state (int vector)
   int w;
   int prev;
 
   int w;
   int prev;
 
-  if (i >= nstates)
+  if (i >= (int) nstates)
     return -1;
 
   t = tally[i];
     return -1;
 
   t = tally[i];
@@ -877,7 +914,7 @@ output_check (void)
 static void
 output_actions (void)
 {
 static void
 output_actions (void)
 {
-  int i;
+  size_t i;
   nvectors = nstates + nvars;
 
   froms = XCALLOC (short *, nvectors);
   nvectors = nstates + nvars;
 
   froms = XCALLOC (short *, nvectors);
@@ -886,7 +923,7 @@ output_actions (void)
   width = XCALLOC (short, nvectors);
 
   token_actions ();
   width = XCALLOC (short, nvectors);
 
   token_actions ();
-  XFREE (LA);
+  bitsetv_free (LA);
   XFREE (LAruleno);
 
   goto_actions ();
   XFREE (LAruleno);
 
   goto_actions ();
@@ -904,130 +941,89 @@ output_actions (void)
 
   for (i = 0; i < nstates; ++i)
     {
 
   for (i = 0; i < nstates; ++i)
     {
-      free (state_table[i]->shifts);
-      XFREE (state_table[i]->reductions);
-      free (state_table[i]->errs);
-      free (state_table[i]);
+      free (states[i]->shifts);
+      XFREE (states[i]->reductions);
+      free (states[i]->errs);
+      free (states[i]);
     }
     }
-  XFREE (state_table);
+  XFREE (states);
 }
 
 \f
 }
 
 \f
-/*------------------------------------------------------------.
-| Copy the parser code from SKEL_FILENAME into OOUT obstack.  |
-| and do the muscle substitution.                             |
-`------------------------------------------------------------*/
-
-static void
-output_parser (const char *skel_filename, FILE *out)
-{
-  int c;
-  FILE *fskel;
-  size_t output_line;
-  size_t skeleton_line;
-
-  fskel = xfopen (skel_filename, "r");
-
-  /* New output code.  */
-  output_line = 1;
-  skeleton_line = 1;
-  c = getc (fskel);
-  while (c != EOF)
-    {
-      if (c != '%')
-       {
-         if (c == '\n')
-           {
-             ++output_line;
-             ++skeleton_line;
-           }
-         putc (c, out);
-         c = getc (fskel);
-       }
-      else if ((c = getc (fskel)) == '%')
-       {
-         /* Read the muscle.  */
-         const char *muscle_key = 0;
-         const char *muscle_value = 0;
-
-         while (isalnum (c = getc (fskel)) || c == '-')
-           obstack_1grow (&muscle_obstack, c);
-         obstack_1grow (&muscle_obstack, 0);
-
-         /* Output the right value, or see if it's something special.  */
-         muscle_key = obstack_finish (&muscle_obstack);
-         muscle_value = muscle_find (muscle_key);
-         if (!strcmp (muscle_key, "actions"))
-           actions_output (out, &output_line);
-         else if (!strcmp (muscle_key, "guards"))
-           guards_output (out, &output_line);
-         else if (!strcmp (muscle_key, "line"))
-           fprintf (out, "%d", output_line);
-         else if (!strcmp (muscle_key, "skeleton-line"))
-           fprintf (out, "%d", skeleton_line);
-         else if (muscle_value)
-           {
-             fputs (muscle_value, out);
-             output_line += get_lines_number (muscle_value);
-           }
-         else
-           {
-             fputs ("%%", out);
-             fputs (muscle_key, out);
-           }
-       }
-      else
-       putc ('%', out);
-    }
-
-  /* End.  */
-  xfclose (fskel);
-}
-
-/*----------------------------------------.
-| Prepare the master parser to be output  |
-`----------------------------------------*/
+/*---------------------------.
+| Call the skeleton parser.  |
+`---------------------------*/
 
 static void
 
 static void
-output_master_parser (void)
+output_skeleton (void)
 {
 {
-  FILE *parser = xfopen (parser_file_name, "w");
-  if (!skeleton)
-    {
-      if (semantic_parser)
-       skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
-      else
-       skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
-    }
-  muscle_insert ("skeleton", skeleton);
-  muscle_insert ("parser-file-name", parser_file_name);
-
-  output_parser (skeleton, parser);
-  xfclose (parser);
-}
-
-
-/* FIXME. */
-
-#define MUSCLE_INSERT_INT(Key, Value)                          \
-{                                                              \
-  obstack_fgrow1 (&muscle_obstack, "%d", Value);               \
-  obstack_1grow (&muscle_obstack, 0);                          \
-  muscle_insert (Key, obstack_finish (&muscle_obstack));       \
-}
-
-#define MUSCLE_INSERT_STRING(Key, Value)                       \
-{                                                              \
-  obstack_sgrow (&muscle_obstack, Value);                      \
-  obstack_1grow (&muscle_obstack, 0);                          \
-  muscle_insert (Key, obstack_finish (&muscle_obstack));       \
-}
+  /* Store the definition of all the muscles. */
+  const char *tempdir = getenv ("TMPDIR");
+  char *tempfile = NULL;
+  FILE *out = NULL;
+  int fd;
+
+  if (tempdir == NULL)
+    tempdir = DEFAULT_TMPDIR;
+  tempfile = xmalloc (strlen (tempdir) + 11);
+  sprintf (tempfile, "%s/bsnXXXXXX", tempdir);
+  fd = mkstemp (tempfile);
+  if (fd == -1)
+    error (EXIT_FAILURE, errno, "%s", tempfile);
+
+  out = fdopen (fd, "w");
+  if (out == NULL)
+    error (EXIT_FAILURE, errno, "%s", tempfile);
+
+  /* There are no comments, especially not `#': we do want M4 expansion
+     after `#': think of CPP macros!  */
+  fputs ("m4_changecom()\n", out);
+  fputs ("m4_init()\n", out);
+
+  fputs ("m4_define([b4_actions], \n[[", out);
+  actions_output (out);
+  fputs ("]])\n\n", out);
+
+  fputs ("m4_define([b4_guards], \n[[", out);
+  guards_output (out);
+  fputs ("]])\n\n", out);
+
+  fputs ("m4_define([b4_tokendef], \n[[", out);
+  token_definitions_output (out);
+  fputs ("]])\n\n", out);
+
+  muscles_m4_output (out);
+
+  fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
+  fputs ("m4_divert_push(0)dnl\n", out);
+  xfclose (out);
 
 
-#define MUSCLE_INSERT_PREFIX(Key, Value)                               \
-{                                                                      \
-  obstack_fgrow2 (&muscle_obstack, "%s%s", spec_name_prefix, Value);   \
-  obstack_1grow (&muscle_obstack, 0);                                  \
-  muscle_insert (Key, obstack_finish (&muscle_obstack));               \
+  /* Invoke m4 on the definition of the muscles, and the skeleton. */
+  {
+    const char *bison_pkgdatadir = getenv ("BISON_PKGDATADIR");
+    const char *m4 = getenv ("M4");
+    if (!m4)
+      m4 = M4;
+    if (!bison_pkgdatadir)
+      bison_pkgdatadir = PKGDATADIR;
+    if (trace_flag)
+      fprintf (stderr,
+              "running: %s -I %s m4sugar/m4sugar.m4 %s %s\n",
+              m4, bison_pkgdatadir, tempfile, skeleton);
+    skel_in = readpipe (m4,
+                       "-I", bison_pkgdatadir,
+                       "m4sugar/m4sugar.m4",
+                       tempfile,
+                       skeleton,
+                       NULL);
+    if (!skel_in)
+      error (EXIT_FAILURE, errno, "cannot run m4");
+    skel_lex ();
+
+    /* If `debugging', keep this file alive. */
+    if (!trace_flag)
+      unlink (tempfile);
+  }
 }
 
 static void
 }
 
 static void
@@ -1040,56 +1036,39 @@ prepare (void)
   MUSCLE_INSERT_INT ("debug", debug_flag);
   MUSCLE_INSERT_INT ("final", final_state);
   MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
   MUSCLE_INSERT_INT ("debug", debug_flag);
   MUSCLE_INSERT_INT ("final", final_state);
   MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
-  MUSCLE_INSERT_INT ("error-verbose", error_verbose);
-  MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
+  MUSCLE_INSERT_INT ("error_verbose", error_verbose);
+  MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
+
+  /* FIXME: This is wrong: the muscles should decide whether they hold
+     a copy or not, but the situation is too obscure currently.  */
+  MUSCLE_INSERT_STRING ("output_infix", output_infix ? output_infix : "");
+  MUSCLE_INSERT_STRING ("output_prefix", short_base_name);
+  MUSCLE_INSERT_STRING ("output_parser_name", parser_file_name);
+  MUSCLE_INSERT_STRING ("output_header_name", spec_defines_file);
 
   MUSCLE_INSERT_INT ("nnts", nvars);
   MUSCLE_INSERT_INT ("nrules", nrules);
   MUSCLE_INSERT_INT ("nstates", nstates);
   MUSCLE_INSERT_INT ("ntokens", ntokens);
 
 
   MUSCLE_INSERT_INT ("nnts", nvars);
   MUSCLE_INSERT_INT ("nrules", nrules);
   MUSCLE_INSERT_INT ("nstates", nstates);
   MUSCLE_INSERT_INT ("ntokens", ntokens);
 
-  MUSCLE_INSERT_INT ("locations-flag", locations_flag);
-}
-
+  MUSCLE_INSERT_INT ("locations_flag", locations_flag);
+  MUSCLE_INSERT_INT ("defines_flag", defines_flag);
 
 
-/*-------------------------.
-| Output the header file.  |
-`-------------------------*/
+  /* Copy definitions in directive.  */
+  obstack_1grow (&attrs_obstack, 0);
+  muscle_insert ("prologue", obstack_finish (&attrs_obstack));
 
 
-static void
-header_output (void)
-{
-  FILE *out = xfopen (spec_defines_file, "w");
-  char *macro_name = compute_header_macro ();
-
-  fprintf (out, "#ifndef %s\n", macro_name);
-  fprintf (out, "# define %s\n\n", macro_name);
-
-  fputs (muscle_find ("tokendef"), out);
-  fprintf (out, "\
-#ifndef YYSTYPE\n\
-typedef %s
-yystype;\n\
-# define YYSTYPE yystype\n\
-#endif\n",
-                   muscle_find ("stype"));
-
-  if (!pure_parser)
-    fprintf (out, "\nextern YYSTYPE %slval;\n",
-            spec_name_prefix);
-  if (semantic_parser)
+  /* Find the right skeleton file.  */
+  if (!skeleton)
     {
     {
-      int i;
-
-      for (i = ntokens; i < nsyms; i++)
-       /* don't make these for dummy nonterminals made by gensym.  */
-       if (*symbols[i]->tag != '@')
-         fprintf (out, "# define NT%s\t%d\n", symbols[i]->tag, i);
+      if (semantic_parser)
+       skeleton = "bison.hairy";
+      else
+       skeleton = "bison.simple";
     }
 
     }
 
-  fprintf (out, "\n#endif /* not %s */\n", macro_name);
-  free (macro_name);
-  xfclose (out);
+  /* Parse the skeleton file and output the needed parsers.  */
+  muscle_insert ("skeleton", skeleton);
 }
 
 
 }
 
 
@@ -1105,24 +1084,16 @@ output (void)
   output_token_translations ();
   output_gram ();
 
   output_token_translations ();
   output_gram ();
 
-  XFREE (ritem);
   if (semantic_parser)
     output_stos ();
   output_rule_data ();
   output_actions ();
 
   prepare ();
   if (semantic_parser)
     output_stos ();
   output_rule_data ();
   output_actions ();
 
   prepare ();
-  /* Copy definitions in directive.  */
-  obstack_1grow (&attrs_obstack, 0);
-  muscle_insert ("prologue", obstack_finish (&attrs_obstack));
 
 
-  /* Output the parser. */
-  output_master_parser ();
-  /* Output the header if needed. */
-  if (defines_flag)
-    header_output ();
+  /* Process the selected skeleton file.  */
+  output_skeleton ();
 
 
-  free (rule_table + 1);
   obstack_free (&muscle_obstack, NULL);
   obstack_free (&format_obstack, NULL);
   obstack_free (&action_obstack, NULL);
   obstack_free (&muscle_obstack, NULL);
   obstack_free (&format_obstack, NULL);
   obstack_free (&action_obstack, NULL);