]>
git.saurik.com Git - bison.git/blob - src/output.c
4ad8f4e803e0abba8403e6d691a18c8c868acfb1
1 /* Output the generated parsing program for bison,
2 Copyright 1984, 1986, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of Bison, the GNU Compiler Compiler.
6 Bison is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 Bison is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 /* The parser tables consist of these tables.
23 Starred ones needed only for the semantic parser.
24 Double starred are output only if switches are set.
26 yytranslate = vector mapping yylex's token numbers into bison's token
29 ** yytname = vector of string-names indexed by bison token number
31 ** yytoknum = vector of yylex token numbers corresponding to entries
34 yyrline = vector of line-numbers of all rules. For yydebug printouts.
36 yyrhs = vector of items of all rules.
37 This is exactly what ritems contains. For yydebug and for semantic
40 yyprhs[r] = index in yyrhs of first item for rule r.
42 yyr1[r] = symbol number of symbol that rule r derives.
44 yyr2[r] = number of symbols composing right hand side of rule r.
46 * yystos[s] = the symbol number of the symbol that leads to state s.
48 yydefact[s] = default rule to reduce with in state s,
49 when yytable doesn't specify something else to do.
50 Zero means the default is an error.
52 yydefgoto[i] = default state to go to after a reduction of a rule that
53 generates variable ntokens + i, except when yytable
54 specifies something else to do.
56 yypact[s] = index in yytable of the portion describing state s.
57 The lookahead token's type is used to index that portion
58 to find out what to do.
60 If the value in yytable is positive,
61 we shift the token and go to that state.
63 If the value is negative, it is minus a rule number to reduce by.
65 If the value is zero, the default action from yydefact[s] is used.
67 yypgoto[i] = the index in yytable of the portion describing
68 what to do after reducing a rule that derives variable i + ntokens.
69 This portion is indexed by the parser state number, s,
70 as of before the text for this nonterminal was read.
71 The value from yytable is the state to go to if
72 the corresponding value in yycheck is s.
74 yytable = a vector filled with portions for different uses,
75 found via yypact and yypgoto.
77 yycheck = a vector indexed in parallel with yytable.
78 It indicates, in a roundabout way, the bounds of the
79 portion you are trying to examine.
81 Suppose that the portion of yytable starts at index p
82 and the index to be examined within the portion is i.
83 Then if yycheck[p+i] != i, i is outside the bounds
84 of what is actually allocated, and the default
85 (from yydefact or yydefgoto) should be used.
86 Otherwise, yytable[p+i] should be used.
88 YYFINAL = the state number of the termination state.
89 YYFLAG = most negative short int. Used to flag ??
103 #include "conflicts.h"
104 #include "muscle_tab.h"
109 static short **froms
= NULL
;
110 static short **tos
= NULL
;
111 static short *tally
= NULL
;
112 static short *width
= NULL
;
113 static short *actrow
= NULL
;
114 static short *state_count
= NULL
;
115 static short *order
= NULL
;
116 static short *base
= NULL
;
117 static short *pos
= NULL
;
118 static short *table
= NULL
;
119 static short *check
= NULL
;
123 struct obstack muscle_obstack
;
124 static struct obstack format_obstack
;
126 int error_verbose
= 0;
128 /* Returns the number of lines of S. */
130 get_lines_number (const char *s
)
135 for (i
= 0; s
[i
]; ++i
)
146 output_table_data (struct obstack
*oout
,
155 obstack_fgrow1 (oout
, "%6d", first
);
156 for (i
= begin
; i
< end
; ++i
)
158 obstack_1grow (oout
, ',');
161 obstack_sgrow (oout
, "\n ");
166 obstack_fgrow1 (oout
, "%6d", table_data
[i
]);
168 obstack_1grow (oout
, 0);
173 output_token_translations (void)
175 output_table_data (&format_obstack
, token_translations
,
176 0, 1, max_user_token_number
+ 1);
177 muscle_insert ("translate", obstack_finish (&format_obstack
));
178 XFREE (token_translations
);
187 short *values
= XCALLOC (short, nrules
+ 1);
188 for (i
= 0; i
< nrules
+ 1; ++i
)
189 values
[i
] = rule_table
[i
].rhs
;
190 output_table_data (&format_obstack
, values
,
195 muscle_insert ("prhs", obstack_finish (&format_obstack
));
201 yyrhs
= XMALLOC (short, nritems
);
203 for (i
= 1; i
< nritems
; ++i
)
204 yyrhs
[i
] = ritem
[i
] >= 0 ? ritem
[i
] : -1;
206 output_table_data (&format_obstack
, yyrhs
,
207 ritem
[0], 1, nritems
);
208 muscle_insert ("rhs", obstack_finish (&format_obstack
));
214 if (!semantic_parser
)
215 obstack_sgrow (&table_obstack
, "\n#endif\n");
224 short *values
= (short *) alloca (sizeof (short) * nstates
);
225 for (i
= 0; i
< nstates
; ++i
)
226 values
[i
] = state_table
[i
]->accessing_symbol
;
227 output_table_data (&format_obstack
, values
,
229 muscle_insert ("stos", obstack_finish (&format_obstack
));
234 output_rule_data (void)
238 short *short_tab
= NULL
;
241 short *values
= XCALLOC (short, nrules
+ 1);
242 for (i
= 0; i
< nrules
+ 1; ++i
)
243 values
[i
] = rule_table
[i
].line
;
244 output_table_data (&format_obstack
, values
,
246 muscle_insert ("rline", obstack_finish (&format_obstack
));
252 for (i
= 0; i
< nsyms
; i
++)
254 /* Be sure not to use twice the same quotearg slot. */
256 quotearg_n_style (1, c_quoting_style
,
257 quotearg_style (escape_quoting_style
, tags
[i
]));
258 /* Width of the next token, including the two quotes, the coma
260 int strsize
= strlen (cp
) + 2;
262 if (j
+ strsize
> 75)
264 obstack_sgrow (&format_obstack
, "\n ");
268 obstack_sgrow (&format_obstack
, cp
);
269 obstack_sgrow (&format_obstack
, ", ");
272 /* add a NULL entry to list of tokens */
273 obstack_sgrow (&format_obstack
, "NULL");
275 /* Finish table and store. */
276 obstack_1grow (&format_obstack
, 0);
277 muscle_insert ("tname", obstack_finish (&format_obstack
));
279 /* Output YYTOKNUM. */
280 output_table_data (&format_obstack
, user_toknums
,
282 muscle_insert ("toknum", obstack_finish (&format_obstack
));
286 short *values
= XCALLOC (short, nrules
+ 1);
287 for (i
= 0; i
< nrules
+ 1; ++i
)
288 values
[i
] = rule_table
[i
].lhs
;
289 output_table_data (&format_obstack
, values
,
291 muscle_insert ("r1", obstack_finish (&format_obstack
));
296 short_tab
= XMALLOC (short, nrules
+ 1);
297 for (i
= 1; i
< nrules
; i
++)
298 short_tab
[i
] = rule_table
[i
+ 1].rhs
- rule_table
[i
].rhs
- 1;
299 short_tab
[nrules
] = nitems
- rule_table
[nrules
].rhs
- 1;
300 output_table_data (&format_obstack
, short_tab
,
302 muscle_insert ("r2", obstack_finish (&format_obstack
));
306 /*------------------------------------------------------------------.
307 | Decide what to do for each type of token if seen as the lookahead |
308 | token in specified state. The value returned is used as the |
309 | default action (yydefact) for the state. In addition, actrow is |
310 | filled with what to do for each kind of token, index by symbol |
311 | number, with zero meaning do the default action. The value |
312 | MINSHORT, a very negative number, means this situation is an |
313 | error. The parser recognizes this value specially. |
315 | This is where conflicts are resolved. The loop over lookahead |
316 | rules considered lower-numbered rules last, and the last rule |
317 | considered that likes a token gets to handle it. |
318 `------------------------------------------------------------------*/
321 action_row (state_t
*state
)
324 int default_rule
= 0;
325 reductions
*redp
= state
->reductions
;
326 shifts
*shiftp
= state
->shifts
;
327 errs
*errp
= state
->errs
;
328 /* set nonzero to inhibit having any default reduction */
331 for (i
= 0; i
< ntokens
; i
++)
334 if (redp
->nreds
>= 1)
337 /* loop over all the rules available here which require
339 for (i
= state
->nlookaheads
- 1; i
>= 0; --i
)
340 /* and find each token which the rule finds acceptable
342 for (j
= 0; j
< ntokens
; j
++)
343 /* and record this rule as the rule to use if that
345 if (BITISSET (LA (state
->lookaheadsp
+ i
), j
))
346 actrow
[j
] = -LAruleno
[state
->lookaheadsp
+ i
];
349 /* Now see which tokens are allowed for shifts in this state. For
350 them, record the shift as the thing to do. So shift is preferred
352 for (i
= 0; i
< shiftp
->nshifts
; i
++)
355 int shift_state
= shiftp
->shifts
[i
];
359 symbol
= state_table
[shift_state
]->accessing_symbol
;
364 actrow
[symbol
] = shift_state
;
366 /* Do not use any default reduction if there is a shift for
368 if (symbol
== error_token_number
)
372 /* See which tokens are an explicit error in this state (due to
373 %nonassoc). For them, record MINSHORT as the action. */
374 for (i
= 0; i
< errp
->nerrs
; i
++)
376 int symbol
= errp
->errs
[i
];
377 actrow
[symbol
] = MINSHORT
;
380 /* Now find the most common reduction and make it the default action
383 if (redp
->nreds
>= 1 && !nodefault
)
385 if (state
->consistent
)
386 default_rule
= redp
->rules
[0];
390 for (i
= 0; i
< state
->nlookaheads
; i
++)
393 int rule
= -LAruleno
[state
->lookaheadsp
+ i
];
396 for (j
= 0; j
< ntokens
; j
++)
397 if (actrow
[j
] == rule
)
407 /* actions which match the default are replaced with zero,
408 which means "use the default" */
413 for (j
= 0; j
< ntokens
; j
++)
414 if (actrow
[j
] == default_rule
)
417 default_rule
= -default_rule
;
422 /* If have no default rule, the default is an error.
423 So replace any action which says "error" with "use default". */
425 if (default_rule
== 0)
426 for (i
= 0; i
< ntokens
; i
++)
427 if (actrow
[i
] == MINSHORT
)
444 for (i
= 0; i
< ntokens
; i
++)
451 froms
[state
] = sp1
= sp
= XCALLOC (short, count
);
452 tos
[state
] = sp2
= XCALLOC (short, count
);
454 for (i
= 0; i
< ntokens
; i
++)
461 tally
[state
] = count
;
462 width
[state
] = sp1
[-1] - sp
[0] + 1;
466 /*------------------------------------------------------------------.
467 | Figure out the actions for the specified state, indexed by |
468 | lookahead token type. |
470 | The YYDEFACT table is output now. The detailed info is saved for |
471 | putting into YYTABLE later. |
472 `------------------------------------------------------------------*/
478 short *yydefact
= XCALLOC (short, nstates
);
480 actrow
= XCALLOC (short, ntokens
);
481 for (i
= 0; i
< nstates
; ++i
)
483 yydefact
[i
] = action_row (state_table
[i
]);
487 output_table_data (&format_obstack
, yydefact
,
488 yydefact
[0], 1, nstates
);
489 muscle_insert ("defact", obstack_finish (&format_obstack
));
496 /*-----------------------------.
497 | Output the actions to OOUT. |
498 `-----------------------------*/
501 actions_output (FILE *out
, size_t *line
)
504 for (rule
= 1; rule
< nrules
+ 1; ++rule
)
505 if (rule_table
[rule
].action
)
507 fprintf (out
, " case %d:\n", rule
);
510 fprintf (out
, muscle_find ("linef"),
511 rule_table
[rule
].action_line
,
512 quotearg_style (c_quoting_style
,
513 muscle_find ("filename")));
514 /* As a Bison extension, add the ending semicolon. Since some
515 Yacc don't do that, help people using bison as a Yacc
516 finding their missing semicolons. */
517 fprintf (out
, "{ %s%s }\n break;\n\n",
518 rule_table
[rule
].action
,
519 yacc_flag
? ";" : "");
521 /* We always output 4 '\n' per action. */
523 /* Plus one if !no_lines_flag. */
526 /* Get the number of lines written by the user. */
527 *line
+= get_lines_number (rule_table
[rule
].action
);
532 /*----------------------------.
533 | Output the guards to OOUT. |
534 `----------------------------*/
537 guards_output (FILE *out
, size_t *line
)
540 for (rule
= 1; rule
< nrules
+ 1; ++rule
)
541 if (rule_table
[rule
].action
)
543 fprintf (out
, " case %d:\n", rule
);
546 fprintf (out
, muscle_find ("linef"),
547 rule_table
[rule
].guard_line
,
548 quotearg_style (c_quoting_style
,
549 muscle_find ("filename")));
550 fprintf (out
, "{ %s; }\n break;\n\n",
551 rule_table
[rule
].guard
);
553 /* We always output 4 '\n' per action. */
555 /* Plus one if !no_lines_flag. */
558 /* Get the number of lines written by the user. */
559 *line
+= get_lines_number (rule_table
[rule
].guard
);
565 save_column (int symbol
, int default_state
)
572 int symno
= symbol
- ntokens
+ nstates
;
574 short begin
= goto_map
[symbol
];
575 short end
= goto_map
[symbol
+ 1];
578 for (i
= begin
; i
< end
; i
++)
579 if (to_state
[i
] != default_state
)
585 froms
[symno
] = sp1
= sp
= XCALLOC (short, count
);
586 tos
[symno
] = sp2
= XCALLOC (short, count
);
588 for (i
= begin
; i
< end
; i
++)
589 if (to_state
[i
] != default_state
)
591 *sp1
++ = from_state
[i
];
592 *sp2
++ = to_state
[i
];
595 tally
[symno
] = count
;
596 width
[symno
] = sp1
[-1] - sp
[0] + 1;
600 default_goto (int symbol
)
603 int m
= goto_map
[symbol
];
604 int n
= goto_map
[symbol
+ 1];
605 int default_state
= -1;
611 for (i
= 0; i
< nstates
; i
++)
614 for (i
= m
; i
< n
; i
++)
615 state_count
[to_state
[i
]]++;
617 for (i
= 0; i
< nstates
; i
++)
618 if (state_count
[i
] > max
)
620 max
= state_count
[i
];
624 return default_state
;
628 /*-------------------------------------------------------------------.
629 | Figure out what to do after reducing with each rule, depending on |
630 | the saved state from before the beginning of parsing the data that |
631 | matched this rule. |
633 | The YYDEFGOTO table is output now. The detailed info is saved for |
634 | putting into YYTABLE later. |
635 `-------------------------------------------------------------------*/
641 short *yydefgoto
= XMALLOC (short, nsyms
- ntokens
);
643 state_count
= XCALLOC (short, nstates
);
644 for (i
= ntokens
; i
< nsyms
; ++i
)
646 int default_state
= default_goto (i
);
647 save_column (i
, default_state
);
648 yydefgoto
[i
- ntokens
] = default_state
;
651 output_table_data (&format_obstack
, yydefgoto
,
652 yydefgoto
[0], 1, nsyms
- ntokens
);
653 muscle_insert ("defgoto", obstack_finish (&format_obstack
));
660 /* The next few functions decide how to pack the actions and gotos
661 information into yytable. */
668 order
= XCALLOC (short, nvectors
);
671 for (i
= 0; i
< nvectors
; i
++)
677 int j
= nentries
- 1;
679 while (j
>= 0 && (width
[order
[j
]] < w
))
682 while (j
>= 0 && (width
[order
[j
]] == w
) && (tally
[order
[j
]] < t
))
685 for (k
= nentries
- 1; k
> j
; k
--)
686 order
[k
+ 1] = order
[k
];
695 matching_state (int vector
)
697 int i
= order
[vector
];
708 for (prev
= vector
- 1; prev
>= 0; prev
--)
714 if (width
[j
] != w
|| tally
[j
] != t
)
717 for (k
= 0; match
&& k
< t
; k
++)
718 if (tos
[j
][k
] != tos
[i
][k
] || froms
[j
][k
] != froms
[i
][k
])
730 pack_vector (int vector
)
732 int i
= order
[vector
];
736 short *from
= froms
[i
];
741 for (j
= lowzero
- from
[0]; j
< MAXTABLE
; j
++)
746 for (k
= 0; ok
&& k
< t
; k
++)
750 fatal (_("maximum table size (%d) exceeded"), MAXTABLE
);
756 for (k
= 0; ok
&& k
< vector
; k
++)
762 for (k
= 0; k
< t
; k
++)
766 check
[loc
] = from
[k
];
769 while (table
[lowzero
] != 0)
778 #define pack_vector_succeeded 0
779 assert (pack_vector_succeeded
);
791 base
= XCALLOC (short, nvectors
);
792 pos
= XCALLOC (short, nentries
);
793 table
= XCALLOC (short, MAXTABLE
);
794 check
= XCALLOC (short, MAXTABLE
);
799 for (i
= 0; i
< nvectors
; i
++)
802 for (i
= 0; i
< MAXTABLE
; i
++)
805 for (i
= 0; i
< nentries
; i
++)
807 state
= matching_state (i
);
810 place
= pack_vector (i
);
815 base
[order
[i
]] = place
;
818 for (i
= 0; i
< nvectors
; i
++)
829 /* the following functions output yytable, yycheck
830 and the vectors whose elements index the portion starts */
836 output_table_data (&format_obstack
, base
,
837 base
[0], 1, nstates
);
838 muscle_insert ("pact", obstack_finish (&format_obstack
));
841 output_table_data (&format_obstack
, base
,
842 base
[nstates
], nstates
+ 1, nvectors
);
843 muscle_insert ("pgoto", obstack_finish (&format_obstack
));
852 output_table_data (&format_obstack
, table
,
853 table
[0], 1, high
+ 1);
854 muscle_insert ("table", obstack_finish (&format_obstack
));
862 output_table_data (&format_obstack
, check
,
863 check
[0], 1, high
+ 1);
864 muscle_insert ("check", obstack_finish (&format_obstack
));
868 /* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
872 output_actions (void)
875 nvectors
= nstates
+ nvars
;
877 froms
= XCALLOC (short *, nvectors
);
878 tos
= XCALLOC (short *, nvectors
);
879 tally
= XCALLOC (short, nvectors
);
880 width
= XCALLOC (short, nvectors
);
887 XFREE (goto_map
+ ntokens
);
899 for (i
= 0; i
< nstates
; ++i
)
901 free (state_table
[i
]->shifts
);
902 XFREE (state_table
[i
]->reductions
);
903 free (state_table
[i
]->errs
);
904 free (state_table
[i
]);
910 /*------------------------------------------------------------.
911 | Copy the parser code from SKEL_FILENAME into OOUT obstack. |
912 | and do the muscle substitution. |
913 `------------------------------------------------------------*/
916 output_parser (const char *skel_filename
, FILE *out
)
921 size_t skeleton_line
;
923 fskel
= xfopen (skel_filename
, "r");
925 /* New output code. */
941 else if ((c
= getc (fskel
)) == '%')
943 /* Read the muscle. */
944 const char *muscle_key
= 0;
945 const char *muscle_value
= 0;
947 while (isalnum (c
= getc (fskel
)) || c
== '-')
948 obstack_1grow (&muscle_obstack
, c
);
949 obstack_1grow (&muscle_obstack
, 0);
951 /* Output the right value, or see if it's something special. */
952 muscle_key
= obstack_finish (&muscle_obstack
);
953 muscle_value
= muscle_find (muscle_key
);
954 if (!strcmp (muscle_key
, "actions"))
955 actions_output (out
, &output_line
);
956 else if (!strcmp (muscle_key
, "guards"))
957 guards_output (out
, &output_line
);
958 else if (!strcmp (muscle_key
, "line"))
959 fprintf (out
, "%d", output_line
);
960 else if (!strcmp (muscle_key
, "skeleton-line"))
961 fprintf (out
, "%d", skeleton_line
);
962 else if (muscle_value
)
964 fputs (muscle_value
, out
);
965 output_line
+= get_lines_number (muscle_value
);
970 fputs (muscle_key
, out
);
981 /*----------------------------------------.
982 | Prepare the master parser to be output |
983 `----------------------------------------*/
986 output_master_parser (void)
988 FILE *parser
= xfopen (parser_file_name
, "w");
992 skeleton
= skeleton_find ("BISON_HAIRY", BISON_HAIRY
);
994 skeleton
= skeleton_find ("BISON_SIMPLE", BISON_SIMPLE
);
996 muscle_insert ("skeleton", skeleton
);
997 muscle_insert ("parser-file-name", parser_file_name
);
999 output_parser (skeleton
, parser
);
1006 #define MUSCLE_INSERT_INT(Key, Value) \
1008 obstack_fgrow1 (&muscle_obstack, "%d", Value); \
1009 obstack_1grow (&muscle_obstack, 0); \
1010 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1013 #define MUSCLE_INSERT_STRING(Key, Value) \
1015 obstack_sgrow (&muscle_obstack, Value); \
1016 obstack_1grow (&muscle_obstack, 0); \
1017 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1020 #define MUSCLE_INSERT_PREFIX(Key, Value) \
1022 obstack_fgrow2 (&muscle_obstack, "%s%s", spec_name_prefix, Value); \
1023 obstack_1grow (&muscle_obstack, 0); \
1024 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1030 MUSCLE_INSERT_INT ("last", high
);
1031 MUSCLE_INSERT_INT ("flag", MINSHORT
);
1032 MUSCLE_INSERT_INT ("pure", pure_parser
);
1033 MUSCLE_INSERT_INT ("nsym", nsyms
);
1034 MUSCLE_INSERT_INT ("debug", debug_flag
);
1035 MUSCLE_INSERT_INT ("final", final_state
);
1036 MUSCLE_INSERT_INT ("maxtok", max_user_token_number
);
1037 MUSCLE_INSERT_INT ("error-verbose", error_verbose
);
1038 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix
);
1040 MUSCLE_INSERT_INT ("nnts", nvars
);
1041 MUSCLE_INSERT_INT ("nrules", nrules
);
1042 MUSCLE_INSERT_INT ("nstates", nstates
);
1043 MUSCLE_INSERT_INT ("ntokens", ntokens
);
1045 MUSCLE_INSERT_INT ("locations-flag", locations_flag
);
1049 /*-------------------------.
1050 | Output the header file. |
1051 `-------------------------*/
1054 header_output (void)
1056 FILE *out
= xfopen (spec_defines_file
, "w");
1057 char *macro_name
= compute_header_macro ();
1059 fprintf (out
, "#ifndef %s\n", macro_name
);
1060 fprintf (out
, "# define %s\n\n", macro_name
);
1062 fputs (muscle_find ("tokendef"), out
);
1067 # define YYSTYPE yystype\n\
1069 muscle_find ("stype"));
1072 fprintf (out
, "\nextern YYSTYPE %slval;\n",
1074 if (semantic_parser
)
1078 for (i
= ntokens
; i
< nsyms
; i
++)
1079 /* don't make these for dummy nonterminals made by gensym. */
1080 if (*tags
[i
] != '@')
1081 fprintf (out
, "# define NT%s\t%d\n", tags
[i
], i
);
1084 fprintf (out
, "\n#endif /* not %s */\n", macro_name
);
1090 /*----------------------------------------------------------.
1091 | Output the parsing tables and the parser code to ftable. |
1092 `----------------------------------------------------------*/
1097 obstack_init (&format_obstack
);
1099 output_token_translations ();
1103 if (semantic_parser
)
1105 output_rule_data ();
1106 XFREE (user_toknums
);
1110 /* Copy definitions in directive. */
1111 obstack_1grow (&attrs_obstack
, 0);
1112 muscle_insert ("prologue", obstack_finish (&attrs_obstack
));
1114 /* Output the parser. */
1115 output_master_parser ();
1116 /* Output the header if needed. */
1120 free (rule_table
+ 1);
1121 obstack_free (&muscle_obstack
, NULL
);
1122 obstack_free (&format_obstack
, NULL
);
1123 obstack_free (&action_obstack
, NULL
);
1124 obstack_free (&attrs_obstack
, NULL
);