]> git.saurik.com Git - bison.git/blobdiff - src/output.c
* src/closure.c (set_firsts): De-obfuscate.
[bison.git] / src / output.c
index adef04336fdf8812b71d4772c74b9e5c474f8d93..c8bd5fc635be60e475643ceeaa8dbb033fa55f4f 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 Free Software Foundation, Inc.
+   Copyright 1984, 1986, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
@@ -94,7 +94,6 @@
 #include "obstack.h"
 #include "quotearg.h"
 #include "getargs.h"
 #include "obstack.h"
 #include "quotearg.h"
 #include "getargs.h"
-#include "xalloc.h"
 #include "files.h"
 #include "gram.h"
 #include "LR0.h"
 #include "files.h"
 #include "gram.h"
 #include "LR0.h"
 #include "lalr.h"
 #include "reader.h"
 #include "conflicts.h"
 #include "lalr.h"
 #include "reader.h"
 #include "conflicts.h"
+#include "muscle_tab.h"
 
 extern void berror PARAMS((const char *));
 
 
 extern void berror PARAMS((const char *));
 
-
-
 static int nvectors;
 static int nentries;
 static int nvectors;
 static int nentries;
-static short **froms;
-static short **tos;
-static short *tally;
-static short *width;
-static short *actrow;
-static short *state_count;
-static short *order;
-static short *base;
-static short *pos;
-static short *table;
-static short *check;
+static short **froms = NULL;
+static short **tos = NULL;
+static short *tally = NULL;
+static short *width = NULL;
+static short *actrow = NULL;
+static short *state_count = NULL;
+static short *order = NULL;
+static short *base = NULL;
+static short *pos = NULL;
+static short *table = NULL;
+static short *check = NULL;
 static int lowzero;
 static int high;
 
 static int lowzero;
 static int high;
 
+struct obstack muscle_obstack;
+struct obstack output_obstack;
+
+int error_verbose = 0;
 
 
+/* FIXME. */
 
 static inline void
 
 static inline void
-output_short_or_char_table (struct obstack *oout,
-                           const char *comment,
-                           const char *type,
-                           const char *table_name,
-                           short *short_table,
-                           short first_value,
-                           short begin, short end)
+output_table_data (struct obstack *oout,
+                  short *table_data,
+                  short first,
+                  short begin,
+                  short end)
 {
 {
-  int i, j;
-
-  if (comment)
-    obstack_fgrow1 (oout, "/* %s. */\n", comment);
-
-  obstack_fgrow3 (oout, "static const %s %s[] =\n{\n  %6d",
-                 type, table_name, first_value);
+  int i;
+  int j = 1;
 
 
-  j = 1;
-  for (i = begin; i < end; i++)
+  obstack_fgrow1 (oout, "%6d", first);
+  for (i = begin; i < end; ++i)
     {
       obstack_1grow (oout, ',');
     {
       obstack_1grow (oout, ',');
-
       if (j >= 10)
        {
       if (j >= 10)
        {
-         obstack_grow_literal_string (oout, "\n  ");
+         obstack_sgrow (oout, "\n  ");
          j = 1;
        }
       else
          j = 1;
        }
       else
-       {
-         j++;
-       }
-
-      obstack_fgrow1 (oout, "%6d", short_table[i]);
-    }
-
-  obstack_grow_literal_string (oout, "\n};\n");
-}
-
-
-static inline void
-output_short_table (struct obstack *oout,
-                   const char *comment,
-                   const char *table_name,
-                   short *short_table,
-                   short first_value,
-                   short begin, short end)
-{
-  output_short_or_char_table (oout, comment, "short", table_name, short_table,
-                             first_value, begin, end);
-}
-
-
-/*--------------------------------------------------------------.
-| output_headers -- Output constant strings to the beginning of |
-| certain files.                                                |
-`--------------------------------------------------------------*/
-
-/* Don't put the `%s' insides quotes, since it quotearg puts them. */
-
-#define        GUARDSTR        \
-"\n\
-#include %s\n\
-extern int yyerror;\n\
-extern int yycost;\n\
-extern char * yymsg;\n\
-extern YYSTYPE yyval;\n\
-\n\
-yyguard(n, yyvsp, yylsp)\n\
-register int n;\n\
-register YYSTYPE *yyvsp;\n\
-register YYLTYPE *yylsp;\n\
-{\n\
-  yyerror = 0;\n\
-  yycost = 0;\n\
-  yymsg = 0;\n\
-  switch (n)\n\
-    {"
-
-#define        ACTSTR          \
-"\n\
-#include %s\n\
-extern YYSTYPE yyval;\n\
-extern int yychar;\n\
-\n\
-yyaction(n, yyvsp, yylsp)\n\
-register int n;\n\
-register YYSTYPE *yyvsp;\n\
-register YYLTYPE *yylsp;\n\
-{\n\
-  switch (n)\n\
-    {"
-
-#define        ACTSTR_SIMPLE   "\n  switch (yyn) {\n"
-
-void
-output_headers (void)
-{
-  char *attrsfile_quoted = quotearg_style (c_quoting_style, attrsfile);
-
-  if (semantic_parser)
-    fprintf (fguard, GUARDSTR, attrsfile_quoted);
-
-  if (no_parser_flag)
-    return;
-
-  if (semantic_parser)
-    obstack_fgrow1 (&action_obstack, ACTSTR, attrsfile_quoted);
-  else
-    obstack_grow_literal_string (&action_obstack, ACTSTR_SIMPLE);
-
-/*  if (semantic_parser)       JF moved this below
-    fprintf(ftable, "#include \"%s\"\n", attrsfile);
-  fprintf(ftable, "#include <stdio.h>\n\n");
-*/
-
-  /* Rename certain symbols if -p was specified.  */
-  if (spec_name_prefix)
-    {
-      obstack_fgrow1 (&table_obstack,
-                     "#define yyparse %sparse\n", spec_name_prefix);
-      obstack_fgrow1 (&table_obstack,
-                     "#define yylex %slex\n", spec_name_prefix);
-      obstack_fgrow1 (&table_obstack,
-                     "#define yyerror %serror\n", spec_name_prefix);
-      obstack_fgrow1 (&table_obstack,
-                     "#define yylval %slval\n", spec_name_prefix);
-      obstack_fgrow1 (&table_obstack,
-                     "#define yychar %schar\n", spec_name_prefix);
-      obstack_fgrow1 (&table_obstack,
-                     "#define yydebug %sdebug\n", spec_name_prefix);
-      obstack_fgrow1 (&table_obstack,
-                     "#define yynerrs %snerrs\n", spec_name_prefix);
+       ++j;
+      obstack_fgrow1 (oout, "%6d", table_data[i]);
     }
     }
+  obstack_1grow (oout, 0);
 }
 
 
 }
 
 
