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