]>
git.saurik.com Git - bison.git/blob - src/output.c
1 /* Output the generated parsing program for bison,
2 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of Bison, the GNU Compiler Compiler.
7 Bison is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 Bison is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bison; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 /* The parser tables consist of these tables. Marked ones needed only
24 for the semantic parser. Double marked are output only if switches
27 YYTRANSLATE = vector mapping yylex's token numbers into bison's
30 ++ YYTNAME = vector of string-names indexed by bison token number.
32 ++ YYTOKNUM = vector of yylex token numbers corresponding to
35 YYRLINE = vector of line-numbers of all rules. For yydebug
38 YYRHS = vector of items of all rules. This is exactly what RITEMS
39 contains. For yydebug and for semantic parser.
41 YYPRHS[R] = index in YYRHS of first item for rule R.
43 YYR1[R] = symbol number of symbol that rule R derives.
45 YYR2[R] = number of symbols composing right hand side of rule R.
47 + YYSTOS[S] = the symbol number of the symbol that leads to state
50 YYDEFACT[S] = default rule to reduce with in state s, when YYTABLE
51 doesn't specify something else to do. Zero means the default is an
54 YYDEFGOTO[I] = default state to go to after a reduction of a rule
55 that generates variable NTOKENS + I, except when YYTABLE specifies
58 YYPACT[S] = index in YYTABLE of the portion describing state S.
59 The lookahead token's type is used to index that portion to find
62 If the value in YYTABLE is positive, we shift the token and go to
65 If the value is negative, it is minus a rule number to reduce by.
67 If the value is zero, the default action from YYDEFACT[S] is used.
69 YYPGOTO[I] = the index in YYTABLE of the portion describing what to
70 do after reducing a rule that derives variable I + NTOKENS. This
71 portion is indexed by the parser state number, S, as of before the
72 text for this nonterminal was read. The value from YYTABLE is the
73 state to go to if the corresponding value in YYCHECK is S.
75 YYTABLE = a vector filled with portions for different uses, found
76 via YYPACT and YYPGOTO.
78 YYCHECK = a vector indexed in parallel with YYTABLE. It indicates,
79 in a roundabout way, the bounds of the portion you are trying to
82 Suppose that the portion of yytable starts at index P and the index
83 to be examined within the portion is I. Then if YYCHECK[P+I] != I,
84 I is outside the bounds of what is actually allocated, and the
85 default (from YYDEFACT or YYDEFGOTO) should be used. Otherwise,
86 YYTABLE[P+I] should be used.
88 YYFINAL = the state number of the termination state. YYFLAG = most
89 negative short int. Used to flag ?? */
104 #include "conflicts.h"
105 #include "muscle_tab.h"
107 /* From lib/readpipe.h. */
108 FILE *readpipe
PARAMS ((const char *, ...));
110 /* From src/scan-skel.l. */
111 int skel_lex
PARAMS ((void));
112 extern FILE *skel_in
;
116 static short **froms
= NULL
;
117 static short **tos
= NULL
;
118 static short *tally
= NULL
;
119 static short *width
= NULL
;
120 static short *actrow
= NULL
;
121 static short *state_count
= NULL
;
122 static short *order
= NULL
;
123 static short *base
= NULL
;
124 static short *pos
= NULL
;
125 static short *table
= NULL
;
126 static short *check
= NULL
;
130 struct obstack muscle_obstack
;
131 static struct obstack format_obstack
;
133 int error_verbose
= 0;
135 /* Returns the number of lines of S. */
137 get_lines_number (const char *s
)
142 for (i
= 0; s
[i
]; ++i
)
153 output_table_data (struct obstack
*oout
,
162 obstack_fgrow1 (oout
, "%6d", first
);
163 for (i
= begin
; i
< end
; ++i
)
165 obstack_1grow (oout
, ',');
168 obstack_sgrow (oout
, "\n ");
173 obstack_fgrow1 (oout
, "%6d", table_data
[i
]);
175 obstack_1grow (oout
, 0);
179 /*-----------------------------------------------------------------.
180 | Prepare the muscles related to the tokens: translate, tname, and |
182 `-----------------------------------------------------------------*/
185 prepare_tokens (void)
187 output_table_data (&format_obstack
, token_translations
,
188 0, 1, max_user_token_number
+ 1);
189 muscle_insert ("translate", obstack_finish (&format_obstack
));
190 XFREE (token_translations
);
195 for (i
= 0; i
< nsyms
; i
++)
197 /* Be sure not to use twice the same quotearg slot. */
199 quotearg_n_style (1, c_quoting_style
,
200 quotearg_style (escape_quoting_style
,
202 /* Width of the next token, including the two quotes, the coma
204 int strsize
= strlen (cp
) + 2;
206 if (j
+ strsize
> 75)
208 obstack_sgrow (&format_obstack
, "\n ");
212 obstack_sgrow (&format_obstack
, cp
);
213 obstack_sgrow (&format_obstack
, ", ");
216 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
218 obstack_sgrow (&format_obstack
, "0");
220 /* Finish table and store. */
221 obstack_1grow (&format_obstack
, 0);
222 muscle_insert ("tname", obstack_finish (&format_obstack
));
225 /* Output YYTOKNUM. */
228 short *values
= XCALLOC (short, ntokens
+ 1);
229 for (i
= 0; i
< ntokens
+ 1; ++i
)
230 values
[i
] = symbols
[i
]->user_token_number
;
231 output_table_data (&format_obstack
, values
,
233 muscle_insert ("toknum", obstack_finish (&format_obstack
));
239 /*-------------------------------------------------------------.
240 | Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
242 `-------------------------------------------------------------*/
250 short *rhs
= XMALLOC (short, nritems
);
251 short *prhs
= XMALLOC (short, nrules
+ 1);
252 short *r1
= XMALLOC (short, nrules
+ 1);
253 short *r2
= XMALLOC (short, nrules
+ 1);
254 short *rline
= XMALLOC (short, nrules
+ 1);
256 for (r
= 1; r
< nrules
+ 1; ++r
)
258 /* Index of rule R in RHS. */
260 /* RHS of the rule R. */
261 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; ++rhsp
)
263 /* LHS of the rule R. */
264 r1
[r
] = rules
[r
].lhs
->number
;
265 /* Length of rule R's RHS. */
267 /* Separator in RHS. */
269 /* Line where rule was defined. */
270 rline
[r
] = rules
[r
].line
;
272 assert (i
== nritems
);
274 output_table_data (&format_obstack
, rhs
, ritem
[0], 1, nritems
);
275 muscle_insert ("rhs", obstack_finish (&format_obstack
));
277 output_table_data (&format_obstack
, prhs
, 0, 1, nrules
+ 1);
278 muscle_insert ("prhs", obstack_finish (&format_obstack
));
280 output_table_data (&format_obstack
, rline
, 0, 1, nrules
+ 1);
281 muscle_insert ("rline", obstack_finish (&format_obstack
));
283 output_table_data (&format_obstack
, r1
, 0, 1, nrules
+ 1);
284 muscle_insert ("r1", obstack_finish (&format_obstack
));
286 output_table_data (&format_obstack
, r2
, 0, 1, nrules
+ 1);
287 muscle_insert ("r2", obstack_finish (&format_obstack
));
294 /*--------------------------------------------.
295 | Prepare the muscles related to the states. |
296 `--------------------------------------------*/
299 prepare_states (void)
302 short *values
= (short *) alloca (sizeof (short) * nstates
);
303 for (i
= 0; i
< nstates
; ++i
)
304 values
[i
] = states
[i
]->accessing_symbol
;
305 output_table_data (&format_obstack
, values
,
307 muscle_insert ("stos", obstack_finish (&format_obstack
));
311 /*------------------------------------------------------------------.
312 | Decide what to do for each type of token if seen as the lookahead |
313 | token in specified state. The value returned is used as the |
314 | default action (yydefact) for the state. In addition, actrow is |
315 | filled with what to do for each kind of token, index by symbol |
316 | number, with zero meaning do the default action. The value |
317 | MINSHORT, a very negative number, means this situation is an |
318 | error. The parser recognizes this value specially. |
320 | This is where conflicts are resolved. The loop over lookahead |
321 | rules considered lower-numbered rules last, and the last rule |
322 | considered that likes a token gets to handle it. |
323 `------------------------------------------------------------------*/
326 action_row (state_t
*state
)
329 int default_rule
= 0;
330 reductions
*redp
= state
->reductions
;
331 shifts
*shiftp
= state
->shifts
;
332 errs
*errp
= state
->errs
;
333 /* set nonzero to inhibit having any default reduction */
336 for (i
= 0; i
< ntokens
; i
++)
339 if (redp
->nreds
>= 1)
342 /* loop over all the rules available here which require
344 for (i
= state
->nlookaheads
- 1; i
>= 0; --i
)
345 /* and find each token which the rule finds acceptable
347 for (j
= 0; j
< ntokens
; j
++)
348 /* and record this rule as the rule to use if that
350 if (bitset_test (LA
[state
->lookaheadsp
+ i
], j
))
351 actrow
[j
] = -LAruleno
[state
->lookaheadsp
+ i
];
354 /* Now see which tokens are allowed for shifts in this state. For
355 them, record the shift as the thing to do. So shift is preferred
357 for (i
= 0; i
< shiftp
->nshifts
; i
++)
360 int shift_state
= shiftp
->shifts
[i
];
364 symbol
= states
[shift_state
]->accessing_symbol
;
369 actrow
[symbol
] = shift_state
;
371 /* Do not use any default reduction if there is a shift for
373 if (symbol
== error_token_number
)
377 /* See which tokens are an explicit error in this state (due to
378 %nonassoc). For them, record MINSHORT as the action. */
379 for (i
= 0; i
< errp
->nerrs
; i
++)
381 int symbol
= errp
->errs
[i
];
382 actrow
[symbol
] = MINSHORT
;
385 /* Now find the most common reduction and make it the default action
388 if (redp
->nreds
>= 1 && !nodefault
)
390 if (state
->consistent
)
391 default_rule
= redp
->rules
[0];
395 for (i
= 0; i
< state
->nlookaheads
; i
++)
398 int rule
= -LAruleno
[state
->lookaheadsp
+ i
];
401 for (j
= 0; j
< ntokens
; j
++)
402 if (actrow
[j
] == rule
)
412 /* actions which match the default are replaced with zero,
413 which means "use the default" */
418 for (j
= 0; j
< ntokens
; j
++)
419 if (actrow
[j
] == default_rule
)
422 default_rule
= -default_rule
;
427 /* If have no default rule, the default is an error.
428 So replace any action which says "error" with "use default". */
430 if (default_rule
== 0)
431 for (i
= 0; i
< ntokens
; i
++)
432 if (actrow
[i
] == MINSHORT
)
449 for (i
= 0; i
< ntokens
; i
++)
456 froms
[state
] = sp1
= sp
= XCALLOC (short, count
);
457 tos
[state
] = sp2
= XCALLOC (short, count
);
459 for (i
= 0; i
< ntokens
; i
++)
466 tally
[state
] = count
;
467 width
[state
] = sp1
[-1] - sp
[0] + 1;
471 /*------------------------------------------------------------------.
472 | Figure out the actions for the specified state, indexed by |
473 | lookahead token type. |
475 | The YYDEFACT table is output now. The detailed info is saved for |
476 | putting into YYTABLE later. |
477 `------------------------------------------------------------------*/
483 short *yydefact
= XCALLOC (short, nstates
);
485 actrow
= XCALLOC (short, ntokens
);
486 for (i
= 0; i
< nstates
; ++i
)
488 yydefact
[i
] = action_row (states
[i
]);
492 output_table_data (&format_obstack
, yydefact
,
493 yydefact
[0], 1, nstates
);
494 muscle_insert ("defact", obstack_finish (&format_obstack
));
501 /*-----------------------------.
502 | Output the actions to OOUT. |
503 `-----------------------------*/
506 actions_output (FILE *out
)
509 for (rule
= 1; rule
< nrules
+ 1; ++rule
)
510 if (rules
[rule
].action
)
512 fprintf (out
, " case %d:\n", rule
);
515 fprintf (out
, muscle_find ("linef"),
516 rules
[rule
].action_line
,
517 quotearg_style (c_quoting_style
,
518 muscle_find ("filename")));
519 /* As a Bison extension, add the ending semicolon. Since some
520 Yacc don't do that, help people using bison as a Yacc
521 finding their missing semicolons. */
522 fprintf (out
, "{ %s%s }\n break;\n\n",
524 yacc_flag
? ";" : "");
529 /*----------------------------.
530 | Output the guards to OOUT. |
531 `----------------------------*/
534 guards_output (FILE *out
)
537 for (rule
= 1; rule
< nrules
+ 1; ++rule
)
538 if (rules
[rule
].guard
)
540 fprintf (out
, " case %d:\n", rule
);
543 fprintf (out
, muscle_find ("linef"),
544 rules
[rule
].guard_line
,
545 quotearg_style (c_quoting_style
,
546 muscle_find ("filename")));
547 fprintf (out
, "{ %s; }\n break;\n\n",
553 /*---------------------------------------.
554 | Output the tokens definition to OOUT. |
555 `---------------------------------------*/
558 token_definitions_output (FILE *out
)
562 for (i
= 0; i
< ntokens
; ++i
)
564 bucket
*symbol
= symbols
[i
];
565 int number
= symbol
->user_token_number
;
567 if (number
== SALIAS
)
569 /* Skip error token. */
570 if (symbol
->number
== error_token_number
)
572 if (symbol
->tag
[0] == '\'')
573 continue; /* skip literal character */
574 if (symbol
->tag
[0] == '\"')
576 /* use literal string only if given a symbol with an alias */
578 symbol
= symbol
->alias
;
583 /* Don't #define nonliteral tokens whose names contain periods
584 or '$' (as does the default value of the EOF token). */
585 if (strchr (symbol
->tag
, '.') || strchr (symbol
->tag
, '$'))
588 fprintf (out
, "%s [[[%s]], [%d]]",
589 first
? "" : ",\n", symbol
->tag
, number
);
591 /* FIXME: This is probably wrong, and should be just as
593 fprintf (out
, "# define T%s\t%d\n", symbol
->tag
, symbol
->number
);
600 save_column (int symbol
, int default_state
)
607 int symno
= symbol
- ntokens
+ nstates
;
609 short begin
= goto_map
[symbol
];
610 short end
= goto_map
[symbol
+ 1];
613 for (i
= begin
; i
< end
; i
++)
614 if (to_state
[i
] != default_state
)
620 froms
[symno
] = sp1
= sp
= XCALLOC (short, count
);
621 tos
[symno
] = sp2
= XCALLOC (short, count
);
623 for (i
= begin
; i
< end
; i
++)
624 if (to_state
[i
] != default_state
)
626 *sp1
++ = from_state
[i
];
627 *sp2
++ = to_state
[i
];
630 tally
[symno
] = count
;
631 width
[symno
] = sp1
[-1] - sp
[0] + 1;
635 default_goto (int symbol
)
638 size_t m
= goto_map
[symbol
];
639 size_t n
= goto_map
[symbol
+ 1];
640 int default_state
= -1;
646 for (i
= 0; i
< nstates
; i
++)
649 for (i
= m
; i
< n
; i
++)
650 state_count
[to_state
[i
]]++;
652 for (i
= 0; i
< nstates
; i
++)
653 if (state_count
[i
] > max
)
655 max
= state_count
[i
];
659 return default_state
;
663 /*-------------------------------------------------------------------.
664 | Figure out what to do after reducing with each rule, depending on |
665 | the saved state from before the beginning of parsing the data that |
666 | matched this rule. |
668 | The YYDEFGOTO table is output now. The detailed info is saved for |
669 | putting into YYTABLE later. |
670 `-------------------------------------------------------------------*/
676 short *yydefgoto
= XMALLOC (short, nsyms
- ntokens
);
678 state_count
= XCALLOC (short, nstates
);
679 for (i
= ntokens
; i
< nsyms
; ++i
)
681 int default_state
= default_goto (i
);
682 save_column (i
, default_state
);
683 yydefgoto
[i
- ntokens
] = default_state
;
686 output_table_data (&format_obstack
, yydefgoto
,
687 yydefgoto
[0], 1, nsyms
- ntokens
);
688 muscle_insert ("defgoto", obstack_finish (&format_obstack
));
695 /* The next few functions decide how to pack the actions and gotos
696 information into yytable. */
703 order
= XCALLOC (short, nvectors
);
706 for (i
= 0; i
< nvectors
; i
++)
712 int j
= nentries
- 1;
714 while (j
>= 0 && (width
[order
[j
]] < w
))
717 while (j
>= 0 && (width
[order
[j
]] == w
) && (tally
[order
[j
]] < t
))
720 for (k
= nentries
- 1; k
> j
; k
--)
721 order
[k
+ 1] = order
[k
];
730 matching_state (int vector
)
732 int i
= order
[vector
];
737 if (i
>= (int) nstates
)
743 for (prev
= vector
- 1; prev
>= 0; prev
--)
749 if (width
[j
] != w
|| tally
[j
] != t
)
752 for (k
= 0; match
&& k
< t
; k
++)
753 if (tos
[j
][k
] != tos
[i
][k
] || froms
[j
][k
] != froms
[i
][k
])
765 pack_vector (int vector
)
767 int i
= order
[vector
];
771 short *from
= froms
[i
];
776 for (j
= lowzero
- from
[0]; j
< MAXTABLE
; j
++)
781 for (k
= 0; ok
&& k
< t
; k
++)
785 fatal (_("maximum table size (%d) exceeded"), MAXTABLE
);
791 for (k
= 0; ok
&& k
< vector
; k
++)
797 for (k
= 0; k
< t
; k
++)
801 check
[loc
] = from
[k
];
804 while (table
[lowzero
] != 0)
813 #define pack_vector_succeeded 0
814 assert (pack_vector_succeeded
);
826 base
= XCALLOC (short, nvectors
);
827 pos
= XCALLOC (short, nentries
);
828 table
= XCALLOC (short, MAXTABLE
);
829 check
= XCALLOC (short, MAXTABLE
);
834 for (i
= 0; i
< nvectors
; i
++)
837 for (i
= 0; i
< MAXTABLE
; i
++)
840 for (i
= 0; i
< nentries
; i
++)
842 state
= matching_state (i
);
845 place
= pack_vector (i
);
850 base
[order
[i
]] = place
;
853 for (i
= 0; i
< nvectors
; i
++)
864 /* the following functions output yytable, yycheck
865 and the vectors whose elements index the portion starts */
871 output_table_data (&format_obstack
, base
,
872 base
[0], 1, nstates
);
873 muscle_insert ("pact", obstack_finish (&format_obstack
));
876 output_table_data (&format_obstack
, base
,
877 base
[nstates
], nstates
+ 1, nvectors
);
878 muscle_insert ("pgoto", obstack_finish (&format_obstack
));
887 output_table_data (&format_obstack
, table
,
888 table
[0], 1, high
+ 1);
889 muscle_insert ("table", obstack_finish (&format_obstack
));
897 output_table_data (&format_obstack
, check
,
898 check
[0], 1, high
+ 1);
899 muscle_insert ("check", obstack_finish (&format_obstack
));
903 /*-----------------------------------------------------------------.
904 | Compute and output yydefact, yydefgoto, yypact, yypgoto, yytable |
906 `-----------------------------------------------------------------*/
909 output_actions (void)
912 nvectors
= nstates
+ nvars
;
914 froms
= XCALLOC (short *, nvectors
);
915 tos
= XCALLOC (short *, nvectors
);
916 tally
= XCALLOC (short, nvectors
);
917 width
= XCALLOC (short, nvectors
);
924 XFREE (goto_map
+ ntokens
);
936 for (i
= 0; i
< nstates
; ++i
)
938 free (states
[i
]->shifts
);
939 XFREE (states
[i
]->reductions
);
940 free (states
[i
]->errs
);
947 /*---------------------------.
948 | Call the skeleton parser. |
949 `---------------------------*/
952 output_skeleton (void)
954 /* Store the definition of all the muscles. */
955 const char *tempdir
= getenv ("TMPDIR");
956 char *tempfile
= NULL
;
961 tempdir
= DEFAULT_TMPDIR
;
962 tempfile
= xmalloc (strlen (tempdir
) + 11);
963 sprintf (tempfile
, "%s/bsnXXXXXX", tempdir
);
964 fd
= mkstemp (tempfile
);
966 error (EXIT_FAILURE
, errno
, "%s", tempfile
);
968 out
= fdopen (fd
, "w");
970 error (EXIT_FAILURE
, errno
, "%s", tempfile
);
972 /* There are no comments, especially not `#': we do want M4 expansion
973 after `#': think of CPP macros! */
974 fputs ("m4_changecom()\n", out
);
975 fputs ("m4_init()\n", out
);
977 fputs ("m4_define([b4_actions], \n[[", out
);
978 actions_output (out
);
979 fputs ("]])\n\n", out
);
981 fputs ("m4_define([b4_guards], \n[[", out
);
983 fputs ("]])\n\n", out
);
985 fputs ("m4_define([b4_tokens], \n[", out
);
986 token_definitions_output (out
);
987 fputs ("])\n\n", out
);
989 muscles_m4_output (out
);
991 fputs ("m4_wrap([m4_divert_pop(0)])\n", out
);
992 fputs ("m4_divert_push(0)dnl\n", out
);
995 /* Invoke m4 on the definition of the muscles, and the skeleton. */
997 const char *bison_pkgdatadir
= getenv ("BISON_PKGDATADIR");
998 const char *m4
= getenv ("M4");
1001 if (!bison_pkgdatadir
)
1002 bison_pkgdatadir
= PKGDATADIR
;
1005 "running: %s -I %s m4sugar/m4sugar.m4 %s %s\n",
1006 m4
, bison_pkgdatadir
, tempfile
, skeleton
);
1007 skel_in
= readpipe (m4
,
1008 "-I", bison_pkgdatadir
,
1009 "m4sugar/m4sugar.m4",
1014 error (EXIT_FAILURE
, errno
, "cannot run m4");
1017 /* If `debugging', keep this file alive. */
1026 MUSCLE_INSERT_INT ("last", high
);
1027 MUSCLE_INSERT_INT ("flag", MINSHORT
);
1028 MUSCLE_INSERT_INT ("pure", pure_parser
);
1029 MUSCLE_INSERT_INT ("nsym", nsyms
);
1030 MUSCLE_INSERT_INT ("debug", debug_flag
);
1031 MUSCLE_INSERT_INT ("final", final_state
);
1032 MUSCLE_INSERT_INT ("maxtok", max_user_token_number
);
1033 MUSCLE_INSERT_INT ("error_verbose", error_verbose
);
1034 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix
? spec_name_prefix
: "yy");
1036 /* FIXME: This is wrong: the muscles should decide whether they hold
1037 a copy or not, but the situation is too obscure currently. */
1038 MUSCLE_INSERT_STRING ("output_infix", output_infix
? output_infix
: "");
1039 MUSCLE_INSERT_STRING ("output_prefix", short_base_name
);
1040 MUSCLE_INSERT_STRING ("output_parser_name", parser_file_name
);
1041 MUSCLE_INSERT_STRING ("output_header_name", spec_defines_file
);
1043 MUSCLE_INSERT_INT ("nnts", nvars
);
1044 MUSCLE_INSERT_INT ("nrules", nrules
);
1045 MUSCLE_INSERT_INT ("nstates", nstates
);
1046 MUSCLE_INSERT_INT ("ntokens", ntokens
);
1048 MUSCLE_INSERT_INT ("locations_flag", locations_flag
);
1049 MUSCLE_INSERT_INT ("defines_flag", defines_flag
);
1051 /* Copy definitions in directive. */
1052 obstack_1grow (&attrs_obstack
, 0);
1053 muscle_insert ("prologue", obstack_finish (&attrs_obstack
));
1055 /* Find the right skeleton file. */
1058 if (semantic_parser
)
1059 skeleton
= "bison.hairy";
1061 skeleton
= "bison.simple";
1064 /* Parse the skeleton file and output the needed parsers. */
1065 muscle_insert ("skeleton", skeleton
);
1069 /*----------------------------------------------------------.
1070 | Output the parsing tables and the parser code to ftable. |
1071 `----------------------------------------------------------*/
1076 obstack_init (&format_obstack
);
1085 /* Process the selected skeleton file. */
1088 obstack_free (&muscle_obstack
, NULL
);
1089 obstack_free (&format_obstack
, NULL
);
1090 obstack_free (&action_obstack
, NULL
);
1091 obstack_free (&attrs_obstack
, NULL
);