-/*-------------------------------------------------------.
-| Output constant strings to the ends of certain files.  |
-`-------------------------------------------------------*/
-
-void
-output_trailers (void)
-{
-  if (semantic_parser)
-    fprintf (fguard, "\n    }\n}\n");
-
-  obstack_1grow (&action_obstack, '\n');
-
-  if (no_parser_flag)
-    return;
-
-  if (semantic_parser)
-    obstack_grow_literal_string (&action_obstack, "    }\n");
-
-  obstack_grow_literal_string (&action_obstack, "}\n");
-}
-
-
-
 static void
 output_token_translations (void)
 {
 static void
 output_token_translations (void)
 {
-  obstack_grow_literal_string (&table_obstack, "\
-\n\
-/* YYRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */\n");
-
-  if (translations)
-    {
-      obstack_fgrow2 (&table_obstack,
-      "#define YYTRANSLATE(x) ((unsigned)(x) <= %d ? yytranslate[x] : %d)\
-\n\
-\n",
-              max_user_token_number, nsyms);
-
-      output_short_or_char_table (&table_obstack,
-            "YYRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX",
-                   ntokens < 127 ? "char" : "short",
-                   "yytranslate", token_translations,
-                   0, 1, max_user_token_number + 1);
-    }
-  else
-    {
-      obstack_grow_literal_string (&table_obstack,
-                                  "\n#define YYTRANSLATE(x) (x)\n");
-    }
+  output_table_data (&output_obstack, token_translations,
+                    0, 1, max_user_token_number + 1);
+  muscle_insert ("translate", obstack_finish (&output_obstack));
+  XFREE (token_translations);
 }
 
 
 static void
 output_gram (void)
 {
 }
 
 
 static void
 output_gram (void)
 {
-  /* With the ordinary parser,
-     yyprhs and yyrhs are needed only for yydebug. */
-  /* With the no_parser option, all tables are generated */
-  if (!semantic_parser && !no_parser_flag)
-    obstack_grow_literal_string (&table_obstack, "\n#if YYDEBUG != 0\n");
+  {
+    int i;
+    short *values = XCALLOC (short, nrules + 1);
+    for (i = 0; i < nrules + 1; ++i)
+      values[i] = rule_table[i].rhs;
+    output_table_data (&output_obstack, values,
+                      0, 1, nrules + 1);
+    XFREE (values);
+  }
 
 
-  output_short_table (&table_obstack, NULL, "yyprhs", rrhs,
-                     0, 1, nrules + 1);
+  muscle_insert ("prhs", obstack_finish (&output_obstack));
 
   {
     size_t yyrhs_size = 1;
 
   {
     size_t yyrhs_size = 1;
@@ -338,21 +193,30 @@ output_gram (void)
     for (sp = ritem + 1, i = 1; *sp; ++sp, ++i)
       yyrhs[i] = *sp > 0 ? *sp : 0;
 
     for (sp = ritem + 1, i = 1; *sp; ++sp, ++i)
       yyrhs[i] = *sp > 0 ? *sp : 0;
 
-    output_short_table (&table_obstack, NULL, "yyrhs", yyrhs,
-                       ritem[0], 1, yyrhs_size);
+    output_table_data (&output_obstack, yyrhs,
+                      ritem[0], 1, yyrhs_size);
+    muscle_insert ("rhs", obstack_finish (&output_obstack));
+
     XFREE (yyrhs);
   }
 
     XFREE (yyrhs);
   }
 
+#if 0
   if (!semantic_parser && !no_parser_flag)
   if (!semantic_parser && !no_parser_flag)
-    obstack_grow_literal_string (&table_obstack, "\n#endif\n");
+    obstack_sgrow (&table_obstack, "\n#endif\n");
+#endif
 }
 
 
 static void
 output_stos (void)
 {
 }
 
 
 static void
 output_stos (void)
 {
-  output_short_table (&table_obstack, NULL, "yystos", accessing_symbol,
-                     0, 1, nstates);
+  int i;
+  short *values = (short *) alloca (sizeof (short) * nstates);
+  for (i = 0; i < nstates; ++i)
+    values[i] = state_table[i].accessing_symbol;
+  output_table_data (&output_obstack, values,
+                    0, 1, nstates);
+  muscle_insert ("stos", obstack_finish (&output_obstack));
 }
 
 
 }
 
 
