1/* Output the generated parsing program for Bison.
2
3 Copyright (C) 1984, 1986, 1989, 1992, 2000-2015, 2018-2019 Free
4 Software Foundation, Inc.
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21#include <config.h>
22#include "system.h"
23
24#include <filename.h> /* IS_PATH_WITH_DIR */
25#include <get-errno.h>
26#include <path-join.h>
27#include <quotearg.h>
28#include <spawn-pipe.h>
29#include <timevar.h>
30#include <wait-process.h>
31
32#include "complain.h"
33#include "files.h"
34#include "getargs.h"
35#include "gram.h"
36#include "muscle-tab.h"
37#include "output.h"
38#include "reader.h"
39#include "reduce.h"
40#include "scan-code.h" /* max_left_semantic_context */
41#include "scan-skel.h"
42#include "symtab.h"
43#include "tables.h"
44
45static struct obstack format_obstack;
46
47
48/*-------------------------------------------------------------------.
49| Create a function NAME which associates to the muscle NAME the |
50| result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of |
51| TYPE), and to the muscle NAME_max, the max value of the |
52| TABLE_DATA. |
53`-------------------------------------------------------------------*/
54
55
56#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
57 \
58static void \
59Name (char const *name, Type *table_data, Type first, \
60 int begin, int end) \
61{ \
62 Type min = first; \
63 Type max = first; \
64 int j = 1; \
65 \
66 obstack_printf (&format_obstack, "%6d", first); \
67 for (int i = begin; i < end; ++i) \
68 { \
69 obstack_1grow (&format_obstack, ','); \
70 if (j >= 10) \
71 { \
72 obstack_sgrow (&format_obstack, "\n "); \
73 j = 1; \
74 } \
75 else \
76 ++j; \
77 obstack_printf (&format_obstack, "%6d", table_data[i]); \
78 if (table_data[i] < min) \
79 min = table_data[i]; \
80 if (max < table_data[i]) \
81 max = table_data[i]; \
82 } \
83 muscle_insert (name, obstack_finish0 (&format_obstack)); \
84 \
85 long lmin = min; \
86 long lmax = max; \
87 /* Build 'NAME_min' and 'NAME_max' in the obstack. */ \
88 obstack_printf (&format_obstack, "%s_min", name); \
89 MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmin); \
90 obstack_printf (&format_obstack, "%s_max", name); \
91 MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmax); \
92}
93
94GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_unsigned_table, unsigned)
95GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_int_table, int)
96GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_base_table, base_number)
97GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_rule_number_table, rule_number)
98GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_symbol_number_table, symbol_number)
99GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_item_number_table, item_number)
100GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_state_number_table, state_number)
101
102/*----------------------------------------------------------------.
103| Print to OUT a representation of CP quoted and escaped for M4. |
104`----------------------------------------------------------------*/
105
106static void
107quoted_output (FILE *out, char const *cp)
108{
109 fprintf (out, "[[");
110
111 for (; *cp; cp++)
112 switch (*cp)
113 {
114 case '$': fputs ("$][", out); break;
115 case '@': fputs ("@@", out); break;
116 case '[': fputs ("@{", out); break;
117 case ']': fputs ("@}", out); break;
118 default: fputc (*cp, out); break;
119 }
120
121 fprintf (out, "]]");
122}
123
124/*----------------------------------------------------------------.
125| Print to OUT a representation of STRING quoted and escaped both |
126| for C and M4. |
127`----------------------------------------------------------------*/
128
129static void
130string_output (FILE *out, char const *string)
131{
132 quoted_output (out, quotearg_style (c_quoting_style, string));
133}
134
135
136/* Generate the b4_<MUSCLE_NAME> (e.g., b4_tname) table with the
137 symbol names (aka tags). */
138
139static void
140prepare_symbol_names (char const *muscle_name)
141{
142 /* We assume that the table will be output starting at column 2. */
143 int j = 2;
144 struct quoting_options *qo = clone_quoting_options (0);
145 set_quoting_style (qo, c_quoting_style);
146 set_quoting_flags (qo, QA_SPLIT_TRIGRAPHS);
147 for (int i = 0; i < nsyms; i++)
148 {
149 char *cp = quotearg_alloc (symbols[i]->tag, -1, qo);
150 /* Width of the next token, including the two quotes, the
151 comma and the space. */
152 int width = strlen (cp) + 2;
153
154 if (j + width > 75)
155 {
156 obstack_sgrow (&format_obstack, "\n ");
157 j = 1;
158 }
159
160 if (i)
161 obstack_1grow (&format_obstack, ' ');
162 obstack_escape (&format_obstack, cp);
163 free (cp);
164 obstack_1grow (&format_obstack, ',');
165 j += width;
166 }
167 free (qo);
168 obstack_sgrow (&format_obstack, " ]b4_null[");
169
170 /* Finish table and store. */
171 muscle_insert (muscle_name, obstack_finish0 (&format_obstack));
172}
173
174
175/*------------------------------------------------------------------.
176| Prepare the muscles related to the symbols: translate, tname, and |
177| toknum. |
178`------------------------------------------------------------------*/
179
180static void
181prepare_symbols (void)
182{
183 MUSCLE_INSERT_INT ("tokens_number", ntokens);
184 MUSCLE_INSERT_INT ("nterms_number", nvars);
185 MUSCLE_INSERT_INT ("symbols_number", nsyms);
186 MUSCLE_INSERT_INT ("undef_token_number", undeftoken->content->number);
187 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
188
189 muscle_insert_symbol_number_table ("translate",
190 token_translations,
191 token_translations[0],
192 1, max_user_token_number + 1);
193
194 /* tname -- token names. */
195 prepare_symbol_names ("tname");
196
197 /* Output YYTOKNUM. */
198 {
199 int *values = xnmalloc (ntokens, sizeof *values);
200 for (int i = 0; i < ntokens; ++i)
201 values[i] = symbols[i]->content->user_token_number;
202 muscle_insert_int_table ("toknum", values,
203 values[0], 1, ntokens);
204 free (values);
205 }
206}
207
208
209/*-------------------------------------------------------------.
210| Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
211| rline, dprec, merger, immediate. |
212`-------------------------------------------------------------*/
213
214static void
215prepare_rules (void)
216{
217 unsigned *prhs = xnmalloc (nrules, sizeof *prhs);
218 item_number *rhs = xnmalloc (nritems, sizeof *rhs);
219 unsigned *rline = xnmalloc (nrules, sizeof *rline);
220 symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
221 unsigned *r2 = xnmalloc (nrules, sizeof *r2);
222 int *dprec = xnmalloc (nrules, sizeof *dprec);
223 int *merger = xnmalloc (nrules, sizeof *merger);
224 int *immediate = xnmalloc (nrules, sizeof *immediate);
225
226 /* Index in RHS. */
227 unsigned i = 0;
228 for (rule_number r = 0; r < nrules; ++r)
229 {
230 /* Index of rule R in RHS. */
231 prhs[r] = i;
232 /* RHS of the rule R. */
233 for (item_number *rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
234 rhs[i++] = *rhsp;
235 /* Separator in RHS. */
236 rhs[i++] = -1;
237
238 /* Line where rule was defined. */
239 rline[r] = rules[r].location.start.line;
240 /* LHS of the rule R. */
241 r1[r] = rules[r].lhs->number;
242 /* Length of rule R's RHS. */
243 r2[r] = rule_rhs_length (&rules[r]);
244 /* Dynamic precedence (GLR). */
245 dprec[r] = rules[r].dprec;
246 /* Merger-function index (GLR). */
247 merger[r] = rules[r].merger;
248 /* Immediate reduction flags (GLR). */
249 immediate[r] = rules[r].is_predicate;
250 }
251 aver (i == nritems);
252
253 muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
254 muscle_insert_unsigned_table ("prhs", prhs, 0, 0, nrules);
255 muscle_insert_unsigned_table ("rline", rline, 0, 0, nrules);
256 muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
257 muscle_insert_unsigned_table ("r2", r2, 0, 0, nrules);
258 muscle_insert_int_table ("dprec", dprec, 0, 0, nrules);
259 muscle_insert_int_table ("merger", merger, 0, 0, nrules);
260 muscle_insert_int_table ("immediate", immediate, 0, 0, nrules);
261
262 MUSCLE_INSERT_INT ("rules_number", nrules);
263 MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
264
265 free (prhs);
266 free (rhs);
267 free (rline);
268 free (r1);
269 free (r2);
270 free (dprec);
271 free (merger);
272 free (immediate);
273}
274
275/*--------------------------------------------.
276| Prepare the muscles related to the states. |
277`--------------------------------------------*/
278
279static void
280prepare_states (void)
281{
282 symbol_number *values = xnmalloc (nstates, sizeof *values);
283 for (state_number i = 0; i < nstates; ++i)
284 values[i] = states[i]->accessing_symbol;
285 muscle_insert_symbol_number_table ("stos", values,
286 0, 1, nstates);
287 free (values);
288
289 MUSCLE_INSERT_INT ("last", high);
290 MUSCLE_INSERT_INT ("final_state_number", final_state->number);
291 MUSCLE_INSERT_INT ("states_number", nstates);
292}
293
294
295/*-------------------------------------------------------.
296| Compare two symbols by type-name, and then by number. |
297`-------------------------------------------------------*/
298
299static int
300symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
301{
302 int res = uniqstr_cmp ((*lhs)->content->type_name, (*rhs)->content->type_name);
303 if (!res)
304 res = (*lhs)->content->number - (*rhs)->content->number;
305 return res;
306}
307
308
309/*----------------------------------------------------------------.
310| Return a (malloc'ed) table of the symbols sorted by type-name. |
311`----------------------------------------------------------------*/
312
313static symbol **
314symbols_by_type_name (void)
315{
316 typedef int (*qcmp_type) (const void *, const void *);
317 symbol **res = xmemdup (symbols, nsyms * sizeof *res);
318 qsort (res, nsyms, sizeof *res, (qcmp_type) &symbol_type_name_cmp);
319 return res;
320}
321
322
323/*------------------------------------------------------------------.
324| Define b4_type_names, which is a list of (lists of the numbers of |
325| symbols with same type-name). |
326`------------------------------------------------------------------*/
327
328static void
329type_names_output (FILE *out)
330{
331 symbol **syms = symbols_by_type_name ();
332 fputs ("m4_define([b4_type_names],\n[", out);
333 for (int i = 0; i < nsyms; /* nothing */)
334 {
335 /* The index of the first symbol of the current type-name. */
336 int i0 = i;
337 fputs (i ? ",\n[" : "[", out);
338 for (; i < nsyms
339 && syms[i]->content->type_name == syms[i0]->content->type_name; ++i)
340 fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->content->number);
341 fputs ("]", out);
342 }
343 fputs ("])\n\n", out);
344 free (syms);
345}
346
347
348/*-------------------------------------.
349| The list of all the symbol numbers. |
350`-------------------------------------*/
351
352static void
353symbol_numbers_output (FILE *out)
354{
355 fputs ("m4_define([b4_symbol_numbers],\n[", out);
356 for (int i = 0; i < nsyms; ++i)
357 fprintf (out, "%s[%d]", i ? ", " : "", i);
358 fputs ("])\n\n", out);
359}
360
361
362/*---------------------------------.
363| Output the user actions to OUT. |
364`---------------------------------*/
365
366static void
367user_actions_output (FILE *out)
368{
369 fputs ("m4_define([b4_actions], \n[", out);
370 for (rule_number r = 0; r < nrules; ++r)
371 if (rules[r].action)
372 {
373 fprintf (out, "%s(%d, [b4_syncline(%d, ",
374 rules[r].is_predicate ? "b4_predicate_case" : "b4_case",
375 r + 1, rules[r].action_loc.start.line);
376 string_output (out, rules[r].action_loc.start.file);
377 fprintf (out, ")dnl\n[ %s]])\n\n", rules[r].action);
378 }
379 fputs ("])\n\n", out);
380}
381
382/*------------------------------------.
383| Output the merge functions to OUT. |
384`------------------------------------*/
385
386static void
387merger_output (FILE *out)
388{
389 fputs ("m4_define([b4_mergers], \n[[", out);
390 int n;
391 merger_list* p;
392 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
393 {
394 if (p->type[0] == '\0')
395 fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
396 n, p->name);
397 else
398 fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
399 n, p->type, p->name);
400 }
401 fputs ("]])\n\n", out);
402}
403
404
405/*---------------------------------------------.
406| Prepare the muscles for symbol definitions. |
407`---------------------------------------------*/
408
409static void
410prepare_symbol_definitions (void)
411{
412 /* Map "orig NUM" to new numbers. See data/README. */
413 for (symbol_number i = ntokens; i < nsyms + nuseless_nonterminals; ++i)
414 {
415 obstack_printf (&format_obstack, "symbol(orig %d, number)", i);
416 const char *key = obstack_finish0 (&format_obstack);
417 MUSCLE_INSERT_INT (key, nterm_map ? nterm_map[i - ntokens] : i);
418 }
419
420 for (int i = 0; i < nsyms; ++i)
421 {
422 symbol *sym = symbols[i];
423 const char *key;
424
425#define SET_KEY(Entry) \
426 obstack_printf (&format_obstack, "symbol(%d, %s)", \
427 i, Entry); \
428 key = obstack_finish0 (&format_obstack);
429
430#define SET_KEY2(Entry, Suffix) \
431 obstack_printf (&format_obstack, "symbol(%d, %s_%s)", \
432 i, Entry, Suffix); \
433 key = obstack_finish0 (&format_obstack);
434
435 /* Whether the symbol has an identifier. */
436 const char *id = symbol_id_get (sym);
437 SET_KEY ("has_id");
438 MUSCLE_INSERT_INT (key, !!id);
439
440 /* Its identifier. */
441 SET_KEY ("id");
442 MUSCLE_INSERT_STRING (key, id ? id : "");
443
444 /* Its tag. Typically for documentation purpose. */
445 SET_KEY ("tag");
446 MUSCLE_INSERT_STRING (key, sym->tag);
447
448 SET_KEY ("user_number");
449 MUSCLE_INSERT_INT (key, sym->content->user_token_number);
450
451 SET_KEY ("is_token");
452 MUSCLE_INSERT_INT (key,
453 i < ntokens && sym != errtoken && sym != undeftoken);
454
455 SET_KEY ("number");
456 MUSCLE_INSERT_INT (key, sym->content->number);
457
458 SET_KEY ("has_type");
459 MUSCLE_INSERT_INT (key, !!sym->content->type_name);
460
461 SET_KEY ("type");
462 MUSCLE_INSERT_STRING (key, sym->content->type_name
463 ? sym->content->type_name : "");
464
465 for (int j = 0; j < CODE_PROPS_SIZE; ++j)
466 {
467 /* "printer", not "%printer". */
468 char const *pname = code_props_type_string (j) + 1;
469 code_props const *p = symbol_code_props_get (sym, j);
470 SET_KEY2 ("has", pname);
471 MUSCLE_INSERT_INT (key, !!p->code);
472
473 if (p->code)
474 {
475 SET_KEY2 (pname, "file");
476 MUSCLE_INSERT_C_STRING (key, p->location.start.file);
477
478 SET_KEY2 (pname, "line");
479 MUSCLE_INSERT_INT (key, p->location.start.line);
480
481 SET_KEY2 (pname, "loc");
482 muscle_location_grow (key, p->location);
483
484 SET_KEY (pname);
485 MUSCLE_INSERT_STRING_RAW (key, p->code);
486 }
487 }
488#undef SET_KEY2
489#undef SET_KEY
490 }
491}
492
493
494static void
495prepare_actions (void)
496{
497 /* Figure out the actions for the specified state, indexed by
498 lookahead token type. */
499
500 muscle_insert_rule_number_table ("defact", yydefact,
501 yydefact[0], 1, nstates);
502
503 /* Figure out what to do after reducing with each rule, depending on
504 the saved state from before the beginning of parsing the data
505 that matched this rule. */
506 muscle_insert_state_number_table ("defgoto", yydefgoto,
507 yydefgoto[0], 1, nsyms - ntokens);
508
509
510 /* Output PACT. */
511 muscle_insert_base_table ("pact", base,
512 base[0], 1, nstates);
513 MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
514
515 /* Output PGOTO. */
516 muscle_insert_base_table ("pgoto", base,
517 base[nstates], nstates + 1, nvectors);
518
519 muscle_insert_base_table ("table", table,
520 table[0], 1, high + 1);
521 MUSCLE_INSERT_INT ("table_ninf", table_ninf);
522
523 muscle_insert_base_table ("check", check,
524 check[0], 1, high + 1);
525
526 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
527 YYPACT) so that in states with unresolved conflicts, the default
528 reduction is not used in the conflicted entries, so that there is
529 a place to put a conflict pointer.
530
531 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
532 parser, so we could avoid accidents by not writing them out in
533 that case. Nevertheless, it seems even better to be able to use
534 the GLR skeletons even without the non-deterministic tables. */
535 muscle_insert_unsigned_table ("conflict_list_heads", conflict_table,
536 conflict_table[0], 1, high + 1);
537 muscle_insert_unsigned_table ("conflicting_rules", conflict_list,
538 0, 1, conflict_list_cnt);
539}
540
541
542/*--------------------------------------------.
543| Output the definitions of all the muscles. |
544`--------------------------------------------*/
545
546static void
547muscles_output (FILE *out)
548{
549 fputs ("m4_init()\n", out);
550 merger_output (out);
551 symbol_numbers_output (out);
552 type_names_output (out);
553 user_actions_output (out);
554 /* Must be last. */
555 muscles_m4_output (out);
556}
557
558/*---------------------------.
559| Call the skeleton parser. |
560`---------------------------*/
561
562static void
563output_skeleton (void)
564{
565 /* Compute the names of the package data dir and skeleton files. */
566 char const *m4 = (m4 = getenv ("M4")) ? m4 : M4;
567 char const *datadir = pkgdatadir ();
568 char *skeldir = xpath_join (datadir, "skeletons");
569 char *m4sugar = xpath_join (datadir, "m4sugar/m4sugar.m4");
570 char *m4bison = xpath_join (skeldir, "bison.m4");
571 char *skel = (IS_PATH_WITH_DIR (skeleton)
572 ? xstrdup (skeleton)
573 : xpath_join (skeldir, skeleton));
574
575 /* Test whether m4sugar.m4 is readable, to check for proper
576 installation. A faulty installation can cause deadlock, so a
577 cheap sanity check is worthwhile. */
578 xfclose (xfopen (m4sugar, "r"));
579
580 /* Create an m4 subprocess connected to us via two pipes. */
581
582 if (trace_flag & trace_tools)
583 fprintf (stderr, "running: %s %s - %s %s\n",
584 m4, m4sugar, m4bison, skel);
585
586 /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a
587 position-dependent manner. Keep it as the first argument so that all
588 files are traced.
589
590 See the thread starting at
591 <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
592 for details. */
593 int filter_fd[2];
594 pid_t pid;
595 {
596 char const *argv[10];
597 int i = 0;
598 argv[i++] = m4;
599
600 /* When POSIXLY_CORRECT is set, GNU M4 1.6 and later disable GNU
601 extensions, which Bison's skeletons depend on. With older M4,
602 it has no effect. M4 1.4.12 added a -g/--gnu command-line
603 option to make it explicit that a program wants GNU M4
604 extensions even when POSIXLY_CORRECT is set.
605
606 See the thread starting at
607 <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
608 for details. */
609 if (*M4_GNU_OPTION)
610 argv[i++] = M4_GNU_OPTION;
611
612 argv[i++] = "-I";
613 argv[i++] = datadir;
614 if (trace_flag & trace_m4)
615 argv[i++] = "-dV";
616 argv[i++] = m4sugar;
617 argv[i++] = "-";
618 argv[i++] = m4bison;
619 argv[i++] = skel;
620 argv[i++] = NULL;
621 aver (i <= ARRAY_CARDINALITY (argv));
622
623 /* The ugly cast is because gnulib gets the const-ness wrong. */
624 pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true,
625 true, filter_fd);
626 }
627
628 free (skeldir);
629 free (m4sugar);
630 free (m4bison);
631 free (skel);
632
633 if (trace_flag & trace_muscles)
634 muscles_output (stderr);
635 {
636 FILE *out = xfdopen (filter_fd[1], "w");
637 muscles_output (out);
638 xfclose (out);
639 }
640
641 /* Read and process m4's output. */
642 timevar_push (tv_m4);
643 {
644 FILE *in = xfdopen (filter_fd[0], "r");
645 scan_skel (in);
646 /* scan_skel should have read all of M4's output. Otherwise, when we
647 close the pipe, we risk letting M4 report a broken-pipe to the
648 Bison user. */
649 aver (feof (in));
650 xfclose (in);
651 }
652 wait_subprocess (pid, "m4", false, false, true, true, NULL);
653 timevar_pop (tv_m4);
654}
655
656static void
657prepare (void)
658{
659 /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be
660 documented for the user. */
661 char const *cp = getenv ("BISON_USE_PUSH_FOR_PULL");
662 bool use_push_for_pull_flag = cp && *cp && strtol (cp, 0, 10);
663
664 MUSCLE_INSERT_INT ("required_version", required_version);
665
666 /* Flags. */
667 MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
668 MUSCLE_INSERT_BOOL ("glr_flag", glr_parser);
669 MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser);
670 MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
671 MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
672 MUSCLE_INSERT_BOOL ("token_table_flag", token_table_flag);
673 MUSCLE_INSERT_BOOL ("use_push_for_pull_flag", use_push_for_pull_flag);
674 MUSCLE_INSERT_BOOL ("yacc_flag", !location_empty (yacc_loc));
675
676 /* File names. */
677 if (spec_name_prefix)
678 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
679
680 MUSCLE_INSERT_STRING ("file_name_all_but_ext", all_but_ext);
681
682#define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "")
683 DEFINE (dir_prefix);
684 DEFINE (parser_file_name);
685 DEFINE (spec_header_file);
686 DEFINE (spec_file_prefix);
687 DEFINE (spec_graph_file);
688 DEFINE (spec_name_prefix);
689 DEFINE (spec_outfile);
690 DEFINE (spec_verbose_file);
691#undef DEFINE
692
693 /* Find the right skeleton file, and add muscles about the skeletons. */
694 if (skeleton)
695 MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
696 else
697 skeleton = language->skeleton;
698
699 /* About the skeletons. */
700 {
701 /* b4_skeletonsdir is used inside m4_include in the skeletons, so digraphs
702 would never be expanded. Hopefully no one has M4-special characters in
703 his Bison installation path. */
704 char *skeldir = xpath_join (pkgdatadir (), "skeletons");
705 MUSCLE_INSERT_STRING_RAW ("skeletonsdir", skeldir);
706 free (skeldir);
707 }
708}
709
710
711/*----------------------------------------------------------.
712| Output the parsing tables and the parser code to ftable. |
713`----------------------------------------------------------*/
714
715void
716output (void)
717{
718 obstack_init (&format_obstack);
719
720 prepare_symbols ();
721 prepare_rules ();
722 prepare_states ();
723 prepare_actions ();
724 prepare_symbol_definitions ();
725
726 prepare ();
727
728 /* Process the selected skeleton file. */
729 output_skeleton ();
730
731 /* If late errors were generated, destroy the generated source
732 files. */
733 if (complaint_status)
734 unlink_generated_sources ();
735
736 obstack_free (&format_obstack, NULL);
737}
738