]> git.saurik.com Git - bison.git/blobdiff - src/output.c
* src/bison.simple (YYSTACK_ALLOC, YYSIZE_T): Remove special
[bison.git] / src / output.c
index 54ec5c19a89806cbcd4ffdd31bc74008108629cb..4ad8f4e803e0abba8403e6d691a18c8c868acfb1 100644 (file)
@@ -1,5 +1,5 @@
 /* Output the generated parsing program for bison,
 /* Output the generated parsing program for bison,
-   Copyright (C) 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.
 
@@ -91,8 +91,8 @@
 */
 
 #include "system.h"
 */
 
 #include "system.h"
+#include "quotearg.h"
 #include "getargs.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"
-
-extern void berror PARAMS((const char *));
-
+#include "muscle_tab.h"
 
 
 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;
+static struct obstack format_obstack;
 
 
+int error_verbose = 0;
 
 
-static inline void
-output_short_table (FILE *out,
-                   const char *comment,
-                   const char *table_name,
-                   short *short_table,
-                   short first_value,
-                   short begin, short end)
+/* Returns the number of lines of S.  */
+static size_t
+get_lines_number (const char *s)
 {
 {
-  int i, j;
-
-  if (comment)
-    fprintf (out, "/* %s. */\n", comment);
-
-  fprintf (out, "static const short %s[] =\n{\n  %6d",
-          table_name, first_value);
-
-  j = 1;
-  for (i = begin; i < end; i++)
-    {
-      putc (',', out);
-
-      if (j >= 10)
-       {
-         fputs ("\n  ", out);
-         j = 1;
-       }
-      else
-       {
-         j++;
-       }
+  size_t lines = 0;
 
 
-      fprintf (out, "%6d", short_table[i]);
-    }
+  size_t i;
+  for (i = 0; s[i]; ++i)
+    if (s[i] == '\n')
+      ++lines;
 
 
-  fprintf (out, "\n};\n");
+  return lines;
 }
 
 
 }
 
 