@@ -363,34 +227,16 @@ output_rule_data (void)
   int j;
   short *short_tab = NULL;
 
   int j;
   short *short_tab = NULL;
 
-  obstack_grow_literal_string (&table_obstack, "\n\
-#if YYDEBUG != 0\n");
-
-  output_short_table (&table_obstack,
-           "YYRLINE[YYN] -- source line where rule number YYN was defined",
-                     "yyrline", rline,
-                     0, 1, nrules + 1);
-
-  obstack_grow_literal_string (&table_obstack, "#endif\n\n");
-
-  if (token_table_flag || no_parser_flag)
-    {
-      obstack_fgrow1 (&table_obstack, "#define YYNTOKENS %d\n", ntokens);
-      obstack_fgrow1 (&table_obstack, "#define YYNNTS %d\n", nvars);
-      obstack_fgrow1 (&table_obstack, "#define YYNRULES %d\n", nrules);
-      obstack_fgrow1 (&table_obstack, "#define YYNSTATES %d\n", nstates);
-      obstack_fgrow1 (&table_obstack, "#define YYMAXUTOK %d\n\n",
-                     max_user_token_number);
-    }
+  {
+    short *values = XCALLOC (short, nrules + 1);
+    for (i = 0; i < nrules + 1; ++i)
+      values[i] = rule_table[i].line;
+    output_table_data (&output_obstack, values,
+                      0, 1, nrules + 1);
+    muscle_insert ("rline", obstack_finish (&output_obstack));
+    XFREE (values);
+  }
 
 
-  /* Output the table of symbol names.  */
-  if (!token_table_flag && !no_parser_flag)
-    obstack_grow_literal_string (&table_obstack,
-                         "\n#if YYDEBUG != 0 || defined YYERROR_VERBOSE\n\n");
-  obstack_grow_literal_string (&table_obstack, "\
-/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */\n");
-  obstack_grow_literal_string (&table_obstack,
-          "static const char *const yytname[] =\n{\n  ");
 
   j = 0;
   for (i = 0; i < nsyms; i++)
 
   j = 0;
   for (i = 0; i < nsyms; i++)
@@ -413,92 +259,66 @@ output_rule_data (void)
 
       if (j + strsize > 75)
        {
 
       if (j + strsize > 75)
        {
-         obstack_grow_literal_string (&table_obstack, "\n  ");
+         obstack_sgrow (&output_obstack, "\n  ");
          j = 2;
        }
 
          j = 2;
        }
 
