]>
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
)
150 /*----------------------------------------------------------------.
151 | Format the FIRST and then TABLE_DATA[BEGIN..END[ into OOUT, and |
152 | return the number of bits needed for its longuest value. |
153 `----------------------------------------------------------------*/
155 static inline long int
156 output_table_data (struct obstack
*oout
,
162 long int max
= first
;
166 obstack_fgrow1 (oout
, "%6d", first
);
167 for (i
= begin
; i
< end
; ++i
)
169 obstack_1grow (oout
, ',');
172 obstack_sgrow (oout
, "\n ");
177 obstack_fgrow1 (oout
, "%6d", table_data
[i
]);
178 if (table_data
[i
] > max
)
181 obstack_1grow (oout
, 0);
187 /*-----------------------------------------------------------------.
188 | Prepare the muscles related to the tokens: translate, tname, and |
190 `-----------------------------------------------------------------*/
193 prepare_tokens (void)
195 long int max
= output_table_data (&format_obstack
, token_translations
,
196 0, 1, max_user_token_number
+ 1);
197 muscle_insert ("translate", obstack_finish (&format_obstack
));
198 MUSCLE_INSERT_LONG_INT ("token_number_max", max
);
199 XFREE (token_translations
);
204 for (i
= 0; i
< nsyms
; i
++)
206 /* Be sure not to use twice the same quotearg slot. */
208 quotearg_n_style (1, c_quoting_style
,
209 quotearg_style (escape_quoting_style
,
211 /* Width of the next token, including the two quotes, the coma
213 int strsize
= strlen (cp
) + 2;
215 if (j
+ strsize
> 75)
217 obstack_sgrow (&format_obstack
, "\n ");
221 obstack_sgrow (&format_obstack
, cp
);
222 obstack_sgrow (&format_obstack
, ", ");
225 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
227 obstack_sgrow (&format_obstack
, "0");
229 /* Finish table and store. */
230 obstack_1grow (&format_obstack
, 0);
231 muscle_insert ("tname", obstack_finish (&format_obstack
));
234 /* Output YYTOKNUM. */
237 short *values
= XCALLOC (short, ntokens
+ 1);
238 for (i
= 0; i
< ntokens
+ 1; ++i
)
239 values
[i
] = symbols
[i
]->user_token_number
;
240 output_table_data (&format_obstack
, values
,
242 muscle_insert ("toknum", obstack_finish (&format_obstack
));
248 /*-------------------------------------------------------------.
249 | Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
251 `-------------------------------------------------------------*/
259 short *rhs
= XMALLOC (short, nritems
);
260 short *prhs
= XMALLOC (short, nrules
+ 1);
261 short *r1
= XMALLOC (short, nrules
+ 1);
262 short *r2
= XMALLOC (short, nrules
+ 1);
263 short *rline
= XMALLOC (short, nrules
+ 1);
265 for (r
= 1; r
< nrules
+ 1; ++r
)
267 /* Index of rule R in RHS. */
269 /* RHS of the rule R. */
270 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; ++rhsp
)
272 /* LHS of the rule R. */
273 r1
[r
] = rules
[r
].lhs
->number
;
274 /* Length of rule R's RHS. */
276 /* Separator in RHS. */
278 /* Line where rule was defined. */
279 rline
[r
] = rules
[r
].line
;
281 assert (i
== nritems
);
283 output_table_data (&format_obstack
, rhs
, ritem
[0], 1, nritems
);
284 muscle_insert ("rhs", obstack_finish (&format_obstack
));
286 output_table_data (&format_obstack
, prhs
, 0, 1, nrules
+ 1);
287 muscle_insert ("prhs", obstack_finish (&format_obstack
));
289 output_table_data (&format_obstack
, rline
, 0, 1, nrules
+ 1);
290 muscle_insert ("rline", obstack_finish (&format_obstack
));
292 output_table_data (&format_obstack
, r1
, 0, 1, nrules
+ 1);
293 muscle_insert ("r1", obstack_finish (&format_obstack
));
295 output_table_data (&format_obstack
, r2
, 0, 1, nrules
+ 1);
296 muscle_insert ("r2", obstack_finish (&format_obstack
));
303 /*--------------------------------------------.
304 | Prepare the muscles related to the states. |
305 `--------------------------------------------*/
308 prepare_states (void)
311 short *values
= (short *) alloca (sizeof (short) * nstates
);
312 for (i
= 0; i
< nstates
; ++i
)
313 values
[i
] = states
[i
]->accessing_symbol
;
314 output_table_data (&format_obstack
, values
,
316 muscle_insert ("stos", 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
] = -LArule
[state
->lookaheadsp
+ i
]->number
;
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
= -LArule
[state
->lookaheadsp
+ i
]->number
;
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
)
571 for (i
= 0; i
< ntokens
; ++i
)
573 symbol_t
*symbol
= symbols
[i
];
574 int number
= symbol
->user_token_number
;
576 if (number
== SALIAS
)
578 /* Skip error token. */
579 if (symbol
->number
== error_token_number
)
581 if (symbol
->tag
[0] == '\'')
582 continue; /* skip literal character */
583 if (symbol
->tag
[0] == '\"')
585 /* use literal string only if given a symbol with an alias */
587 symbol
= symbol
->alias
;
592 /* Don't #define nonliteral tokens whose names contain periods
593 or '$' (as does the default value of the EOF token). */
594 if (strchr (symbol
->tag
, '.') || strchr (symbol
->tag
, '$'))
597 fprintf (out
, "%s [[[%s]], [%d]]",
598 first
? "" : ",\n", symbol
->tag
, number
);
600 /* FIXME: This is probably wrong, and should be just as
602 fprintf (out
, "# define T%s\t%d\n", symbol
->tag
, symbol
->number
);
609 save_column (int symbol
, int default_state
)
616 int symno
= symbol
- ntokens
+ nstates
;
618 short begin
= goto_map
[symbol
];
619 short end
= goto_map
[symbol
+ 1];
622 for (i
= begin
; i
< end
; i
++)
623 if (to_state
[i
] != default_state
)
629 froms
[symno
] = sp1
= sp
= XCALLOC (short, count
);
630 tos
[symno
] = sp2
= XCALLOC (short, count
);
632 for (i
= begin
; i
< end
; i
++)
633 if (to_state
[i
] != default_state
)
635 *sp1
++ = from_state
[i
];
636 *sp2
++ = to_state
[i
];
639 tally
[symno
] = count
;
640 width
[symno
] = sp1
[-1] - sp
[0] + 1;
644 default_goto (int symbol
)
647 size_t m
= goto_map
[symbol
];
648 size_t n
= goto_map
[symbol
+ 1];
649 int default_state
= -1;
655 for (i
= 0; i
< nstates
; i
++)
658 for (i
= m
; i
< n
; i
++)
659 state_count
[to_state
[i
]]++;
661 for (i
= 0; i
< nstates
; i
++)
662 if (state_count
[i
] > max
)
664 max
= state_count
[i
];
668 return default_state
;
672 /*-------------------------------------------------------------------.
673 | Figure out what to do after reducing with each rule, depending on |
674 | the saved state from before the beginning of parsing the data that |
675 | matched this rule. |
677 | The YYDEFGOTO table is output now. The detailed info is saved for |
678 | putting into YYTABLE later. |
679 `-------------------------------------------------------------------*/
685 short *yydefgoto
= XMALLOC (short, nsyms
- ntokens
);
687 state_count
= XCALLOC (short, nstates
);
688 for (i
= ntokens
; i
< nsyms
; ++i
)
690 int default_state
= default_goto (i
);
691 save_column (i
, default_state
);
692 yydefgoto
[i
- ntokens
] = default_state
;
695 output_table_data (&format_obstack
, yydefgoto
,
696 yydefgoto
[0], 1, nsyms
- ntokens
);
697 muscle_insert ("defgoto", obstack_finish (&format_obstack
));
704 /* The next few functions decide how to pack the actions and gotos
705 information into yytable. */
712 order
= XCALLOC (short, nvectors
);
715 for (i
= 0; i
< nvectors
; i
++)
721 int j
= nentries
- 1;
723 while (j
>= 0 && (width
[order
[j
]] < w
))
726 while (j
>= 0 && (width
[order
[j
]] == w
) && (tally
[order
[j
]] < t
))
729 for (k
= nentries
- 1; k
> j
; k
--)
730 order
[k
+ 1] = order
[k
];
739 matching_state (int vector
)
741 int i
= order
[vector
];
746 if (i
>= (int) nstates
)
752 for (prev
= vector
- 1; prev
>= 0; prev
--)
758 if (width
[j
] != w
|| tally
[j
] != t
)
761 for (k
= 0; match
&& k
< t
; k
++)
762 if (tos
[j
][k
] != tos
[i
][k
] || froms
[j
][k
] != froms
[i
][k
])
774 pack_vector (int vector
)
776 int i
= order
[vector
];
780 short *from
= froms
[i
];
785 for (j
= lowzero
- from
[0]; j
< MAXTABLE
; j
++)
790 for (k
= 0; ok
&& k
< t
; k
++)
794 fatal (_("maximum table size (%d) exceeded"), MAXTABLE
);
800 for (k
= 0; ok
&& k
< vector
; k
++)
806 for (k
= 0; k
< t
; k
++)
810 check
[loc
] = from
[k
];
813 while (table
[lowzero
] != 0)
822 #define pack_vector_succeeded 0
823 assert (pack_vector_succeeded
);
835 base
= XCALLOC (short, nvectors
);
836 pos
= XCALLOC (short, nentries
);
837 table
= XCALLOC (short, MAXTABLE
);
838 check
= XCALLOC (short, MAXTABLE
);
843 for (i
= 0; i
< nvectors
; i
++)
846 for (i
= 0; i
< MAXTABLE
; i
++)
849 for (i
= 0; i
< nentries
; i
++)
851 state
= matching_state (i
);
854 place
= pack_vector (i
);
859 base
[order
[i
]] = place
;
862 for (i
= 0; i
< nvectors
; i
++)
873 /* the following functions output yytable, yycheck
874 and the vectors whose elements index the portion starts */
880 output_table_data (&format_obstack
, base
,
881 base
[0], 1, nstates
);
882 muscle_insert ("pact", obstack_finish (&format_obstack
));
885 output_table_data (&format_obstack
, base
,
886 base
[nstates
], nstates
+ 1, nvectors
);
887 muscle_insert ("pgoto", obstack_finish (&format_obstack
));
896 output_table_data (&format_obstack
, table
,
897 table
[0], 1, high
+ 1);
898 muscle_insert ("table", obstack_finish (&format_obstack
));
906 output_table_data (&format_obstack
, check
,
907 check
[0], 1, high
+ 1);
908 muscle_insert ("check", obstack_finish (&format_obstack
));
912 /*-----------------------------------------------------------------.
913 | Compute and output yydefact, yydefgoto, yypact, yypgoto, yytable |
915 `-----------------------------------------------------------------*/
918 output_actions (void)
921 nvectors
= nstates
+ nvars
;
923 froms
= XCALLOC (short *, nvectors
);
924 tos
= XCALLOC (short *, nvectors
);
925 tally
= XCALLOC (short, nvectors
);
926 width
= XCALLOC (short, nvectors
);
933 XFREE (goto_map
+ ntokens
);
945 for (i
= 0; i
< nstates
; ++i
)
947 free (states
[i
]->shifts
);
948 XFREE (states
[i
]->reductions
);
949 free (states
[i
]->errs
);
956 /*---------------------------.
957 | Call the skeleton parser. |
958 `---------------------------*/
961 output_skeleton (void)
963 /* Store the definition of all the muscles. */
964 const char *tempdir
= getenv ("TMPDIR");
965 char *tempfile
= NULL
;
970 tempdir
= DEFAULT_TMPDIR
;
971 tempfile
= xmalloc (strlen (tempdir
) + 11);
972 sprintf (tempfile
, "%s/bsnXXXXXX", tempdir
);
973 fd
= mkstemp (tempfile
);
975 error (EXIT_FAILURE
, errno
, "%s", tempfile
);
977 out
= fdopen (fd
, "w");
979 error (EXIT_FAILURE
, errno
, "%s", tempfile
);
981 /* There are no comments, especially not `#': we do want M4 expansion
982 after `#': think of CPP macros! */
983 fputs ("m4_changecom()\n", out
);
984 fputs ("m4_init()\n", out
);
986 fputs ("m4_define([b4_actions], \n[[", out
);
987 actions_output (out
);
988 fputs ("]])\n\n", out
);
990 fputs ("m4_define([b4_guards], \n[[", out
);
992 fputs ("]])\n\n", out
);
994 fputs ("m4_define([b4_tokens], \n[", out
);
995 token_definitions_output (out
);
996 fputs ("])\n\n", out
);
998 muscles_m4_output (out
);
1000 fputs ("m4_wrap([m4_divert_pop(0)])\n", out
);
1001 fputs ("m4_divert_push(0)dnl\n", out
);
1004 /* Invoke m4 on the definition of the muscles, and the skeleton. */
1006 const char *bison_pkgdatadir
= getenv ("BISON_PKGDATADIR");
1007 const char *m4
= getenv ("M4");
1010 if (!bison_pkgdatadir
)
1011 bison_pkgdatadir
= PKGDATADIR
;
1014 "running: %s -I %s m4sugar/m4sugar.m4 %s %s\n",
1015 m4
, bison_pkgdatadir
, tempfile
, skeleton
);
1016 skel_in
= readpipe (m4
,
1017 "-I", bison_pkgdatadir
,
1018 "m4sugar/m4sugar.m4",
1023 error (EXIT_FAILURE
, errno
, "cannot run m4");
1026 /* If `debugging', keep this file alive. */
1035 MUSCLE_INSERT_INT ("last", high
);
1036 MUSCLE_INSERT_INT ("flag", MINSHORT
);
1037 MUSCLE_INSERT_INT ("pure", pure_parser
);
1038 MUSCLE_INSERT_INT ("nsym", nsyms
);
1039 MUSCLE_INSERT_INT ("debug", debug_flag
);
1040 MUSCLE_INSERT_INT ("final", final_state
);
1041 MUSCLE_INSERT_INT ("maxtok", max_user_token_number
);
1042 MUSCLE_INSERT_INT ("error_verbose", error_verbose
);
1043 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix
? spec_name_prefix
: "yy");
1045 /* FIXME: This is wrong: the muscles should decide whether they hold
1046 a copy or not, but the situation is too obscure currently. */
1047 MUSCLE_INSERT_STRING ("output_infix", output_infix
? output_infix
: "");
1048 MUSCLE_INSERT_STRING ("output_prefix", short_base_name
);
1049 MUSCLE_INSERT_STRING ("output_parser_name", parser_file_name
);
1050 MUSCLE_INSERT_STRING ("output_header_name", spec_defines_file
);
1052 MUSCLE_INSERT_INT ("nnts", nvars
);
1053 MUSCLE_INSERT_INT ("nrules", nrules
);
1054 MUSCLE_INSERT_INT ("nstates", nstates
);
1055 MUSCLE_INSERT_INT ("ntokens", ntokens
);
1057 MUSCLE_INSERT_INT ("locations_flag", locations_flag
);
1058 MUSCLE_INSERT_INT ("defines_flag", defines_flag
);
1060 /* Copy definitions in directive. */
1061 obstack_1grow (&attrs_obstack
, 0);
1062 muscle_insert ("prologue", obstack_finish (&attrs_obstack
));
1064 /* Find the right skeleton file. */
1067 if (semantic_parser
)
1068 skeleton
= "bison.hairy";
1070 skeleton
= "bison.simple";
1073 /* Parse the skeleton file and output the needed parsers. */
1074 muscle_insert ("skeleton", skeleton
);
1078 /*----------------------------------------------------------.
1079 | Output the parsing tables and the parser code to ftable. |
1080 `----------------------------------------------------------*/
1085 obstack_init (&format_obstack
);
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
);