]> git.saurik.com Git - bison.git/blame - src/output.c
Restore --no-lines.
[bison.git] / src / output.c
CommitLineData
c3e23647 1/* Output the generated parsing program for bison,
5bb18f9a 2 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
255ef638 3 Free Software Foundation, Inc.
c3e23647 4
9ee3c97b 5 This file is part of Bison, the GNU Compiler Compiler.
c3e23647 6
9ee3c97b
AD
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)
10 any later version.
c3e23647 11
9ee3c97b
AD
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.
c3e23647 16
9ee3c97b
AD
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
20 02111-1307, USA. */
c3e23647
RS
21
22
c3e23647 23#include "system.h"
14d3eb9b 24#include "quotearg.h"
be2a1a68 25#include "error.h"
573312ac 26#include "subpipe.h"
ceed8467 27#include "getargs.h"
c3e23647
RS
28#include "files.h"
29#include "gram.h"
a0f6b076 30#include "complain.h"
6c89f1c1 31#include "output.h"
a70083a3 32#include "reader.h"
ad949da9 33#include "symtab.h"
c6f1a33c 34#include "tables.h"
11d82f03 35#include "muscle_tab.h"
be2a1a68 36
be2a1a68 37/* From src/scan-skel.l. */
573312ac 38void scan_skel (FILE *);
d019d655 39
12b0043a 40
f87685c3 41static struct obstack format_obstack;
c3e23647 42
c7925b99
MA
43int error_verbose = 0;
44
f0440388 45
133c20e2 46
5372019f
AD
47/*-------------------------------------------------------------------.
48| Create a function NAME which associates to the muscle NAME the |
49| result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of |
50| TYPE), and to the muscle NAME_max, the max value of the |
51| TABLE_DATA. |
52`-------------------------------------------------------------------*/
62a3e4f0 53
62a3e4f0 54
5372019f 55#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
5fbb0954 56 \
5372019f
AD
57static void \
58Name (const char *name, \
5fbb0954
AD
59 Type *table_data, \
60 Type first, \
61 int begin, \
62 int end) \
63{ \
12b0043a 64 Type min = first; \
0c2d3f4c 65 Type max = first; \
5fbb0954
AD
66 int i; \
67 int j = 1; \
68 \
5372019f 69 obstack_fgrow1 (&format_obstack, "%6d", first); \
5fbb0954
AD
70 for (i = begin; i < end; ++i) \
71 { \
5372019f 72 obstack_1grow (&format_obstack, ','); \
5fbb0954
AD
73 if (j >= 10) \
74 { \
5372019f 75 obstack_sgrow (&format_obstack, "\n "); \
5fbb0954
AD
76 j = 1; \
77 } \
78 else \
79 ++j; \
5372019f 80 obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \
12b0043a
AD
81 if (table_data[i] < min) \
82 min = table_data[i]; \
83 if (max < table_data[i]) \
5fbb0954
AD
84 max = table_data[i]; \
85 } \
5372019f
AD
86 obstack_1grow (&format_obstack, 0); \
87 muscle_insert (name, obstack_finish (&format_obstack)); \
5fbb0954 88 \
12b0043a
AD
89 /* Build `NAME_min' and `NAME_max' in the obstack. */ \
90 obstack_fgrow1 (&format_obstack, "%s_min", name); \
91 obstack_1grow (&format_obstack, 0); \
92 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), \
93 (long int) min); \
5372019f
AD
94 obstack_fgrow1 (&format_obstack, "%s_max", name); \
95 obstack_1grow (&format_obstack, 0); \
0c2d3f4c
AD
96 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), \
97 (long int) max); \
62a3e4f0
AD
98}
99
5372019f 100GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int)
12b0043a 101GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table, int)
5372019f 102GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_short_table, short)
12b0043a
AD
103GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_t)
104GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number_t)
a49aecd5 105GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number_t)
5372019f 106GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number_t)
d57650a5 107GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number_t)
c3e23647
RS
108
109
39912f52
AD
110/*------------------------------------------------------------------.
111| Prepare the muscles related to the symbols: translate, tname, and |
112| toknum. |
113`------------------------------------------------------------------*/
b0940840 114
4a120d45 115static void
39912f52 116prepare_symbols (void)
c3e23647 117{
39912f52
AD
118 MUSCLE_INSERT_INT ("tokens_number", ntokens);
119 MUSCLE_INSERT_INT ("nterms_number", nvars);
120 MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
121 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
122
a49aecd5 123 muscle_insert_symbol_number_table ("translate",
fc5734fe
AD
124 token_translations,
125 token_translations[0],
126 1, max_user_token_number + 1);
c3e23647 127
39912f52 128 /* tname -- token names. */
b0940840
AD
129 {
130 int i;
131 int j = 0;
132 for (i = 0; i < nsyms; i++)
133 {
6b98e4b5
AD
134 /* Be sure not to use twice the same QUOTEARG slot:
135 SYMBOL_TAG_GET uses slot 0. */
b0940840
AD
136 const char *cp =
137 quotearg_n_style (1, c_quoting_style,
97650f4e 138 symbols[i]->tag);
01cfa697 139 /* Width of the next token, including the two quotes, the comma
b0940840
AD
140 and the space. */
141 int strsize = strlen (cp) + 2;
142
143 if (j + strsize > 75)
144 {
145 obstack_sgrow (&format_obstack, "\n ");
146 j = 2;
147 }
148
01cfa697
PE
149 for (; *cp; cp++)
150 switch (*cp)
151 {
152 case '[': obstack_sgrow (&format_obstack, "@<:@"); break;
153 case ']': obstack_sgrow (&format_obstack, "@:>@"); break;
154 default: obstack_1grow (&format_obstack, *cp); break;
155 }
156
b0940840
AD
157 obstack_sgrow (&format_obstack, ", ");
158 j += strsize;
159 }
160 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
161 defined). */
162 obstack_sgrow (&format_obstack, "0");
c3e23647 163
b0940840
AD
164 /* Finish table and store. */
165 obstack_1grow (&format_obstack, 0);
166 muscle_insert ("tname", obstack_finish (&format_obstack));
167 }
168
12b0043a 169 /* Output YYTOKNUM. */
b2ed6e58
AD
170 {
171 int i;
3650b4b8
AD
172 int *values = XCALLOC (int, ntokens);
173 for (i = 0; i < ntokens; ++i)
b0940840 174 values[i] = symbols[i]->user_token_number;
12b0043a 175 muscle_insert_int_table ("toknum", values,
3650b4b8 176 values[0], 1, ntokens);
b0940840 177 free (values);
b2ed6e58 178 }
b0940840 179}
b2ed6e58 180
b0940840
AD
181
182/*-------------------------------------------------------------.
183| Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
676385e2 184| rline, dprec, merger |
b0940840
AD
185`-------------------------------------------------------------*/
186
187static void
188prepare_rules (void)
189{
9222837b 190 rule_number_t r;
5df5f6d5 191 unsigned int i = 0;
62a3e4f0 192 item_number_t *rhs = XMALLOC (item_number_t, nritems);
4b3d3a8e
AD
193 unsigned int *prhs = XMALLOC (unsigned int, nrules);
194 unsigned int *rline = XMALLOC (unsigned int, nrules);
195 symbol_number_t *r1 = XMALLOC (symbol_number_t, nrules);
196 unsigned int *r2 = XMALLOC (unsigned int, nrules);
197 short *dprec = XMALLOC (short, nrules);
198 short *merger = XMALLOC (short, nrules);
199
200 for (r = 0; r < nrules; ++r)
b0940840 201 {
9222837b 202 item_number_t *rhsp = NULL;
b0940840
AD
203 /* Index of rule R in RHS. */
204 prhs[r] = i;
205 /* RHS of the rule R. */
206 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
207 rhs[i++] = *rhsp;
208 /* LHS of the rule R. */
209 r1[r] = rules[r].lhs->number;
210 /* Length of rule R's RHS. */
211 r2[r] = i - prhs[r];
212 /* Separator in RHS. */
213 rhs[i++] = -1;
214 /* Line where rule was defined. */
8efe435c 215 rline[r] = rules[r].location.first_line;
676385e2
PH
216 /* Dynamic precedence (GLR) */
217 dprec[r] = rules[r].dprec;
218 /* Merger-function index (GLR) */
219 merger[r] = rules[r].merger;
b0940840
AD
220 }
221 assert (i == nritems);
222
5372019f 223 muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
4b3d3a8e
AD
224 muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules);
225 muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
226 muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
227 muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
228 muscle_insert_short_table ("dprec", dprec, 0, 0, nrules);
229 muscle_insert_short_table ("merger", merger, 0, 0, nrules);
796d61fb 230
39912f52
AD
231 MUSCLE_INSERT_INT ("rules_number", nrules);
232
b0940840
AD
233 free (rhs);
234 free (prhs);
5df5f6d5
AD
235 free (rline);
236 free (r1);
b0940840 237 free (r2);
676385e2
PH
238 free (dprec);
239 free (merger);
c3e23647
RS
240}
241
b0940840
AD
242/*--------------------------------------------.
243| Prepare the muscles related to the states. |
244`--------------------------------------------*/
c3e23647 245
4a120d45 246static void
b0940840 247prepare_states (void)
c3e23647 248{
d57650a5 249 state_number_t i;
a49aecd5
AD
250 symbol_number_t *values =
251 (symbol_number_t *) alloca (sizeof (symbol_number_t) * nstates);
9703cc49 252 for (i = 0; i < nstates; ++i)
29e88316 253 values[i] = states[i]->accessing_symbol;
a49aecd5 254 muscle_insert_symbol_number_table ("stos", values,
d57650a5 255 0, 1, nstates);
39912f52
AD
256
257 MUSCLE_INSERT_INT ("last", high);
258 MUSCLE_INSERT_INT ("final_state_number", final_state->number);
259 MUSCLE_INSERT_INT ("states_number", nstates);
c3e23647
RS
260}
261
262
c3e23647 263
bb33f19a
PE
264/*---------------------------------.
265| Output the user actions to OUT. |
266`---------------------------------*/
12b0043a 267
4a120d45 268static void
c6f1a33c 269user_actions_output (FILE *out)
3f96f4dc 270{
9222837b 271 rule_number_t r;
dafdc66f
AD
272
273 fputs ("m4_define([b4_actions], \n[[", out);
4b3d3a8e 274 for (r = 0; r < nrules; ++r)
9222837b 275 if (rules[r].action)
3f96f4dc 276 {
4b3d3a8e 277 fprintf (out, " case %d:\n", r + 1);
3f96f4dc 278
437c2d80
AD
279 fprintf (out, "]b4_syncline([[%d]], [[%s]])[\n",
280 rules[r].action_location.first_line,
281 quotearg_style (escape_quoting_style,
282 rules[r].action_location.file));
e9955c83 283 fprintf (out, " %s\n break;\n\n",
9222837b 284 rules[r].action);
3f96f4dc 285 }
dafdc66f 286 fputs ("]])\n\n", out);
3f96f4dc
AD
287}
288
676385e2
PH
289/*--------------------------------------.
290| Output the merge functions to OUT. |
291`--------------------------------------*/
292
41442480 293static void
676385e2
PH
294merger_output (FILE *out)
295{
296 int n;
297 merger_list* p;
298
299 fputs ("m4_define([b4_mergers], \n[[", out);
e0e5bf84 300 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
676385e2 301 {
e0e5bf84 302 if (p->type[0] == '\0')
676385e2
PH
303 fprintf (out, " case %d: yyval = %s (*yy0, *yy1); break;\n",
304 n, p->name);
305 else
306 fprintf (out, " case %d: yyval.%s = %s (*yy0, *yy1); break;\n",
307 n, p->type, p->name);
308 }
309 fputs ("]])\n\n", out);
310}
3f96f4dc 311
ae7453f2
AD
312/*--------------------------------------.
313| Output the tokens definition to OUT. |
314`--------------------------------------*/
091e20bb 315
c6f1a33c 316static void
be2a1a68 317token_definitions_output (FILE *out)
091e20bb
AD
318{
319 int i;
0d8bed56 320 int first = 1;
dafdc66f
AD
321
322 fputs ("m4_define([b4_tokens], \n[", out);
091e20bb
AD
323 for (i = 0; i < ntokens; ++i)
324 {
db8837cb 325 symbol_t *symbol = symbols[i];
091e20bb
AD
326 int number = symbol->user_token_number;
327
b87f8b21
AD
328 /* At this stage, if there are literal aliases, they are part of
329 SYMBOLS, so we should not find symbols which are the aliases
330 here. */
331 assert (number != USER_NUMBER_ALIAS);
332
091e20bb 333 /* Skip error token. */
007a50a4 334 if (symbol == errtoken)
091e20bb 335 continue;
b87f8b21
AD
336
337 /* If this string has an alias, then it is necessarily the alias
338 which is to be output. */
339 if (symbol->alias)
340 symbol = symbol->alias;
341
342 /* Don't output literal chars or strings (when defined only as a
343 string). Note that must be done after the alias resolution:
344 think about `%token 'f' "f"'. */
345 if (symbol->tag[0] == '\'' || symbol->tag[0] == '\"')
346 continue;
091e20bb
AD
347
348 /* Don't #define nonliteral tokens whose names contain periods
349 or '$' (as does the default value of the EOF token). */
350 if (strchr (symbol->tag, '.') || strchr (symbol->tag, '$'))
351 continue;
352
83ccf991 353 fprintf (out, "%s[[[%s]], [%d]]",
0d8bed56 354 first ? "" : ",\n", symbol->tag, number);
b87f8b21 355
0d8bed56 356 first = 0;
091e20bb 357 }
dafdc66f 358 fputs ("])\n\n", out);
091e20bb
AD
359}
360
361
ae7453f2
AD
362/*---------------------------------------.
363| Output the symbol destructors to OUT. |
364`---------------------------------------*/
9280d3ef
AD
365
366static void
367symbol_destructors_output (FILE *out)
368{
369 int i;
370 int first = 1;
371
372 fputs ("m4_define([b4_symbol_destructors], \n[", out);
373 for (i = 0; i < nsyms; ++i)
374 if (symbols[i]->destructor)
375 {
376 symbol_t *symbol = symbols[i];
377
24c0aad7
AD
378 /* Filename, lineno,
379 Symbol-name, Symbol-number,
380 destructor, typename. */
381 fprintf (out, "%s[[[%s]], [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
9280d3ef 382 first ? "" : ",\n",
900c5db5
AD
383 symbol->destructor_location.file,
384 symbol->destructor_location.first_line,
97650f4e 385 symbol->tag,
24c0aad7
AD
386 symbol->number,
387 symbol->destructor,
388 symbol->type_name);
9280d3ef
AD
389
390 first = 0;
391 }
392 fputs ("])\n\n", out);
393}
394
395
ae7453f2
AD
396/*------------------------------------.
397| Output the symbol printers to OUT. |
398`------------------------------------*/
366eea36
AD
399
400static void
401symbol_printers_output (FILE *out)
402{
403 int i;
404 int first = 1;
405
406 fputs ("m4_define([b4_symbol_printers], \n[", out);
407 for (i = 0; i < nsyms; ++i)
408 if (symbols[i]->destructor)
409 {
410 symbol_t *symbol = symbols[i];
411
412 /* Filename, lineno,
413 Symbol-name, Symbol-number,
ae7453f2 414 printer, typename. */
366eea36
AD
415 fprintf (out, "%s[[[%s]], [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
416 first ? "" : ",\n",
900c5db5
AD
417 symbol->printer_location.file,
418 symbol->printer_location.first_line,
97650f4e 419 symbol->tag,
366eea36
AD
420 symbol->number,
421 symbol->printer,
422 symbol->type_name);
423
424 first = 0;
425 }
426 fputs ("])\n\n", out);
427}
428
429
4a120d45 430static void
c6f1a33c 431prepare_actions (void)
6c89f1c1 432{
c6f1a33c
AD
433 /* Figure out the actions for the specified state, indexed by
434 lookahead token type. */
bbb5bcc6 435
c6f1a33c
AD
436 muscle_insert_rule_number_table ("defact", yydefact,
437 yydefact[0], 1, nstates);
6c89f1c1 438
c6f1a33c
AD
439 /* Figure out what to do after reducing with each rule, depending on
440 the saved state from before the beginning of parsing the data
441 that matched this rule. */
d57650a5
AD
442 muscle_insert_state_number_table ("defgoto", yydefgoto,
443 yydefgoto[0], 1, nsyms - ntokens);
12b0043a 444
12b0043a 445
12b0043a
AD
446 /* Output PACT. */
447 muscle_insert_base_table ("pact", base,
5372019f 448 base[0], 1, nstates);
12b0043a 449 MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
c3e23647 450
12b0043a
AD
451 /* Output PGOTO. */
452 muscle_insert_base_table ("pgoto", base,
5372019f 453 base[nstates], nstates + 1, nvectors);
c3e23647 454
12b0043a
AD
455 muscle_insert_base_table ("table", table,
456 table[0], 1, high + 1);
457 MUSCLE_INSERT_INT ("table_ninf", table_ninf);
676385e2 458
12b0043a
AD
459 muscle_insert_base_table ("check", check,
460 check[0], 1, high + 1);
c3e23647 461
ea99527d
AD
462 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
463 YYPACT) so that in states with unresolved conflicts, the default
464 reduction is not used in the conflicted entries, so that there is
465 a place to put a conflict pointer.
466
467 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
468 parser, so we could avoid accidents by not writing them out in
469 that case. Nevertheless, it seems even better to be able to use
470 the GLR skeletons even without the non-deterministic tables. */
471 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
39912f52 472 conflict_table[0], 1, high + 1);
ea99527d
AD
473 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
474 conflict_list[0], 1, conflict_list_cnt);
6c89f1c1 475}
c3e23647 476
652def80 477\f
1239777d
AD
478/*---------------------------.
479| Call the skeleton parser. |
480`---------------------------*/
c3e23647 481
4a120d45 482static void
1239777d 483output_skeleton (void)
9b3add5b 484{
573312ac
PE
485 FILE *in;
486 FILE *out;
487 int filter_fd[2];
488 char const *argv[7];
489 pid_t pid;
490
491 /* Compute the names of the package data dir and skeleton file.
492 Test whether m4sugar.m4 is readable, to check for proper
493 installation. A faulty installation can cause deadlock, so a
494 cheap sanity check is worthwhile. */
495 char const m4sugar[] = "m4sugar/m4sugar.m4";
496 char *full_path;
497 char const *p;
498 char const *m4 = (p = getenv ("M4")) ? p : M4;
499 char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR;
500 size_t skeleton_size = strlen (skeleton) + 1;
501 size_t pkgdatadirlen = strlen (pkgdatadir);
502 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
503 pkgdatadirlen--;
504 full_path = xmalloc (pkgdatadirlen + 1
505 + (skeleton_size < sizeof m4sugar
506 ? sizeof m4sugar : skeleton_size));
507 strcpy (full_path, pkgdatadir);
508 full_path[pkgdatadirlen] = '/';
509 strcpy (full_path + pkgdatadirlen + 1, m4sugar);
510 in = fopen (full_path, "r");
30ba05f2 511 if (! in)
573312ac 512 error (EXIT_FAILURE, errno, "%s", full_path);
30ba05f2 513 xfclose (in);
573312ac
PE
514 strcpy (full_path + pkgdatadirlen + 1, skeleton);
515
516 /* Create an m4 subprocess connected to us via two pipes. */
517
518 if (trace_flag & trace_tools)
519 fprintf (stderr, "running: %s -I %s %s - %s\n",
520 m4, pkgdatadir, m4sugar, full_path);
521
522 argv[0] = m4;
523 argv[1] = "-I";
524 argv[2] = pkgdatadir;
525 argv[3] = m4sugar;
526 argv[4] = "-";
527 argv[5] = full_path;
528 argv[6] = NULL;
529
530 init_subpipe ();
531 pid = create_subpipe (argv, filter_fd);
532 free (full_path);
533
534 out = fdopen (filter_fd[0], "w");
535 if (! out)
536 error (EXIT_FAILURE, errno, "fdopen");
537
538 /* Output the definitions of all the muscles. */
381fb12e
AD
539 fputs ("m4_init()\n", out);
540
c6f1a33c 541 user_actions_output (out);
676385e2 542 merger_output (out);
381fb12e 543 token_definitions_output (out);
9280d3ef 544 symbol_destructors_output (out);
366eea36 545 symbol_printers_output (out);
be2a1a68 546
381fb12e 547 muscles_m4_output (out);
be2a1a68 548
381fb12e
AD
549 fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
550 fputs ("m4_divert_push(0)dnl\n", out);
551 xfclose (out);
be2a1a68 552
573312ac 553 /* Read and process m4's output. */
1509d42f 554 timevar_push (TV_M4);
573312ac
PE
555 in = fdopen (filter_fd[1], "r");
556 if (! in)
557 error (EXIT_FAILURE, errno, "fdopen");
558 scan_skel (in);
573312ac
PE
559 xfclose (in);
560 reap_subpipe (pid, m4);
1509d42f 561 timevar_pop (TV_M4);
26f609ff
RA
562}
563
564static void
565prepare (void)
566{
7db2ed2d 567 /* Flags. */
437c2d80 568 MUSCLE_INSERT_INT ("debug", debug_flag);
7db2ed2d
AD
569 MUSCLE_INSERT_INT ("defines_flag", defines_flag);
570 MUSCLE_INSERT_INT ("error_verbose", error_verbose);
437c2d80 571 MUSCLE_INSERT_INT ("locations_flag", locations_flag);
11d82f03 572 MUSCLE_INSERT_INT ("pure", pure_parser);
437c2d80 573 MUSCLE_INSERT_INT ("synclines_flag", !no_lines_flag);
11d82f03 574
b85810ae
AD
575 /* FIXME: This is wrong: the muscles should decide whether they hold
576 a copy or not, but the situation is too obscure currently. */
7db2ed2d 577 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
be2a1a68
AD
578 MUSCLE_INSERT_STRING ("output_infix", output_infix ? output_infix : "");
579 MUSCLE_INSERT_STRING ("output_prefix", short_base_name);
580 MUSCLE_INSERT_STRING ("output_parser_name", parser_file_name);
581 MUSCLE_INSERT_STRING ("output_header_name", spec_defines_file);
b85810ae 582
7db2ed2d 583 /* User Code. */
0dd1580a
RA
584 obstack_1grow (&pre_prologue_obstack, 0);
585 obstack_1grow (&post_prologue_obstack, 0);
586 muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack));
587 muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack));
381fb12e
AD
588
589 /* Find the right skeleton file. */
590 if (!skeleton)
676385e2
PH
591 {
592 if (glr_parser)
593 skeleton = "glr.c";
594 else
595 skeleton = "yacc.c";
596 }
381fb12e
AD
597
598 /* Parse the skeleton file and output the needed parsers. */
66d30cd4 599 MUSCLE_INSERT_STRING ("skeleton", skeleton);
26f609ff 600}
c3e23647 601
93ede233 602
6c89f1c1
AD
603/*----------------------------------------------------------.
604| Output the parsing tables and the parser code to ftable. |
605`----------------------------------------------------------*/
c3e23647 606
6c89f1c1
AD
607void
608output (void)
609{
f87685c3 610 obstack_init (&format_obstack);
dd60faec 611
39912f52 612 prepare_symbols ();
b0940840
AD
613 prepare_rules ();
614 prepare_states ();
536545f3 615 prepare_actions ();
342b8b6e 616
26f609ff 617 prepare ();
652def80 618
9b3add5b
RA
619 /* Process the selected skeleton file. */
620 output_skeleton ();
621
f499b062 622 obstack_free (&format_obstack, NULL);
0dd1580a
RA
623 obstack_free (&pre_prologue_obstack, NULL);
624 obstack_free (&post_prologue_obstack, NULL);
c3e23647 625}