-      obstack_1grow (&table_obstack, '\"');
+      obstack_1grow (&output_obstack, '\"');
       for (p = tags[i]; p && *p; p++)
        {
          if (*p == '"' || *p == '\\')
       for (p = tags[i]; p && *p; p++)
        {
          if (*p == '"' || *p == '\\')
-           {
-             obstack_fgrow1 (&table_obstack, "\\%c", *p);
-           }
+           obstack_fgrow1 (&output_obstack, "\\%c", *p);
          else if (*p == '\n')
          else if (*p == '\n')
-           {
-             obstack_grow_literal_string (&table_obstack, "\\n");
-           }
+           obstack_sgrow (&output_obstack, "\\n");
          else if (*p == '\t')
          else if (*p == '\t')
-           {
-             obstack_grow_literal_string (&table_obstack, "\\t");
-           }
+           obstack_sgrow (&output_obstack, "\\t");
          else if (*p == '\b')
          else if (*p == '\b')
-           {
-             obstack_grow_literal_string (&table_obstack, "\\b");
-           }
+           obstack_sgrow (&output_obstack, "\\b");
          else if (*p < 040 || *p >= 0177)
          else if (*p < 040 || *p >= 0177)
-           {
-             obstack_fgrow1 (&table_obstack, "\\%03o", *p);
-           }
+           obstack_fgrow1 (&output_obstack, "\\%03o", *p);
          else
          else
-           {
-             obstack_1grow (&table_obstack, *p);
-           }
+           obstack_1grow (&output_obstack, *p);
        }
 
        }
 
-      obstack_grow_literal_string (&table_obstack, "\", ");
+      obstack_sgrow (&output_obstack, "\", ");
       j += strsize;
     }
   /* add a NULL entry to list of tokens */
       j += strsize;
     }
   /* add a NULL entry to list of tokens */
-  obstack_grow_literal_string (&table_obstack, "NULL\n};\n");
+  obstack_sgrow (&output_obstack, "NULL");
 
 
-  if (!token_table_flag && !no_parser_flag)
-    obstack_grow_literal_string (&table_obstack, "#endif\n\n");
+  /* Finish table and store. */
+  obstack_1grow (&output_obstack, 0);
+  muscle_insert ("tname", obstack_finish (&output_obstack));
 
   /* Output YYTOKNUM. */
 
   /* Output YYTOKNUM. */
-  if (token_table_flag)
-    {
-      output_short_table (&table_obstack,
-                 "YYTOKNUM[YYLEX] -- Index in YYTNAME corresponding to YYLEX",
-                         "yytoknum", user_toknums,
-                         0, 1, ntokens + 1);
-    }
+  output_table_data (&output_obstack, user_toknums,
+                    0, 1, ntokens + 1);
+  muscle_insert ("toknum", obstack_finish (&output_obstack));
 
   /* Output YYR1. */
 
   /* Output YYR1. */
-  output_short_table (&table_obstack,
-             "YYR1[YYN] -- Symbol number of symbol that rule YYN derives",
-                     "yyr1", rlhs,
-                     0, 1, nrules + 1);
-  XFREE (rlhs + 1);
-
-  obstack_1grow (&table_obstack, '\n');
+  {
+    short *values = XCALLOC (short, nrules + 1);
+    for (i = 0; i < nrules + 1; ++i)
+      values[i] = rule_table[i].lhs;
+    output_table_data (&output_obstack, values,
+                      0, 1, nrules + 1);
+    muscle_insert ("r1", obstack_finish (&output_obstack));
+    XFREE (values);
+  }
 
   /* 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] = rrhs[i + 1] - rrhs[i] - 1;
-  short_tab[nrules] = nitems - rrhs[nrules] - 1;
-  output_short_table (&table_obstack,
-        "YYR2[YYN] -- Number of symbols composing right hand side of rule YYN",
-                     "yyr2", short_tab,
-                     0, 1, nrules + 1);
-  obstack_1grow (&table_obstack, '\n');
-
+    short_tab[i] = rule_table[i + 1].rhs - rule_table[i].rhs - 1;
+  short_tab[nrules] =  nitems - rule_table[nrules].rhs - 1;
+  output_table_data (&output_obstack, short_tab,
+                    0, 1, nrules + 1);
+  muscle_insert ("r2", obstack_finish (&output_obstack));
   XFREE (short_tab);
 
   XFREE (short_tab);
 
-  XFREE (rrhs + 1);
-}
-
-
-static void
-output_defines (void)
-{
-  obstack_fgrow1 (&table_obstack, "\n\n#define\tYYFINAL\t\t%d\n", final_state);
-  obstack_fgrow1 (&table_obstack, "#define\tYYFLAG\t\t%d\n", MINSHORT);
-  obstack_fgrow1 (&table_obstack, "#define\tYYNTBASE\t%d\n", ntokens);
+  XFREE (rule_table + 1);
 }
 
 }
 
-
 /*------------------------------------------------------------------.
 | Decide what to do for each type of token if seen as the lookahead |
 | token in specified state.  The value returned is used as the      |
 /*------------------------------------------------------------------.
 | Decide what to do for each type of token if seen as the lookahead |
 | token in specified state.  The value returned is used as the      |
@@ -521,15 +341,11 @@ action_row (int state)
   int k;
   int m = 0;
   int n = 0;
   int k;
   int m = 0;
   int n = 0;
-  int count;
   int default_rule;
   int nreds;
   int default_rule;
   int nreds;
-  int max;
   int rule;
   int shift_state;
   int symbol;
   int rule;
   int shift_state;
   int symbol;
-  unsigned mask;
-  unsigned *wordp;
   reductions *redp;
   shifts *shiftp;
   errs *errp;
   reductions *redp;
   shifts *shiftp;
   errs *errp;
@@ -540,7 +356,7 @@ action_row (int state)
 
   default_rule = 0;
   nreds = 0;
 
   default_rule = 0;
   nreds = 0;
-  redp = reduction_table[state];
+  redp = state_table[state].reduction_table;
 
   if (redp)
     {
 
   if (redp)
     {
@@ -550,69 +366,46 @@ action_row (int state)
        {
          /* loop over all the rules available here which require
             lookahead */
        {
          /* loop over all the rules available here which require
             lookahead */
-         m = lookaheads[state];
-         n = lookaheads[state + 1];
+         m = state_table[state].lookaheads;
+         n = state_table[state + 1].lookaheads;
 
          for (i = n - 1; i >= m; i--)
 
          for (i = n - 1; i >= m; i--)
-           {
-             rule = -LAruleno[i];
-             wordp = LA + i * tokensetsize;
-             mask = 1;
-
-             /* and find each token which the rule finds acceptable
-                to come next */
-             for (j = 0; j < ntokens; j++)
-               {
-                 /* and record this rule as the rule to use if that
-                    token follows.  */
-                 if (mask & *wordp)
-                   actrow[j] = rule;
-
-                 mask <<= 1;
-                 if (mask == 0)
-                   {
-                     mask = 1;
-                     wordp++;
-                   }
-               }
-           }
+           /* and find each token which the rule finds acceptable
+              to come next */
+           for (j = 0; j < ntokens; j++)
+             /* and record this rule as the rule to use if that
+                token follows.  */
+             if (BITISSET (LA (i), j))
+               actrow[j] = -LAruleno[i];
        }
     }
 
        }
     }
 
