]>
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 ?? */
103 #include "conflicts.h"
104 #include "muscle_tab.h"
106 /* From lib/readpipe.h. */
107 FILE *readpipe
PARAMS ((const char *, ...));
109 /* From src/scan-skel.l. */
110 int skel_lex
PARAMS ((void));
111 extern FILE *skel_in
;
115 static short **froms
= NULL
;
116 static short **tos
= NULL
;
117 static short *tally
= NULL
;
118 static short *width
= NULL
;
119 static short *actrow
= NULL
;
120 static short *state_count
= NULL
;
121 static short *order
= NULL
;
122 static short *base
= NULL
;
123 static short *pos
= NULL
;
124 static short *table
= NULL
;
125 static short *check
= NULL
;
129 struct obstack muscle_obstack
;
130 static struct obstack format_obstack
;
132 int error_verbose
= 0;
134 /* Returns the number of lines of S. */
136 get_lines_number (const char *s
)
141 for (i
= 0; s
[i
]; ++i
)
152 output_table_data (struct obstack
*oout
,
161 obstack_fgrow1 (oout
, "%6d", first
);
162 for (i
= begin
; i
< end
; ++i
)
164 obstack_1grow (oout
, ',');
167 obstack_sgrow (oout
, "\n ");
172 obstack_fgrow1 (oout
, "%6d", table_data
[i
]);
174 obstack_1grow (oout
, 0);
179 output_token_translations (void)
181 output_table_data (&format_obstack
, token_translations
,
182 0, 1, max_user_token_number
+ 1);
183 muscle_insert ("translate", obstack_finish (&format_obstack
));
184 XFREE (token_translations
);
193 short *values
= XCALLOC (short, nrules
+ 1);
194 for (i
= 0; i
< nrules
+ 1; ++i
)
195 values
[i
] = rules
[i
].rhs
;
196 output_table_data (&format_obstack
, values
,
201 muscle_insert ("prhs", obstack_finish (&format_obstack
));
207 yyrhs
= XMALLOC (short, nritems
);
209 for (i
= 1; i
< nritems
; ++i
)
210 yyrhs
[i
] = ritem
[i
] >= 0 ? ritem
[i
] : -1;
212 output_table_data (&format_obstack
, yyrhs
,
213 ritem
[0], 1, nritems
);
214 muscle_insert ("rhs", obstack_finish (&format_obstack
));
220 if (!semantic_parser
)
221 obstack_sgrow (&table_obstack
, "\n#endif\n");
230 short *values
= (short *) alloca (sizeof (short) * nstates
);
231 for (i
= 0; i
< nstates
; ++i
)
232 values
[i
] = states
[i
]->accessing_symbol
;
233 output_table_data (&format_obstack
, values
,
235 muscle_insert ("stos", obstack_finish (&format_obstack
));
240 output_rule_data (void)
244 short *short_tab
= NULL
;
247 short *values
= XCALLOC (short, nrules
+ 1);
248 for (i
= 0; i
< nrules
+ 1; ++i
)
249 values
[i
] = rules
[i
].line
;
250 output_table_data (&format_obstack
, values
,
252 muscle_insert ("rline", obstack_finish (&format_obstack
));
258 for (i
= 0; i
< nsyms
; i
++)
260 /* Be sure not to use twice the same quotearg slot. */
262 quotearg_n_style (1, c_quoting_style
,
263 quotearg_style (escape_quoting_style
, symbols
[i
]->tag
));
264 /* Width of the next token, including the two quotes, the coma
266 int strsize
= strlen (cp
) + 2;
268 if (j
+ strsize
> 75)
270 obstack_sgrow (&format_obstack
, "\n ");
274 obstack_sgrow (&format_obstack
, cp
);
275 obstack_sgrow (&format_obstack
, ", ");
278 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
280 obstack_sgrow (&format_obstack
, "0");
282 /* Finish table and store. */
283 obstack_1grow (&format_obstack
, 0);
284 muscle_insert ("tname", obstack_finish (&format_obstack
));
286 /* Output YYTOKNUM. */
288 short *values
= XCALLOC (short, ntokens
+ 1);
289 for (i
= 0; i
< ntokens
+ 1; ++i
)
290 values
[i
] = symbols
[i
]->user_token_number
;
291 output_table_data (&format_obstack
, values
,
293 muscle_insert ("toknum", obstack_finish (&format_obstack
));
300 short *values
= XCALLOC (short, nrules
+ 1);
301 for (i
= 0; i
< nrules
+ 1; ++i
)
302 values
[i
] = rules
[i
].lhs
;
303 output_table_data (&format_obstack
, values
,
305 muscle_insert ("r1", obstack_finish (&format_obstack
));
310 short_tab
= XMALLOC (short, nrules
+ 1);
311 for (i
= 1; i
< nrules
; i
++)
312 short_tab
[i
] = rules
[i
+ 1].rhs
- rules
[i
].rhs
- 1;
313 short_tab
[nrules
] = nritems
- rules
[nrules
].rhs
- 1;
314 output_table_data (&format_obstack
, short_tab
,
316 muscle_insert ("r2", obstack_finish (&format_obstack
));
320 /*------------------------------------------------------------------.
321 | Decide what to do for each type of token if seen as the lookahead |
322 | token in specified state. The value returned is used as the |
323 | default action (yydefact) for the state. In addition, actrow is |
324 | filled with what to do for each kind of token, index by symbol |
325 | number, with zero meaning do the default action. The value |
326 | MINSHORT, a very negative number, means this situation is an |
327 | error. The parser recognizes this value specially. |
329 | This is where conflicts are resolved. The loop over lookahead |
330 | rules considered lower-numbered rules last, and the last rule |
331 | considered that likes a token gets to handle it. |
332 `------------------------------------------------------------------*/
335 action_row (state_t
*state
)
338 int default_rule
= 0;
339 reductions
*redp
= state
->reductions
;
340 shifts
*shiftp
= state
->shifts
;
341 errs
*errp
= state
->errs
;
342 /* set nonzero to inhibit having any default reduction */
345 for (i
= 0; i
< ntokens
; i
++)
348 if (redp
->nreds
>= 1)
351 /* loop over all the rules available here which require
353 for (i
= state
->nlookaheads
- 1; i
>= 0; --i
)
354 /* and find each token which the rule finds acceptable
356 for (j
= 0; j
< ntokens
; j
++)
357 /* and record this rule as the rule to use if that
359 if (bitset_test (LA
[state
->lookaheadsp
+ i
], j
))
360 actrow
[j
] = -LAruleno
[state
->lookaheadsp
+ i
];
363 /* Now see which tokens are allowed for shifts in this state. For
364 them, record the shift as the thing to do. So shift is preferred
366 for (i
= 0; i
< shiftp
->nshifts
; i
++)
369 int shift_state
= shiftp
->shifts
[i
];
373 symbol
= states
[shift_state
]->accessing_symbol
;
378 actrow
[symbol
] = shift_state
;
380 /* Do not use any default reduction if there is a shift for
382 if (symbol
== error_token_number
)
386 /* See which tokens are an explicit error in this state (due to
387 %nonassoc). For them, record MINSHORT as the action. */
388 for (i
= 0; i
< errp
->nerrs
; i
++)
390 int symbol
= errp
->errs
[i
];
391 actrow
[symbol
] = MINSHORT
;
394 /* Now find the most common reduction and make it the default action
397 if (redp
->nreds
>= 1 && !nodefault
)
399 if (state
->consistent
)
400 default_rule
= redp
->rules
[0];
404 for (i
= 0; i
< state
->nlookaheads
; i
++)
407 int rule
= -LAruleno
[state
->lookaheadsp
+ i
];
410 for (j
= 0; j
< ntokens
; j
++)
411 if (actrow
[j
] == rule
)
421 /* actions which match the default are replaced with zero,
422 which means "use the default" */
427 for (j
= 0; j
< ntokens
; j
++)
428 if (actrow
[j
] == default_rule
)
431 default_rule
= -default_rule
;
436 /* If have no default rule, the default is an error.
437 So replace any action which says "error" with "use default". */
439 if (default_rule
== 0)
440 for (i
= 0; i
< ntokens
; i
++)
441 if (actrow
[i
] == MINSHORT
)
458 for (i
= 0; i
< ntokens
; i
++)
465 froms
[state
] = sp1
= sp
= XCALLOC (short, count
);
466 tos
[state
] = sp2
= XCALLOC (short, count
);
468 for (i
= 0; i
< ntokens
; i
++)
475 tally
[state
] = count
;
476 width
[state
] = sp1
[-1] - sp
[0] + 1;
480 /*------------------------------------------------------------------.
481 | Figure out the actions for the specified state, indexed by |
482 | lookahead token type. |
484 | The YYDEFACT table is output now. The detailed info is saved for |
485 | putting into YYTABLE later. |
486 `------------------------------------------------------------------*/
492 short *yydefact
= XCALLOC (short, nstates
);
494 actrow
= XCALLOC (short, ntokens
);
495 for (i
= 0; i
< nstates
; ++i
)
497 yydefact
[i
] = action_row (states
[i
]);
501 output_table_data (&format_obstack
, yydefact
,
502 yydefact
[0], 1, nstates
);
503 muscle_insert ("defact", obstack_finish (&format_obstack
));
510 /*-----------------------------.
511 | Output the actions to OOUT. |
512 `-----------------------------*/
515 actions_output (FILE *out
)
518 for (rule
= 1; rule
< nrules
+ 1; ++rule
)
519 if (rules
[rule
].action
)
521 fprintf (out
, " case %d:\n", rule
);
524 fprintf (out
, muscle_find ("linef"),
525 rules
[rule
].action_line
,
526 quotearg_style (c_quoting_style
,
527 muscle_find ("filename")));
528 /* As a Bison extension, add the ending semicolon. Since some
529 Yacc don't do that, help people using bison as a Yacc
530 finding their missing semicolons. */
531 fprintf (out
, "{ %s%s }\n break;\n\n",
533 yacc_flag
? ";" : "");
538 /*----------------------------.
539 | Output the guards to OOUT. |
540 `----------------------------*/
543 guards_output (FILE *out
)
546 for (rule
= 1; rule
< nrules
+ 1; ++rule
)
547 if (rules
[rule
].guard
)
549 fprintf (out
, " case %d:\n", rule
);
552 fprintf (out
, muscle_find ("linef"),
553 rules
[rule
].guard_line
,
554 quotearg_style (c_quoting_style
,
555 muscle_find ("filename")));
556 fprintf (out
, "{ %s; }\n break;\n\n",
562 /*---------------------------------------.
563 | Output the tokens definition to OOUT. |
564 `---------------------------------------*/
567 token_definitions_output (FILE *out
)
570 for (i
= 0; i
< ntokens
; ++i
)
572 bucket
*symbol
= symbols
[i
];
573 int number
= symbol
->user_token_number
;
575 if (number
== SALIAS
)
577 /* Skip error token. */
578 if (symbol
->value
== error_token_number
)
580 if (symbol
->tag
[0] == '\'')
581 continue; /* skip literal character */
582 if (symbol
->tag
[0] == '\"')
584 /* use literal string only if given a symbol with an alias */
586 symbol
= symbol
->alias
;
591 /* Don't #define nonliteral tokens whose names contain periods
592 or '$' (as does the default value of the EOF token). */
593 if (strchr (symbol
->tag
, '.') || strchr (symbol
->tag
, '$'))
596 fprintf (out
, "# define %s\t%d\n",
597 symbol
->tag
, number
);
599 /* FIXME: This is probably wrong, and should be just as
601 fprintf (out
, "# define T%s\t%d\n", symbol
->tag
, symbol
->value
);
607 save_column (int symbol
, int default_state
)
614 int symno
= symbol
- ntokens
+ nstates
;
616 short begin
= goto_map
[symbol
];
617 short end
= goto_map
[symbol
+ 1];
620 for (i
= begin
; i
< end
; i
++)
621 if (to_state
[i
] != default_state
)
627 froms
[symno
] = sp1
= sp
= XCALLOC (short, count
);
628 tos
[symno
] = sp2
= XCALLOC (short, count
);
630 for (i
= begin
; i
< end
; i
++)
631 if (to_state
[i
] != default_state
)
633 *sp1
++ = from_state
[i
];
634 *sp2
++ = to_state
[i
];
637 tally
[symno
] = count
;
638 width
[symno
] = sp1
[-1] - sp
[0] + 1;
642 default_goto (int symbol
)
645 size_t m
= goto_map
[symbol
];
646 size_t n
= goto_map
[symbol
+ 1];
647 int default_state
= -1;
653 for (i
= 0; i
< nstates
; i
++)
656 for (i
= m
; i
< n
; i
++)
657 state_count
[to_state
[i
]]++;
659 for (i
= 0; i
< nstates
; i
++)
660 if (state_count
[i
] > max
)
662 max
= state_count
[i
];
666 return default_state
;
670 /*-------------------------------------------------------------------.
671 | Figure out what to do after reducing with each rule, depending on |
672 | the saved state from before the beginning of parsing the data that |
673 | matched this rule. |
675 | The YYDEFGOTO table is output now. The detailed info is saved for |
676 | putting into YYTABLE later. |
677 `-------------------------------------------------------------------*/
683 short *yydefgoto
= XMALLOC (short, nsyms
- ntokens
);
685 state_count
= XCALLOC (short, nstates
);
686 for (i
= ntokens
; i
< nsyms
; ++i
)
688 int default_state
= default_goto (i
);
689 save_column (i
, default_state
);
690 yydefgoto
[i
- ntokens
] = default_state
;
693 output_table_data (&format_obstack
, yydefgoto
,
694 yydefgoto
[0], 1, nsyms
- ntokens
);
695 muscle_insert ("defgoto", obstack_finish (&format_obstack
));
702 /* The next few functions decide how to pack the actions and gotos
703 information into yytable. */
710 order
= XCALLOC (short, nvectors
);
713 for (i
= 0; i
< nvectors
; i
++)
719 int j
= nentries
- 1;
721 while (j
>= 0 && (width
[order
[j
]] < w
))
724 while (j
>= 0 && (width
[order
[j
]] == w
) && (tally
[order
[j
]] < t
))
727 for (k
= nentries
- 1; k
> j
; k
--)
728 order
[k
+ 1] = order
[k
];
737 matching_state (int vector
)
739 int i
= order
[vector
];
744 if (i
>= (int) nstates
)
750 for (prev
= vector
- 1; prev
>= 0; prev
--)
756 if (width
[j
] != w
|| tally
[j
] != t
)
759 for (k
= 0; match
&& k
< t
; k
++)
760 if (tos
[j
][k
] != tos
[i
][k
] || froms
[j
][k
] != froms
[i
][k
])
772 pack_vector (int vector
)
774 int i
= order
[vector
];
778 short *from
= froms
[i
];
783 for (j
= lowzero
- from
[0]; j
< MAXTABLE
; j
++)
788 for (k
= 0; ok
&& k
< t
; k
++)
792 fatal (_("maximum table size (%d) exceeded"), MAXTABLE
);
798 for (k
= 0; ok
&& k
< vector
; k
++)
804 for (k
= 0; k
< t
; k
++)
808 check
[loc
] = from
[k
];
811 while (table
[lowzero
] != 0)
820 #define pack_vector_succeeded 0
821 assert (pack_vector_succeeded
);
833 base
= XCALLOC (short, nvectors
);
834 pos
= XCALLOC (short, nentries
);
835 table
= XCALLOC (short, MAXTABLE
);
836 check
= XCALLOC (short, MAXTABLE
);
841 for (i
= 0; i
< nvectors
; i
++)
844 for (i
= 0; i
< MAXTABLE
; i
++)
847 for (i
= 0; i
< nentries
; i
++)
849 state
= matching_state (i
);
852 place
= pack_vector (i
);
857 base
[order
[i
]] = place
;
860 for (i
= 0; i
< nvectors
; i
++)
871 /* the following functions output yytable, yycheck
872 and the vectors whose elements index the portion starts */
878 output_table_data (&format_obstack
, base
,
879 base
[0], 1, nstates
);
880 muscle_insert ("pact", obstack_finish (&format_obstack
));
883 output_table_data (&format_obstack
, base
,
884 base
[nstates
], nstates
+ 1, nvectors
);
885 muscle_insert ("pgoto", obstack_finish (&format_obstack
));
894 output_table_data (&format_obstack
, table
,
895 table
[0], 1, high
+ 1);
896 muscle_insert ("table", obstack_finish (&format_obstack
));
904 output_table_data (&format_obstack
, check
,
905 check
[0], 1, high
+ 1);
906 muscle_insert ("check", obstack_finish (&format_obstack
));
910 /* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
914 output_actions (void)
917 nvectors
= nstates
+ nvars
;
919 froms
= XCALLOC (short *, nvectors
);
920 tos
= XCALLOC (short *, nvectors
);
921 tally
= XCALLOC (short, nvectors
);
922 width
= XCALLOC (short, nvectors
);
929 XFREE (goto_map
+ ntokens
);
941 for (i
= 0; i
< nstates
; ++i
)
943 free (states
[i
]->shifts
);
944 XFREE (states
[i
]->reductions
);
945 free (states
[i
]->errs
);
952 /*---------------------------.
953 | Call the skeleton parser. |
954 `---------------------------*/
957 output_skeleton (void)
959 /* Store the definition of all the muscles. */
960 char *tempdir
= getenv ("TMPDIR");
961 char *tempfile
= NULL
;
967 tempdir
= DEFAULT_TMPDIR
;
968 tempfile
= xmalloc (strlen (tempdir
) + 11);
969 sprintf (tempfile
, "%s/bsnXXXXXX", tempdir
);
970 fd
= mkstemp (tempfile
);
972 error (EXIT_FAILURE
, errno
, "%s", tempfile
);
974 out
= fdopen (fd
, "w");
976 error (EXIT_FAILURE
, errno
, "%s", tempfile
);
978 /* There are no comments, especially not `#': we do want M4 expansion
979 after `#': think of CPP macros! */
980 fputs ("m4_changecom()\n", out
);
981 fputs ("m4_init()\n", out
);
983 fputs ("m4_define([b4_actions], \n[[", out
);
984 actions_output (out
);
985 fputs ("]])\n\n", out
);
987 fputs ("m4_define([b4_guards], \n[[", out
);
989 fputs ("]])\n\n", out
);
991 fputs ("m4_define([b4_tokendef], \n[[", out
);
992 token_definitions_output (out
);
993 fputs ("]])\n\n", out
);
995 muscles_m4_output (out
);
997 fputs ("m4_wrap([m4_divert_pop(0)])\n", out
);
998 fputs ("m4_divert_push(0)dnl\n", out
);
1001 /* Invoke m4 on the definition of the muscles, and the skeleton. */
1003 const char *bison_pkgdatadir
= getenv ("BISON_PKGDATADIR");
1004 const char *m4
= getenv ("M4");
1007 if (!bison_pkgdatadir
)
1008 bison_pkgdatadir
= PKGDATADIR
;
1011 "running: %s -I %s m4sugar/m4sugar.m4 %s %s\n",
1012 m4
, bison_pkgdatadir
, tempfile
, skeleton
);
1013 skel_in
= readpipe (m4
,
1014 "-I", bison_pkgdatadir
,
1015 "m4sugar/m4sugar.m4",
1020 error (EXIT_FAILURE
, errno
, "cannot run m4");
1023 /* If `debugging', keep this file alive. */
1032 MUSCLE_INSERT_INT ("last", high
);
1033 MUSCLE_INSERT_INT ("flag", MINSHORT
);
1034 MUSCLE_INSERT_INT ("pure", pure_parser
);
1035 MUSCLE_INSERT_INT ("nsym", nsyms
);
1036 MUSCLE_INSERT_INT ("debug", debug_flag
);
1037 MUSCLE_INSERT_INT ("final", final_state
);
1038 MUSCLE_INSERT_INT ("maxtok", max_user_token_number
);
1039 MUSCLE_INSERT_INT ("error_verbose", error_verbose
);
1040 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix
? spec_name_prefix
: "yy");
1042 /* FIXME: This is wrong: the muscles should decide whether they hold
1043 a copy or not, but the situation is too obscure currently. */
1044 MUSCLE_INSERT_STRING ("output_infix", output_infix
? output_infix
: "");
1045 MUSCLE_INSERT_STRING ("output_prefix", short_base_name
);
1046 MUSCLE_INSERT_STRING ("output_parser_name", parser_file_name
);
1047 MUSCLE_INSERT_STRING ("output_header_name", spec_defines_file
);
1049 MUSCLE_INSERT_INT ("nnts", nvars
);
1050 MUSCLE_INSERT_INT ("nrules", nrules
);
1051 MUSCLE_INSERT_INT ("nstates", nstates
);
1052 MUSCLE_INSERT_INT ("ntokens", ntokens
);
1054 MUSCLE_INSERT_INT ("locations_flag", locations_flag
);
1055 MUSCLE_INSERT_INT ("defines_flag", defines_flag
);
1057 /* Copy definitions in directive. */
1058 obstack_1grow (&attrs_obstack
, 0);
1059 muscle_insert ("prologue", obstack_finish (&attrs_obstack
));
1061 /* Find the right skeleton file. */
1064 if (semantic_parser
)
1065 skeleton
= "bison.hairy";
1067 skeleton
= "bison.simple";
1070 /* Parse the skeleton file and output the needed parsers. */
1071 muscle_insert ("skeleton", skeleton
);
1075 /*----------------------------------------------------------.
1076 | Output the parsing tables and the parser code to ftable. |
1077 `----------------------------------------------------------*/
1082 obstack_init (&format_obstack
);
1084 output_token_translations ();
1087 if (semantic_parser
)
1089 output_rule_data ();
1094 /* Process the selected skeleton file. */
1097 obstack_free (&muscle_obstack
, NULL
);
1098 obstack_free (&format_obstack
, NULL
);
1099 obstack_free (&action_obstack
, NULL
);
1100 obstack_free (&attrs_obstack
, NULL
);