-/*--------------------------------------------------------------.
-| output_headers -- Output constant strings to the beginning of |
-| certain files.                                                |
-`--------------------------------------------------------------*/
-
-#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"
+/* FIXME. */
 
 
-void
-output_headers (void)
+static inline void
+output_table_data (struct obstack *oout,
+                  short *table_data,
+                  short first,
+                  int begin,
+                  int end)
 {
 {
-  if (semantic_parser)
-    fprintf (fguard, GUARDSTR, attrsfile);
-
-  if (no_parser_flag)
-    return;
-
-  fprintf (faction, (semantic_parser ? ACTSTR : ACTSTR_SIMPLE), attrsfile);
-/*  if (semantic_parser)       JF moved this below
-    fprintf(ftable, "#include \"%s\"\n", attrsfile);
-  fprintf(ftable, "#include <stdio.h>\n\n");
-*/
+  int i;
+  int j = 1;
 
 
-  /* Rename certain symbols if -p was specified.  */
-  if (spec_name_prefix)
+  obstack_fgrow1 (oout, "%6d", first);
+  for (i = begin; i < end; ++i)
     {
     {
-      fprintf (ftable, "#define yyparse %sparse\n", spec_name_prefix);
-      fprintf (ftable, "#define yylex %slex\n", spec_name_prefix);
-      fprintf (ftable, "#define yyerror %serror\n", spec_name_prefix);
-      fprintf (ftable, "#define yylval %slval\n", spec_name_prefix);
-      fprintf (ftable, "#define yychar %schar\n", spec_name_prefix);
-      fprintf (ftable, "#define yydebug %sdebug\n", spec_name_prefix);
-      fprintf (ftable, "#define yynerrs %snerrs\n", spec_name_prefix);
+      obstack_1grow (oout, ',');
+      if (j >= 10)
+       {
+         obstack_sgrow (oout, "\n  ");
+         j = 1;
+       }
+      else
+       ++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");
-
-  fprintf (faction, "\n");
-
-  if (no_parser_flag)
-    return;
-
-  if (semantic_parser)
-    fprintf (faction, "    }\n");
-  fprintf (faction, "}\n");
-}
-
-
-
 static void
 output_token_translations (void)
 {
 static void
 output_token_translations (void)
 {
-  int i, j;
-/*   short *sp; JF unused */
-
-  if (translations)
-    {
-      fprintf (ftable,
-              "\n#define YYTRANSLATE(x) ((unsigned)(x) <= %d ? yytranslate[x] : %d)\n",
-              max_user_token_number, nsyms);
-
-      if (ntokens < 127)       /* play it very safe; check maximum element value.  */
-       fprintf (ftable, "\nstatic const char yytranslate[] = {     0");
-      else
-       fprintf (ftable, "\nstatic const short yytranslate[] = {     0");
-
-      j = 10;
-      for (i = 1; i <= max_user_token_number; i++)
-       {
-         putc (',', ftable);
-
-         if (j >= 10)
-           {
-             putc ('\n', ftable);
-             j = 1;
-           }
-         else
-           {
-             j++;
-           }
-
-         fprintf (ftable, "%6d", token_translations[i]);
-       }
-
-      fprintf (ftable, "\n};\n");
-    }
-  else
-    {
-      fprintf (ftable, "\n#define YYTRANSLATE(x) (x)\n");
-    }
+  output_table_data (&format_obstack, token_translations,
+                    0, 1, max_user_token_number + 1);
+  muscle_insert ("translate", obstack_finish (&format_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)
-    fprintf (ftable, "\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 (&format_obstack, values,
+                      0, 1, nrules + 1);
+    XFREE (values);
+  }
 
 
-  output_short_table (ftable, NULL, "yyprhs", rrhs,
-                     0, 1, nrules + 1);
+  muscle_insert ("prhs", obstack_finish (&format_obstack));
 
   {
 
   {
-    size_t yyrhs_size = 1;
-    short *yyrhs, *sp;
+    short *yyrhs;
     int i;
 
     int i;
 
-    for (sp = ritem + 1; *sp; sp++)
-      ++yyrhs_size;
-    yyrhs = XMALLOC (short, yyrhs_size);
+    yyrhs = XMALLOC (short, nritems);
 
 
-    for (sp = ritem + 1, i = 1; *sp; ++sp, ++i)
-      yyrhs[i] = *sp > 0 ? *sp : 0;
+    for (i = 1; i < nritems; ++i)
+      yyrhs[i] = ritem[i] >= 0 ? ritem[i] : -1;
+
+    output_table_data (&format_obstack, yyrhs,
+                      ritem[0], 1, nritems);
+    muscle_insert ("rhs", obstack_finish (&format_obstack));
 
 
-    output_short_table (ftable, NULL, "yyrhs", yyrhs,
-                       ritem[0], 1, yyrhs_size);
     XFREE (yyrhs);
   }
 
     XFREE (yyrhs);
   }
 
-  if (!semantic_parser && !no_parser_flag)
-    fprintf (ftable, "\n#endif\n");
+#if 0
+  if (!semantic_parser)
+    obstack_sgrow (&table_obstack, "\n#endif\n");
+#endif
 }
 
 
 static void
 output_stos (void)
 {
 }
 
 
 static void
 output_stos (void)
 {
-  output_short_table (ftable, 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 (&format_obstack, values,
+                    0, 1, nstates);
+  muscle_insert ("stos", obstack_finish (&format_obstack));
 }
 
 
 }
 
 
@@ -346,142 +237,72 @@ output_rule_data (void)
   int j;
   short *short_tab = NULL;
 
   int j;
   short *short_tab = NULL;
 
-  fputs ("\n\
-#if YYDEBUG != 0\n",
-        ftable);
-
-  output_short_table (ftable,
-           "YYRLINE[YYN] -- source line where rule number YYN was defined",
-                     "yyrline", rline,
-                     0, 1, nrules + 1);
-
-  fputs ("#endif\n\n", ftable);
-
-  if (token_table_flag || no_parser_flag)
-    {
-      fprintf (ftable, "#define YYNTOKENS %d\n", ntokens);
-      fprintf (ftable, "#define YYNNTS %d\n", nvars);
-      fprintf (ftable, "#define YYNRULES %d\n", nrules);
-      fprintf (ftable, "#define YYNSTATES %d\n", nstates);
-      fprintf (ftable, "#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 (&format_obstack, values,
+                      0, 1, nrules + 1);
+    muscle_insert ("rline", obstack_finish (&format_obstack));
+    XFREE (values);
+  }
 
 
-  /* Output the table of symbol names.  */
-  if (!token_table_flag && !no_parser_flag)
-    fputs ("\n#if YYDEBUG != 0 || defined YYERROR_VERBOSE\n\n", ftable);
-  fputs ("\
-/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */\n",
-        ftable);
-  fprintf (ftable,
-          "static const char *const yytname[] =\n{\n  ");
 
   j = 0;
   for (i = 0; i < nsyms; i++)
 
   j = 0;
   for (i = 0; i < nsyms; i++)
-    /* this used to be i<=nsyms, but that output a final "" symbol
-       almost by accident */
     {
     {
+      /* Be sure not to use twice the same quotearg slot. */
+      const char *cp =
+       quotearg_n_style (1, c_quoting_style,
+                         quotearg_style (escape_quoting_style, tags[i]));
       /* Width of the next token, including the two quotes, the coma
         and the space.  */
       /* Width of the next token, including the two quotes, the coma
         and the space.  */
-      int strsize = 4;
-      char *p;
-
-      for (p = tags[i]; p && *p; p++)
-       if (*p == '"' || *p == '\\' || *p == '\n' || *p == '\t'
-           || *p == '\b')
-         strsize += 2;
-       else if (*p < 040 || *p >= 0177)
-         strsize += 4;
-       else
-         strsize++;
+      int strsize = strlen (cp) + 2;
 
       if (j + strsize > 75)
        {
 
       if (j + strsize > 75)
        {
-         fputs ("\n  ", ftable);
+         obstack_sgrow (&format_obstack, "\n  ");
          j = 2;
        }
 
          j = 2;
        }
 
-      putc ('\"', ftable);
-      for (p = tags[i]; p && *p; p++)
-       {
-         if (*p == '"' || *p == '\\')
-           {
-             fprintf (ftable, "\\%c", *p);
-           }
-         else if (*p == '\n')
-           {
-             fprintf (ftable, "\\n");
-           }
-         else if (*p == '\t')
-           {
-             fprintf (ftable, "\\t");
-           }
-         else if (*p == '\b')
-           {
-             fprintf (ftable, "\\b");
-           }
-         else if (*p < 040 || *p >= 0177)
-           {
-             fprintf (ftable, "\\%03o", *p);
-           }
-         else
-           {
-             putc (*p, ftable);
-           }
-       }
-
-      fputs ("\", ", ftable);
+      obstack_sgrow (&format_obstack, cp);
+      obstack_sgrow (&format_obstack, ", ");
       j += strsize;
     }
   /* add a NULL entry to list of tokens */
       j += strsize;
     }
   /* add a NULL entry to list of tokens */
-  fprintf (ftable, "NULL\n};\n");
+  obstack_sgrow (&format_obstack, "NULL");
 
 
-  if (!token_table_flag && !no_parser_flag)
-    fprintf (ftable, "#endif\n\n");
+  /* Finish table and store. */
+  obstack_1grow (&format_obstack, 0);
+  muscle_insert ("tname", obstack_finish (&format_obstack));
 
   /* Output YYTOKNUM. */
 
   /* Output YYTOKNUM. */
-  if (token_table_flag)
-    {
-      output_short_table (ftable,
-                 "YYTOKNUM[YYLEX] -- Index in YYTNAME corresponding to YYLEX",
-                         "yytoknum", user_toknums,
-                         0, 1, ntokens + 1);
-    }
+  output_table_data (&format_obstack, user_toknums,
+                    0, 1, ntokens + 1);
+  muscle_insert ("toknum", obstack_finish (&format_obstack));
 
   /* Output YYR1. */
 
   /* Output YYR1. */
-  output_short_table (ftable,
-             "YYR1[YYN] -- Symbol number of symbol that rule YYN derives",
-                     "yyr1", rlhs,
-                     0, 1, nrules + 1);
-  XFREE (rlhs + 1);
-
-  putc ('\n', ftable);
+  {
+    short *values = XCALLOC (short, nrules + 1);
+    for (i = 0; i < nrules + 1; ++i)
+      values[i] = rule_table[i].lhs;
+    output_table_data (&format_obstack, values,
+                      0, 1, nrules + 1);
+    muscle_insert ("r1", obstack_finish (&format_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 (ftable,
-        "YYR2[YYN] -- Number of symbols composing right hand side of rule YYN",
-                     "yyr2", short_tab,
-                     0, 1, nrules + 1);
-  putc ('\n', ftable);
-
+    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 (&format_obstack, short_tab,
+                    0, 1, nrules + 1);
+  muscle_insert ("r2", obstack_finish (&format_obstack));
   XFREE (short_tab);
   XFREE (short_tab);
-
-  XFREE (rrhs + 1);
-}
-
-
-static void
-output_defines (void)
-{
-  fprintf (ftable, "\n\n#define\tYYFINAL\t\t%d\n", final_state);
-  fprintf (ftable, "#define\tYYFLAG\t\t%d\n", MINSHORT);
-  fprintf (ftable, "#define\tYYNTBASE\t%d\n", ntokens);
 }
 
 }
 
-
 /*------------------------------------------------------------------.
 | 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      |
@@ -497,137 +318,84 @@ output_defines (void)
 `------------------------------------------------------------------*/
 
 static int
 `------------------------------------------------------------------*/
 
 static int
-action_row (int state)
+action_row (state_t *state)
 {
   int i;
 {
   int i;
-  int j;
-  int k;
-  int m = 0;
-  int n = 0;
-  int count;
-  int default_rule;
-  int nreds;
-  int max;
-  int rule;
-  int shift_state;
-  int symbol;
-  unsigned mask;
-  unsigned *wordp;
-  reductions *redp;
-  shifts *shiftp;
-  errs *errp;
-  int nodefault = 0;           /* set nonzero to inhibit having any default reduction */
+  int default_rule = 0;
+  reductions *redp = state->reductions;
+  shifts *shiftp = state->shifts;
+  errs *errp = state->errs;
+  /* set nonzero to inhibit having any default reduction */
+  int nodefault = 0;
 
   for (i = 0; i < ntokens; i++)
     actrow[i] = 0;
 
 
   for (i = 0; i < ntokens; i++)
     actrow[i] = 0;
 
-  default_rule = 0;
-  nreds = 0;
-  redp = reduction_table[state];
-
-  if (redp)
+  if (redp->nreds >= 1)
     {
     {
-      nreds = redp->nreds;
-
-      if (nreds >= 1)
-       {
-         /* loop over all the rules available here which require
-            lookahead */
-         m = lookaheads[state];
-         n = lookaheads[state + 1];
-
-         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++;
-                   }
-               }
-           }
-       }
+      int j;
+      /* loop over all the rules available here which require
+        lookahead */
+      for (i = state->nlookaheads - 1; i >= 0; --i)
+       /* 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 (state->lookaheadsp + i), j))
+           actrow[j] = -LAruleno[state->lookaheadsp + 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)
+  for (i = 0; i < shiftp->nshifts; i++)
     {
     {
-      k = shiftp->nshifts;
-
-      for (i = 0; i < k; i++)
-       {
-         shift_state = shiftp->shifts[i];
-         if (!shift_state)
-           continue;
+      int symbol;
+      int 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.  */
-
-  if (errp)
+  for (i = 0; i < errp->nerrs; i++)
     {
     {
-      k = errp->nerrs;
-
-      for (i = 0; i < k; i++)
-       {
-         symbol = errp->errs[i];
-         actrow[symbol] = MINSHORT;
-       }
+      int symbol = errp->errs[i];
+      actrow[symbol] = MINSHORT;
     }
 
   /* Now find the most common reduction and make it the default action
      for this state.  */
 
     }
 
   /* Now find the most common reduction and make it the default action
      for this state.  */
 
-  if (nreds >= 1 && !nodefault)
+  if (redp->nreds >= 1 && !nodefault)
     {
     {
-      if (consistent[state])
+      if (state->consistent)
        default_rule = redp->rules[0];
       else
        {
        default_rule = redp->rules[0];
       else
        {
-         max = 0;
-         for (i = m; i < n; i++)
+         int max = 0;
+         for (i = 0; i < state->nlookaheads; i++)
            {
            {
-             count = 0;
-             rule = -LAruleno[i];
+             int count = 0;
+             int rule = -LAruleno[state->lookaheadsp + i];
+             int j;
 
              for (j = 0; j < ntokens; j++)
 
              for (j = 0; j < ntokens; j++)
-               {
-                 if (actrow[j] == rule)
-                   count++;
-               }
+               if (actrow[j] == rule)
+                 count++;
 
              if (count > max)
                {
 
              if (count > max)
                {
@@ -641,11 +409,10 @@ action_row (int state)
 
          if (max > 0)
            {
 
          if (max > 0)
            {
+             int j;
              for (j = 0; j < ntokens; j++)
              for (j = 0; j < ntokens; j++)
-               {
-                 if (actrow[j] == default_rule)
-                   actrow[j] = 0;
-               }
+               if (actrow[j] == default_rule)
+                 actrow[j] = 0;
 
              default_rule = -default_rule;
            }
 
              default_rule = -default_rule;
            }
@@ -656,11 +423,9 @@ action_row (int state)
      So replace any action which says "error" with "use default".  */
 
   if (default_rule == 0)
      So replace any action which says "error" with "use default".  */
 
   if (default_rule == 0)
-    for (j = 0; j < ntokens; j++)
-      {
-       if (actrow[j] == MINSHORT)
-         actrow[j] = 0;
-      }
+    for (i = 0; i < ntokens; i++)
+      if (actrow[i] == MINSHORT)
+       actrow[i] = 0;
 
   return default_rule;
 }
 
   return default_rule;
 }
@@ -677,10 +442,8 @@ save_row (int state)
 
   count = 0;
   for (i = 0; i < ntokens; i++)
 
   count = 0;
   for (i = 0; i < ntokens; i++)
-    {
-      if (actrow[i] != 0)
-       count++;
-    }
+    if (actrow[i] != 0)
+      count++;
 
   if (count == 0)
     return;
 
   if (count == 0)
     return;
@@ -689,13 +452,11 @@ save_row (int state)
   tos[state] = sp2 = XCALLOC (short, count);
 
   for (i = 0; i < ntokens; i++)
   tos[state] = sp2 = XCALLOC (short, count);
 
   for (i = 0; i < ntokens; i++)
-    {
-      if (actrow[i] != 0)
-       {
-         *sp1++ = i;
-         *sp2++ = actrow[i];
-       }
-    }
+    if (actrow[i] != 0)
+      {
+       *sp1++ = i;
+       *sp2++ = actrow[i];
+      }
 
   tally[state] = count;
   width[state] = sp1[-1] - sp[0] + 1;
 
   tally[state] = count;
   width[state] = sp1[-1] - sp[0] + 1;
@@ -719,86 +480,117 @@ token_actions (void)
   actrow = XCALLOC (short, ntokens);
   for (i = 0; i < nstates; ++i)
     {
   actrow = XCALLOC (short, ntokens);
   for (i = 0; i < nstates; ++i)
     {
-      yydefact[i] = action_row (i);
+      yydefact[i] = action_row (state_table[i]);
       save_row (i);
     }
       save_row (i);
     }
-  XFREE (actrow);
 
 
-  output_short_table (ftable, NULL, "yydefact", yydefact,
-                     yydefact[0], 1, nstates);
+  output_table_data (&format_obstack, yydefact,
+                    yydefact[0], 1, nstates);
+  muscle_insert ("defact", obstack_finish (&format_obstack));
+
+  XFREE (actrow);
   XFREE (yydefact);
 }
 
 
   XFREE (yydefact);
 }
 
 
+/*-----------------------------.
+| Output the actions to OOUT.  |
+`-----------------------------*/
+
 static void
 static void
-free_shifts (void)
+actions_output (FILE *out, size_t *line)
 {
 {
-  shifts *sp, *sptmp;  /* JF derefrenced freed ptr */
-
-  XFREE (shift_table);
-
-  for (sp = first_shift; sp; sp = sptmp)
-    {
-      sptmp = sp->next;
-      XFREE (sp);
-    }
+  int rule;
+  for (rule = 1; rule < nrules + 1; ++rule)
+    if (rule_table[rule].action)
+      {
+       fprintf (out, "  case %d:\n", rule);
+
+       if (!no_lines_flag)
+         fprintf (out, muscle_find ("linef"),
+                  rule_table[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",
+                rule_table[rule].action,
+                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);
+      }
 }
 
 
 }
 
 
+/*----------------------------.
+| Output the guards to OOUT.  |
+`----------------------------*/
+
 static void
 static void
-free_reductions (void)
+guards_output (FILE *out, size_t *line)
 {
 {
-  reductions *rp, *rptmp;      /* JF fixed freed ptr */
-
-  XFREE (reduction_table);
-
-  for (rp = first_reduction; rp; rp = rptmp)
-    {
-      rptmp = rp->next;
-      XFREE (rp);
-    }
+  int rule;
+  for (rule = 1; rule < nrules + 1; ++rule)
+    if (rule_table[rule].action)
+      {
+       fprintf (out, "  case %d:\n", rule);
+
+       if (!no_lines_flag)
+         fprintf (out, muscle_find ("linef"),
+                  rule_table[rule].guard_line,
+                  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);
+      }
 }
 
 
 }
 
 
-
 static void
 save_column (int symbol, int default_state)
 {
   int i;
 static void
 save_column (int symbol, int default_state)
 {
   int i;
-  int m;
-  int n;
   short *sp;
   short *sp1;
   short *sp2;
   int count;
   short *sp;
   short *sp1;
   short *sp2;
   int count;
-  int symno;
+  int symno = symbol - ntokens + nstates;
 
 
-  m = goto_map[symbol];
-  n = goto_map[symbol + 1];
+  short begin = goto_map[symbol];
+  short end = goto_map[symbol + 1];
 
   count = 0;
 
   count = 0;
-  for (i = m; i < n; i++)
-    {
-      if (to_state[i] != default_state)
-       count++;
-    }
+  for (i = begin; i < end; i++)
+    if (to_state[i] != default_state)
+      count++;
 
   if (count == 0)
     return;
 
 
   if (count == 0)
     return;
 
-  symno = symbol - ntokens + nstates;
-
   froms[symno] = sp1 = sp = XCALLOC (short, count);
   tos[symno] = sp2 = XCALLOC (short, count);
 
   froms[symno] = sp1 = sp = XCALLOC (short, count);
   tos[symno] = sp2 = XCALLOC (short, count);
 
-  for (i = m; i < n; i++)
-    {
-      if (to_state[i] != default_state)
-       {
-         *sp1++ = from_state[i];
-         *sp2++ = to_state[i];
-       }
-    }
+  for (i = begin; i < end; i++)
+    if (to_state[i] != default_state)
+      {
+       *sp1++ = from_state[i];
+       *sp2++ = to_state[i];
+      }
 
   tally[symno] = count;
   width[symno] = sp1[-1] - sp[0] + 1;
 
   tally[symno] = count;
   width[symno] = sp1[-1] - sp[0] + 1;
@@ -808,13 +600,10 @@ static int
 default_goto (int symbol)
 {
   int i;
 default_goto (int symbol)
 {
   int i;
-  int m;
-  int n;
-  int default_state;
-  int max;
-
-  m = goto_map[symbol];
-  n = goto_map[symbol + 1];
+  int m = goto_map[symbol];
+  int n = goto_map[symbol + 1];
+  int default_state = -1;
+  int max = 0;
 
   if (m == n)
     return -1;
 
   if (m == n)
     return -1;
@@ -825,17 +614,12 @@ default_goto (int symbol)
   for (i = m; i < n; i++)
     state_count[to_state[i]]++;
 
   for (i = m; i < n; i++)
     state_count[to_state[i]]++;
 
-  max = 0;
-  default_state = -1;
-
   for (i = 0; i < nstates; i++)
   for (i = 0; i < nstates; i++)
-    {
-      if (state_count[i] > max)
-       {
-         max = state_count[i];
-         default_state = i;
-       }
-    }
+    if (state_count[i] > max)
+      {
+       max = state_count[i];
+       default_state = i;
+      }
 
   return default_state;
 }
 
   return default_state;
 }
@@ -853,36 +637,23 @@ default_goto (int symbol)
 static void
 goto_actions (void)
 {
 static void
 goto_actions (void)
 {
-  int i, j, k;
+  int i;
+  short *yydefgoto = XMALLOC (short, nsyms - ntokens);
 
   state_count = XCALLOC (short, nstates);
 
   state_count = XCALLOC (short, nstates);
-
-  k = default_goto (ntokens);
-  fprintf (ftable, "\nstatic const short yydefgoto[] = {%6d", k);
-  save_column (ntokens, k);
-
-  j = 10;
-  for (i = ntokens + 1; i < nsyms; i++)
+  for (i = ntokens; i < nsyms; ++i)
     {
     {
-      putc (',', ftable);
-
-      if (j >= 10)
-       {
-         putc ('\n', ftable);
-         j = 1;
-       }
-      else
-       {
-         j++;
-       }
-
-      k = default_goto (i);
-      fprintf (ftable, "%6d", k);
-      save_column (i, k);
+      int default_state = default_goto (i);
+      save_column (i, default_state);
+      yydefgoto[i - ntokens] = default_state;
     }
 
     }
 
-  fprintf (ftable, "\n};\n");
+  output_table_data (&format_obstack, yydefgoto,
+                    yydefgoto[0], 1, nsyms - ntokens);
+  muscle_insert ("defgoto", obstack_finish (&format_obstack));
+
   XFREE (state_count);
   XFREE (state_count);
+  XFREE (yydefgoto);
 }
 
 
 }
 
 
@@ -893,50 +664,41 @@ static void
 sort_actions (void)
 {
   int i;
 sort_actions (void)
 {
   int i;
-  int j;
-  int k;
-  int t;
-  int w;
 
   order = XCALLOC (short, nvectors);
   nentries = 0;
 
   for (i = 0; i < nvectors; i++)
 
   order = XCALLOC (short, nvectors);
   nentries = 0;
 
   for (i = 0; i < nvectors; i++)
-    {
-      if (tally[i] > 0)
-       {
-         t = tally[i];
-         w = width[i];
-         j = nentries - 1;
+    if (tally[i] > 0)
+      {
+       int k;
+       int t = tally[i];
+       int w = width[i];
+       int j = nentries - 1;
 
 
-         while (j >= 0 && (width[order[j]] < w))
-           j--;
+       while (j >= 0 && (width[order[j]] < w))
+         j--;
 
 
-         while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
-           j--;
+       while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
+         j--;
 
 
-         for (k = nentries - 1; k > j; k--)
-           order[k + 1] = order[k];
+       for (k = nentries - 1; k > j; k--)
+         order[k + 1] = order[k];
 
 
-         order[j + 1] = i;
-         nentries++;
-       }
-    }
+       order[j + 1] = i;
+       nentries++;
+      }
 }
 
 
 static int
 matching_state (int vector)
 {
 }
 
 
 static int
 matching_state (int vector)
 {
-  int i;
-  int j;
-  int k;
+  int i = order[vector];
   int t;
   int w;
   int t;
   int w;
-  int match;
   int prev;
 
   int prev;
 
-  i = order[vector];
   if (i >= nstates)
     return -1;
 
   if (i >= nstates)
     return -1;
 
@@ -945,16 +707,16 @@ matching_state (int vector)
 
   for (prev = vector - 1; prev >= 0; prev--)
     {
 
   for (prev = vector - 1; prev >= 0; prev--)
     {
-      j = order[prev];
+      int j = order[prev];
+      int k;
+      int match = 1;
+
       if (width[j] != w || tally[j] != t)
        return -1;
 
       if (width[j] != w || tally[j] != t)
        return -1;
 
-      match = 1;
       for (k = 0; match && k < t; k++)
       for (k = 0; match && k < t; k++)
-       {
-         if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
-           match = 0;
-       }
+       if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
+         match = 0;
 
       if (match)
        return j;
 
       if (match)
        return j;
@@ -967,26 +729,19 @@ matching_state (int vector)
 static int
 pack_vector (int vector)
 {
 static int
 pack_vector (int vector)
 {
-  int i;
+  int i = order[vector];
   int j;
   int j;
-  int k;
-  int t;
+  int t = tally[i];
   int loc = 0;
   int loc = 0;
-  int ok;
-  short *from;
-  short *to;
-
-  i = order[vector];
-  t = tally[i];
+  short *from = froms[i];
+  short *to = tos[i];
 
   assert (t);
 
 
   assert (t);
 
-  from = froms[i];
-  to = tos[i];
-
   for (j = lowzero - from[0]; j < MAXTABLE; j++)
     {
   for (j = lowzero - from[0]; j < MAXTABLE; j++)
     {
-      ok = 1;
+      int k;
+      int ok = 1;
 
       for (k = 0; ok && k < t; k++)
        {
 
       for (k = 0; ok && k < t; k++)
        {
@@ -999,10 +754,8 @@ pack_vector (int vector)
        }
 
       for (k = 0; ok && k < vector; k++)
        }
 
       for (k = 0; ok && k < vector; k++)
-       {
-         if (pos[k] == j)
-           ok = 0;
-       }
+       if (pos[k] == j)
+         ok = 0;
 
       if (ok)
        {
 
       if (ok)
        {
@@ -1022,9 +775,9 @@ pack_vector (int vector)
          return j;
        }
     }
          return j;
        }
     }
-
-  berror ("pack_vector");
-  return 0;                    /* JF keep lint happy */
+#define pack_vector_succeeded 0
+  assert (pack_vector_succeeded);
+  return 0;
 }
 
 
 }
 
 
@@ -1064,10 +817,8 @@ pack_table (void)
 
   for (i = 0; i < nvectors; i++)
     {
 
   for (i = 0; i < nvectors; i++)
     {
-      if (froms[i])
-       XFREE (froms[i]);
-      if (tos[i])
-       XFREE (tos[i]);
+      XFREE (froms[i]);
+      XFREE (tos[i]);
     }
 
   XFREE (froms);
     }
 
   XFREE (froms);
@@ -1081,13 +832,15 @@ pack_table (void)
 static void
 output_base (void)
 {
 static void
 output_base (void)
 {
-  output_short_table (ftable, NULL, "yypact", base,
-                     base[0], 1, nstates);
-
-  putc ('\n', ftable);
+  /* Output pact. */
+  output_table_data (&format_obstack, base,
+                    base[0], 1, nstates);
+  muscle_insert ("pact", obstack_finish (&format_obstack));
 
 
-  output_short_table (ftable, NULL, "yypgoto", base,
-                     base[nstates], nstates + 1, nvectors);
+  /* Output pgoto. */
+  output_table_data (&format_obstack, base,
+                    base[nstates], nstates + 1, nvectors);
+  muscle_insert ("pgoto", obstack_finish (&format_obstack));
 
   XFREE (base);
 }
 
   XFREE (base);
 }
@@ -1096,9 +849,9 @@ output_base (void)
 static void
 output_table (void)
 {
 static void
 output_table (void)
 {
-  fprintf (ftable, "\n\n#define\tYYLAST\t\t%d\n\n\n", high);
-  output_short_table (ftable, NULL, "yytable", table,
-                     table[0], 1, high + 1);
+  output_table_data (&format_obstack, table,
+                    table[0], 1, high + 1);
+  muscle_insert ("table", obstack_finish (&format_obstack));
   XFREE (table);
 }
 
   XFREE (table);
 }
 
@@ -1106,8 +859,9 @@ output_table (void)
 static void
 output_check (void)
 {
 static void
 output_check (void)
 {
-  output_short_table (ftable, NULL, "yycheck", check,
-                     check[0], 1, high + 1);
+  output_table_data (&format_obstack, check,
+                    check[0], 1, high + 1);
+  muscle_insert ("check", obstack_finish (&format_obstack));
   XFREE (check);
 }
 
   XFREE (check);
 }
 
@@ -1117,6 +871,7 @@ output_check (void)
 static void
 output_actions (void)
 {
 static void
 output_actions (void)
 {
+  int i;
   nvectors = nstates + nvars;
 
   froms = XCALLOC (short *, nvectors);
   nvectors = nstates + nvars;
 
   froms = XCALLOC (short *, nvectors);
@@ -1125,12 +880,8 @@ output_actions (void)
   width = XCALLOC (short, nvectors);
 
   token_actions ();
   width = XCALLOC (short, nvectors);
 
   token_actions ();
-  free_shifts ();
-  free_reductions ();
-  XFREE (lookaheads);
   XFREE (LA);
   XFREE (LAruleno);
   XFREE (LA);
   XFREE (LAruleno);
-  XFREE (accessing_symbol);
 
   goto_actions ();
   XFREE (goto_map + ntokens);
 
   goto_actions ();
   XFREE (goto_map + ntokens);
@@ -1139,131 +890,200 @@ output_actions (void)
 
   sort_actions ();
   pack_table ();
 
   sort_actions ();
   pack_table ();
-  putc ('\n', ftable);
+
   output_base ();
   output_table ();
   output_base ();
   output_table ();
-  putc ('\n', ftable);
+
   output_check ();
   output_check ();
+
+  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]);
+    }
+  XFREE (state_table);
 }
 
 }
 
-/* copy the parser code into the ftable file at the end.  */
+\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, FILE *out)
 {
   int c;
 {
   int c;
-  static int number_of_dollar_signs = 0;
-#ifdef DONTDEF
-  FILE *fpars;
-#else
-#define fpars fparser
-#endif
+  FILE *fskel;
+  size_t output_line;
+  size_t skeleton_line;
 
 
-  if (pure_parser)
-    fprintf (ftable, "#define YYPURE 1\n\n");
+  fskel = xfopen (skel_filename, "r");
 
 
-#ifdef DONTDEF
-  /* JF no longer needed 'cuz open_extra_files changes the currently
-     open parser from bison.simple to bison.hairy */
-  if (semantic_parser)
-    fpars = fparser;
-  else
-    fpars = fparser1;
-#endif
-
-  /* Loop over lines in the standard parser file.  */
-
-  while (1)
+  /* New output code.  */
+  output_line = 1;
+  skeleton_line = 1;
+  c = getc (fskel);
+  while (c != EOF)
     {
     {
-      int write_line = 1;
-
-      c = getc (fpars);
-
-      /* See if the line starts with `#line.
-         If so, set write_line to 0.  */
-      if (no_lines_flag)
-       if (c == '#')
-         {
-           c = getc (fpars);
-           if (c == 'l')
-             {
-               c = getc (fpars);
-               if (c == 'i')
-                 {
-                   c = getc (fpars);
-                   if (c == 'n')
-                     {
-                       c = getc (fpars);
-                       if (c == 'e')
-                         write_line = 0;
-                       else
-                         fprintf (ftable, "#lin");
-                     }
-                   else
-                     fprintf (ftable, "#li");
-                 }
-               else
-                 fprintf (ftable, "#l");
-             }
-           else
-             fprintf (ftable, "#");
-         }
-
-      /* now write out the line... */
-      for (; c != '\n' && c != EOF; c = getc (fpars))
-       if (write_line)
-         {
-           if (c == '$')
-             {
-               number_of_dollar_signs++;
-               assert (number_of_dollar_signs == 1);
-               /* `$' in the parser file indicates where to put the actions.
-                  Copy them in at this point.  */
-               rewind (faction);
-               for (c = getc (faction); c != EOF; c = getc (faction))
-                 putc (c, ftable);
-               /* Skip the end of the line containing `$'. */
-               write_line = 0;
-             }
-           else
-             putc (c, ftable);
-         }
-      if (c == EOF)
-       break;
-      putc (c, ftable);
+      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);
     }
     }
-  assert (number_of_dollar_signs == 1);
+
+  /* End.  */
+  xfclose (fskel);
 }
 
 }
 
+/*----------------------------------------.
+| Prepare the master parser to be output  |
+`----------------------------------------*/
+
 static void
 static void
-output_program (void)
+output_master_parser (void)
 {
 {
-  int c;
-
-  if (!no_lines_flag)
-    fprintf (ftable, "#line %d \"%s\"\n", lineno, infile);
-
-  c = getc (finput);
-  while (c != EOF)
+  FILE *parser = xfopen (parser_file_name, "w");
+  if (!skeleton)
     {
     {
-      putc (c, ftable);
-      c = getc (finput);
+      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));       \
 }
 
 }
 
+#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 ("error-verbose", error_verbose);
+  MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
+
+  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);
+}
 
 
-  XFREE (state_table);
 
 
-  for (cp = first_state; cp; cp = cptmp)
+/*-------------------------.
+| Output the header file.  |
+`-------------------------*/
+
+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)
     {
     {
-      cptmp = cp->next;
-      XFREE (cp);
+      int i;
+
+      for (i = ntokens; i < nsyms; i++)
+       /* don't make these for dummy nonterminals made by gensym.  */
+       if (*tags[i] != '@')
+         fprintf (out, "# define NT%s\t%d\n", tags[i], i);
     }
     }
+
+  fprintf (out, "\n#endif /* not %s */\n", macro_name);
+  free (macro_name);
+  xfclose (out);
 }
 
 
 }
 
 
@@ -1274,52 +1094,32 @@ free_itemsets (void)
 void
 output (void)
 {
 void
 output (void)
 {
-  int c;
-
-  /* output_token_defines(ftable);      / * JF put out token defines FIRST */
-  if (!semantic_parser)                /* JF Put out other stuff */
-    {
-      rewind (fattrs);
-      while ((c = getc (fattrs)) != EOF)
-       putc (c, ftable);
-    }
-  reader_output_yylsp (ftable);
-  if (debug_flag)
-    fputs ("\
-#ifndef YYDEBUG\n\
-# define YYDEBUG 1\n\
-#endif\n\
-\n",
-          ftable);
+  obstack_init (&format_obstack);
 
 
-  if (semantic_parser)
-    fprintf (ftable, "#include \"%s\"\n", attrsfile);
-
-  if (!no_parser_flag)
-    fprintf (ftable, "#include <stdio.h>\n\n");
-
-  /* Make "const" do nothing if not in ANSI C.  */
-  fputs ("\
-#ifndef __cplusplus\n\
-# ifndef __STDC__\n\
-#  define const\n\
-# endif\n\
-#endif\n\
-\n",
-        ftable);
-
-  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 ();
+
+  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 ();
+
+  free (rule_table + 1);
+  obstack_free (&muscle_obstack, NULL);
+  obstack_free (&format_obstack, NULL);
+  obstack_free (&action_obstack, NULL);
+  obstack_free (&attrs_obstack, NULL);
 }
 }