-  shiftp = shift_table[state];
-
   /* Now see which tokens are allowed for shifts in this state.  For
      them, record the shift as the thing to do.  So shift is preferred
      to reduce.  */
   /* Now see which tokens are allowed for shifts in this state.  For
      them, record the shift as the thing to do.  So shift is preferred
      to reduce.  */
-
-  if (shiftp)
+  shiftp = state_table[state].shift_table;
+  for (i = 0; i < shiftp->nshifts; i++)
     {
     {
-      k = shiftp->nshifts;
+      shift_state = shiftp->shifts[i];
+      if (!shift_state)
+       continue;
 
 
-      for (i = 0; i < k; i++)
-       {
-         shift_state = shiftp->shifts[i];
-         if (!shift_state)
-           continue;
-
-         symbol = accessing_symbol[shift_state];
+      symbol = state_table[shift_state].accessing_symbol;
 
 
-         if (ISVAR (symbol))
-           break;
+      if (ISVAR (symbol))
+       break;
 
 
-         actrow[symbol] = shift_state;
+      actrow[symbol] = shift_state;
 
 
-         /* Do not use any default reduction if there is a shift for
-            error */
-         if (symbol == error_token_number)
-           nodefault = 1;
-       }
+      /* Do not use any default reduction if there is a shift for
+        error */
+      if (symbol == error_token_number)
+       nodefault = 1;
     }
 
     }
 
-  errp = err_table[state];
-
   /* See which tokens are an explicit error in this state (due to
      %nonassoc).  For them, record MINSHORT as the action.  */
   /* See which tokens are an explicit error in this state (due to
      %nonassoc).  For them, record MINSHORT as the action.  */
+  errp = err_table[state];
 
   if (errp)
     {
 
   if (errp)
     {
@@ -630,14 +423,14 @@ action_row (int state)
 
   if (nreds >= 1 && !nodefault)
     {
 
   if (nreds >= 1 && !nodefault)
     {
-      if (consistent[state])
+      if (state_table[state].consistent)
        default_rule = redp->rules[0];
       else
        {
        default_rule = redp->rules[0];
       else
        {
-         max = 0;
+         int max = 0;
          for (i = m; i < n; i++)
            {
          for (i = m; i < n; i++)
            {
-             count = 0;
+             int count = 0;
              rule = -LAruleno[i];
 
              for (j = 0; j < ntokens; j++)
              rule = -LAruleno[i];
 
              for (j = 0; j < ntokens; j++)
@@ -739,50 +532,16 @@ token_actions (void)
       yydefact[i] = action_row (i);
       save_row (i);
     }
       yydefact[i] = action_row (i);
       save_row (i);
     }
-  XFREE (actrow);
-
-  output_short_table (&table_obstack,
-  "YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE\n\
-   doesn't specify something else to do.  Zero means the default is an\n\
-   error",
-                     "yydefact", yydefact,
-                     yydefact[0], 1, nstates);
-  obstack_1grow (&table_obstack, '\n');
-  XFREE (yydefact);
-}
-
-
-static void
-free_shifts (void)
-{
-  shifts *sp, *sptmp;  /* JF derefrenced freed ptr */
-
-  XFREE (shift_table);
-
-  for (sp = first_shift; sp; sp = sptmp)
-    {
-      sptmp = sp->next;
-      XFREE (sp);
-    }
-}
 
 
+  output_table_data (&output_obstack, yydefact,
+                    yydefact[0], 1, nstates);
+  muscle_insert ("defact", obstack_finish (&output_obstack));
 
 
-static void
-free_reductions (void)
-{
-  reductions *rp, *rptmp;      /* JF fixed freed ptr */
-
-  XFREE (reduction_table);
-
-  for (rp = first_reduction; rp; rp = rptmp)
-    {
-      rptmp = rp->next;
-      XFREE (rp);
-    }
+  XFREE (actrow);
+  XFREE (yydefact);
 }
 
 
 }
 
 
-
 static void
 save_column (int symbol, int default_state)
 {
 static void
 save_column (int symbol, int default_state)
 {
@@ -874,10 +633,9 @@ static void
 goto_actions (void)
 {
   int i;
 goto_actions (void)
 {
   int i;
-
   short *yydefgoto = XMALLOC (short, nsyms - ntokens);
   short *yydefgoto = XMALLOC (short, nsyms - ntokens);
-  state_count = XCALLOC (short, nstates);
 
 
+  state_count = XCALLOC (short, nstates);
   for (i = ntokens; i < nsyms; ++i)
     {
       int default_state = default_goto (i);
   for (i = ntokens; i < nsyms; ++i)
     {
       int default_state = default_goto (i);
@@ -885,8 +643,9 @@ goto_actions (void)
       yydefgoto[i - ntokens] = default_state;
     }
 
       yydefgoto[i - ntokens] = default_state;
     }
 
-  output_short_table (&table_obstack, NULL, "yydefgoto", yydefgoto,
-                     yydefgoto[0], 1, nsyms - ntokens);
+  output_table_data (&output_obstack, yydefgoto,
+                    yydefgoto[0], 1, nsyms - ntokens);
+  muscle_insert ("defgoto", obstack_finish (&output_obstack));
 
   XFREE (state_count);
   XFREE (yydefgoto);
 
   XFREE (state_count);
   XFREE (yydefgoto);
@@ -1088,13 +847,15 @@ pack_table (void)
 static void
 output_base (void)
 {
 static void
 output_base (void)
 {
-  output_short_table (&table_obstack, NULL, "yypact", base,
-                     base[0], 1, nstates);
-
-  obstack_1grow (&table_obstack, '\n');
+  /* Output pact. */
+  output_table_data (&output_obstack, base,
+                    base[0], 1, nstates);
+  muscle_insert ("pact", obstack_finish (&output_obstack));
 
 
-  output_short_table (&table_obstack, NULL, "yypgoto", base,
-                     base[nstates], nstates + 1, nvectors);
+  /* Output pgoto. */
+  output_table_data (&output_obstack, base,
+                    base[nstates], nstates + 1, nvectors);
+  muscle_insert ("pgoto", obstack_finish (&output_obstack));
 
   XFREE (base);
 }
 
   XFREE (base);
 }
@@ -1103,9 +864,9 @@ output_base (void)
 static void
 output_table (void)
 {
 static void
 output_table (void)
 {
-  obstack_fgrow1 (&table_obstack, "\n\n#define\tYYLAST\t\t%d\n\n\n", high);
-  output_short_table (&table_obstack, NULL, "yytable", table,
-                     table[0], 1, high + 1);
+  output_table_data (&output_obstack, table,
+                    table[0], 1, high + 1);
+  muscle_insert ("table", obstack_finish (&output_obstack));
   XFREE (table);
 }
 
   XFREE (table);
 }
 
@@ -1113,8 +874,9 @@ output_table (void)
 static void
 output_check (void)
 {
 static void
 output_check (void)
 {
-  output_short_table (&table_obstack, NULL, "yycheck", check,
-                     check[0], 1, high + 1);
+  output_table_data (&output_obstack, check,
+                    check[0], 1, high + 1);
+  muscle_insert ("check", obstack_finish (&output_obstack));
   XFREE (check);
 }
 
   XFREE (check);
 }
 
@@ -1132,12 +894,10 @@ output_actions (void)
   width = XCALLOC (short, nvectors);
 
   token_actions ();
   width = XCALLOC (short, nvectors);
 
   token_actions ();
-  free_shifts ();
-  free_reductions ();
-  XFREE (lookaheads);
+  LIST_FREE (shifts, first_shift);
+  LIST_FREE (reductions, first_reduction);
   XFREE (LA);
   XFREE (LAruleno);
   XFREE (LA);
   XFREE (LAruleno);
-  XFREE (accessing_symbol);
 
   goto_actions ();
   XFREE (goto_map + ntokens);
 
   goto_actions ();
   XFREE (goto_map + ntokens);
@@ -1146,133 +906,143 @@ output_actions (void)
 
   sort_actions ();
   pack_table ();
 
   sort_actions ();
   pack_table ();
-  obstack_1grow (&table_obstack, '\n');
+
   output_base ();
   output_table ();
   output_base ();
   output_table ();
-  obstack_1grow (&table_obstack, '\n');
+
   output_check ();
   output_check ();
+  XFREE (state_table);
 }
 
 }
 
-/*------------------------------------------.
-| Copy the parser code into TABLE_OBSTACK.  |
-`------------------------------------------*/
+\f
+/*------------------------------------------------------------.
+| Copy the parser code from SKEL_FILENAME into OOUT obstack.  |
+| and do the muscle substitution.                             |
+`------------------------------------------------------------*/
 
 static void
 
 static void
-output_parser (void)
+output_parser (const char *skel_filename, struct obstack *oout)
 {
   int c;
   FILE *fskel;
   size_t line;
 {
   int c;
   FILE *fskel;
   size_t line;
-  const char *skeleton = NULL;
-  int number_of_dollar_signs = 0;
 
 
-  if (pure_parser)
-    obstack_grow_literal_string (&table_obstack, "#define YYPURE 1\n\n");
+  fskel = xfopen (skel_filename, "r");
 
 
-  /* Loop over lines in the standard parser file.  */
-  if (semantic_parser)
-    skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
-  else
-    skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
-  fskel = xfopen (skeleton, "r");
-
-  /* Set LINE to 2, not 1: `#line LINENUM' -- Here LINENUM is a
-     decimal integer constant.  This specifies that the line number of
-     the *following* line of input, in its original source file, was
-     LINENUM.  */
-  line = 2;
-
-  while (1)
+  /* New output code.  */
+  line = 1;
+  c = getc (fskel);
+  while (c != EOF)
     {
     {
-      int is_sync_line = 0;
-      int write_line = 1;
-
-      c = getc (fskel);
-
-      /* See if the line starts with `#line'. */
-      if (c == '#')
-       if ((c = getc (fskel)) == 'l')
-         if ((c = getc (fskel)) == 'i')
-           if ((c = getc (fskel)) == 'n')
-             if ((c = getc (fskel)) == 'e')
-               is_sync_line = 1;
-             else
-               obstack_grow_literal_string (&table_obstack, "#lin");
-           else
-             obstack_grow_literal_string (&table_obstack, "#li");
+      if (c != '%')
+       {
+         if (c == '\n')
+           ++line;
+         obstack_1grow (oout, c);
+         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 (muscle_value)
+           obstack_sgrow (oout, muscle_value);
+         else if (!strcmp (muscle_key, "line"))
+           obstack_fgrow1 (oout, "%d", line + 1);
+         else if (!strcmp (muscle_key, "input-line"))
+           obstack_fgrow1 (oout, "%d", lineno);
          else
          else
-           obstack_grow_literal_string (&table_obstack, "#l");
-       else
-         obstack_grow_literal_string (&table_obstack, "#");
-
-      /* If was a `#line' line, either compute it, or drop it. */
-      if (is_sync_line && !no_lines_flag)
-       obstack_fgrow2 (&table_obstack, "#line %d %s\n",
-                       line, quotearg_style (c_quoting_style, skeleton));
-
-      if (is_sync_line)
-       write_line = 0;
-
-      /* now write out the line... */
-      for (; c != '\n' && c != EOF; c = getc (fskel))
-       if (write_line)
-         {
-           /* `$' in the parser file indicates where to put the
-              actions.  Copy them in at this point.  */
-           if (c == '$')
-             {
-               size_t size = obstack_object_size (&action_obstack);
-
-               number_of_dollar_signs++;
-               assert (number_of_dollar_signs == 1);
-               obstack_grow (&table_obstack,
-                             obstack_finish (&action_obstack),
-                             size);
-
-               /* Skip the end of the line containing `$'. */
-               write_line = 0;
-             }
-           else
-             obstack_1grow (&table_obstack, c);
-         }
-      if (c == EOF)
-       break;
-      obstack_1grow (&table_obstack, c);
-      line++;
+           {
+             obstack_sgrow (oout, "%%");
+             obstack_sgrow (oout, muscle_key);
+           }
+       }
+      else
+       obstack_1grow (oout, '%');
     }
     }
-  assert (number_of_dollar_signs == 1);
+
+  /* End.  */
   xfclose (fskel);
 }
 
   xfclose (fskel);
 }
 
+/*----------------------------------------.
+| Prepare the master parser to be output  |
+`----------------------------------------*/
+
 static void
 static void
-output_program (void)
+output_master_parser (void)
 {
 {
-  int c;
+  if (!skeleton)
+    {
+      if (semantic_parser)
+       skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
+      else
+       skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
+    }
+  muscle_insert ("skeleton", skeleton);    
+  output_parser (skeleton, &table_obstack);
+}
+
 
 
-  if (!no_lines_flag)
-    obstack_fgrow2 (&table_obstack, "#line %d %s\n",
-                   lineno, quotearg_style (c_quoting_style, infile));
+/* FIXME. */
 
 
-  while ((c = getc (finput)) != EOF)
-    obstack_1grow (&table_obstack, c);
+#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));       \
+}
+
+#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));               \
+}
 
 static void
 
 static void
-free_itemsets (void)
+prepare (void)
 {
 {
-  core *cp, *cptmp;
+  MUSCLE_INSERT_INT ("last", high);
+  MUSCLE_INSERT_INT ("flag", MINSHORT);
+  MUSCLE_INSERT_INT ("pure", pure_parser);
+  MUSCLE_INSERT_INT ("nsym", nsyms);
+  MUSCLE_INSERT_INT ("debug", debug_flag);
+  MUSCLE_INSERT_INT ("final", final_state);
+  MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
+  MUSCLE_INSERT_INT ("ntbase", ntokens);
+  MUSCLE_INSERT_INT ("error-verbose", error_verbose);
+
+  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);
+
+  /* We need to save the actions in the muscle %%action.  */
+  muscle_insert ("action", obstack_finish (&action_obstack));
 
 
-  XFREE (state_table);
-
-  for (cp = first_state; cp; cp = cptmp)
-    {
-      cptmp = cp->next;
-      XFREE (cp);
-    }
+  if (spec_name_prefix)
+    MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
 }
 
 }
 
-
 /*----------------------------------------------------------.
 | Output the parsing tables and the parser code to ftable.  |
 `----------------------------------------------------------*/
 /*----------------------------------------------------------.
 | Output the parsing tables and the parser code to ftable.  |
 `----------------------------------------------------------*/
@@ -1280,51 +1050,30 @@ free_itemsets (void)
 void
 output (void)
 {
 void
 output (void)
 {
-  /* output_token_defines(ftable);      / * JF put out token defines FIRST */
+  obstack_init (&output_obstack);
 
 
-  /* If using a simple parser the definition of YYSTYPE are put into
-     TABLE_OBSTACK.  */
-  if (!semantic_parser)
-    {
-      size_t size = obstack_object_size (&attrs_obstack);
-      obstack_grow (&table_obstack, obstack_finish (&attrs_obstack), size);
-    }
-  reader_output_yylsp (&table_obstack);
-  if (debug_flag)
-    obstack_grow_literal_string (&table_obstack, "\
-#ifndef YYDEBUG\n\
-# define YYDEBUG 1\n\
-#endif\n\
-\n");
+  LIST_FREE (core, first_state);
 
 
-  if (semantic_parser)
-    obstack_fgrow1 (&table_obstack, "#include %s\n",
-                   quotearg_style (c_quoting_style, attrsfile));
-
-  if (!no_parser_flag)
-    obstack_grow_literal_string (&table_obstack, "#include <stdio.h>\n\n");
-
-  /* Make "const" do nothing if not in ANSI C.  */
-  obstack_grow_literal_string (&table_obstack, "\
-#ifndef __cplusplus\n\
-# ifndef __STDC__\n\
-#  define const\n\
-# endif\n\
-#endif\n\
-\n");
-
-  free_itemsets ();
-  output_defines ();
   output_token_translations ();
   output_token_translations ();
-/*   if (semantic_parser) */
-  /* This is now unconditional because debugging printouts can use it.  */
   output_gram ();
   output_gram ();
+
   XFREE (ritem);
   if (semantic_parser)
     output_stos ();
   output_rule_data ();
   XFREE (ritem);
   if (semantic_parser)
     output_stos ();
   output_rule_data ();
+  XFREE (user_toknums);
   output_actions ();
   output_actions ();
-  if (!no_parser_flag)
-    output_parser ();
-  output_program ();
+
+#if 0
+  if (!no_parser_flag) */
+#endif
+  prepare ();
+  /* Copy definitions in directive.  */
+  muscle_insert ("prologue", obstack_finish (&attrs_obstack));
+
+  output_master_parser ();
+
+  obstack_free (&muscle_obstack, 0);
+  obstack_free (&output_obstack, 0);
+  obstack_free (&action_obstack, 0);
 }
 }