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 <configmake.h> 25 #include <error.h> 26 #include <get-errno.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 "scan-code.h" /* max_left_semantic_context */ 40 #include "scan-skel.h" 41 #include "symtab.h" 42 #include "tables.h" 43 44 static struct obstack format_obstack; 45 46 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 `-------------------------------------------------------------------*/ 53 54 55 #define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \ 56 \ 57 static void \ 58 Name (char const *name, \ 59 Type *table_data, \ 60 Type first, \ 61 int begin, \ 62 int end) \ 63 { \ 64 Type min = first; \ 65 Type max = first; \ 66 long int lmin; \ 67 long int lmax; \ 68 int i; \ 69 int j = 1; \ 70 \ 71 obstack_printf (&format_obstack, "%6d", first); \ 72 for (i = begin; i < end; ++i) \ 73 { \ 74 obstack_1grow (&format_obstack, ','); \ 75 if (j >= 10) \ 76 { \ 77 obstack_sgrow (&format_obstack, "\n "); \ 78 j = 1; \ 79 } \ 80 else \ 81 ++j; \ 82 obstack_printf (&format_obstack, "%6d", table_data[i]); \ 83 if (table_data[i] < min) \ 84 min = table_data[i]; \ 85 if (max < table_data[i]) \ 86 max = table_data[i]; \ 87 } \ 88 obstack_1grow (&format_obstack, 0); \ 89 muscle_insert (name, obstack_finish (&format_obstack)); \ 90 \ 91 lmin = min; \ 92 lmax = max; \ 93 /* Build `NAME_min' and `NAME_max' in the obstack. */ \ 94 obstack_printf (&format_obstack, "%s_min", name); \ 95 obstack_1grow (&format_obstack, 0); \ 96 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \ 97 obstack_printf (&format_obstack, "%s_max", name); \ 98 obstack_1grow (&format_obstack, 0); \ 99 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \ 100 } 101 102 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int) 103 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table, int) 104 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number) 105 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number) 106 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number) 107 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_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 ("undef_token_number", undeftoken->number); 156 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number); 157 158 muscle_insert_symbol_number_table ("translate", 159 token_translations, 160 token_translations[0], 161 1, max_user_token_number + 1); 162 163 /* tname -- token names. */ 164 { 165 int i; 166 /* We assume that the table will be output starting at column 2. */ 167 int j = 2; 168 struct quoting_options *qo = clone_quoting_options (0); 169 set_quoting_style (qo, c_quoting_style); 170 set_quoting_flags (qo, QA_SPLIT_TRIGRAPHS); 171 for (i = 0; i < nsyms; i++) 172 { 173 char *cp = quotearg_alloc (symbols[i]->tag, -1, qo); 174 /* Width of the next token, including the two quotes, the 175 comma and the space. */ 176 int width = strlen (cp) + 2; 177 178 if (j + width > 75) 179 { 180 obstack_sgrow (&format_obstack, "\n "); 181 j = 1; 182 } 183 184 if (i) 185 obstack_1grow (&format_obstack, ' '); 186 obstack_escape (&format_obstack, cp); 187 free (cp); 188 obstack_1grow (&format_obstack, ','); 189 j += width; 190 } 191 free (qo); 192 obstack_sgrow (&format_obstack, " ]b4_null["); 193 194 /* Finish table and store. */ 195 obstack_1grow (&format_obstack, 0); 196 muscle_insert ("tname", obstack_finish (&format_obstack)); 197 } 198 199 /* Output YYTOKNUM. */ 200 { 201 int i; 202 int *values = xnmalloc (ntokens, sizeof *values); 203 for (i = 0; i < ntokens; ++i) 204 values[i] = symbols[i]->user_token_number; 205 muscle_insert_int_table ("toknum", values, 206 values[0], 1, ntokens); 207 free (values); 208 } 209 } 210 211 212 /*-------------------------------------------------------------. 213 | Prepare the muscles related to the rules: rhs, prhs, r1, r2, | 214 | rline, dprec, merger. | 215 `-------------------------------------------------------------*/ 216 217 static void 218 prepare_rules (void) 219 { 220 rule_number r; 221 unsigned int i = 0; 222 item_number *rhs = xnmalloc (nritems, sizeof *rhs); 223 unsigned int *prhs = xnmalloc (nrules, sizeof *prhs); 224 unsigned int *rline = xnmalloc (nrules, sizeof *rline); 225 symbol_number *r1 = xnmalloc (nrules, sizeof *r1); 226 unsigned int *r2 = xnmalloc (nrules, sizeof *r2); 227 int *dprec = xnmalloc (nrules, sizeof *dprec); 228 int *merger = xnmalloc (nrules, sizeof *merger); 229 230 for (r = 0; r < nrules; ++r) 231 { 232 item_number *rhsp = NULL; 233 /* Index of rule R in RHS. */ 234 prhs[r] = i; 235 /* RHS of the rule R. */ 236 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp) 237 rhs[i++] = *rhsp; 238 /* LHS of the rule R. */ 239 r1[r] = rules[r].lhs->number; 240 /* Length of rule R's RHS. */ 241 r2[r] = i - prhs[r]; 242 /* Separator in RHS. */ 243 rhs[i++] = -1; 244 /* Line where rule was defined. */ 245 rline[r] = rules[r].location.start.line; 246 /* Dynamic precedence (GLR). */ 247 dprec[r] = rules[r].dprec; 248 /* Merger-function index (GLR). */ 249 merger[r] = rules[r].merger; 250 } 251 aver (i == nritems); 252 253 muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems); 254 muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules); 255 muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules); 256 muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules); 257 muscle_insert_unsigned_int_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 261 MUSCLE_INSERT_INT ("rules_number", nrules); 262 MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context); 263 264 free (rhs); 265 free (prhs); 266 free (rline); 267 free (r1); 268 free (r2); 269 free (dprec); 270 free (merger); 271 } 272 273 /*--------------------------------------------. 274 | Prepare the muscles related to the states. | 275 `--------------------------------------------*/ 276 277 static void 278 prepare_states (void) 279 { 280 state_number i; 281 symbol_number *values = xnmalloc (nstates, sizeof *values); 282 for (i = 0; i < nstates; ++i) 283 values[i] = states[i]->accessing_symbol; 284 muscle_insert_symbol_number_table ("stos", values, 285 0, 1, nstates); 286 free (values); 287 288 MUSCLE_INSERT_INT ("last", high); 289 MUSCLE_INSERT_INT ("final_state_number", final_state->number); 290 MUSCLE_INSERT_INT ("states_number", nstates); 291 } 292 293 294 295 /*---------------------------------. 296 | Output the user actions to OUT. | 297 `---------------------------------*/ 298 299 static void 300 user_actions_output (FILE *out) 301 { 302 rule_number r; 303 304 fputs ("m4_define([b4_actions], \n[", out); 305 for (r = 0; r < nrules; ++r) 306 if (rules[r].action) 307 { 308 fprintf (out, "b4_case(%d, [b4_syncline(%d, ", r + 1, 309 rules[r].action_location.start.line); 310 string_output (out, rules[r].action_location.start.file); 311 fprintf (out, ")\n[ %s]])\n\n", rules[r].action); 312 } 313 fputs ("])\n\n", out); 314 } 315 316 /*--------------------------------------. 317 | Output the merge functions to OUT. | 318 `--------------------------------------*/ 319 320 static void 321 merger_output (FILE *out) 322 { 323 int n; 324 merger_list* p; 325 326 fputs ("m4_define([b4_mergers], \n[[", out); 327 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next) 328 { 329 if (p->type[0] == '\0') 330 fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n", 331 n, p->name); 332 else 333 fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n", 334 n, p->type, p->name); 335 } 336 fputs ("]])\n\n", out); 337 } 338 339 /*--------------------------------------. 340 | Output the tokens definition to OUT. | 341 `--------------------------------------*/ 342 343 static void 344 token_definitions_output (FILE *out) 345 { 346 int i; 347 char const *sep = ""; 348 349 fputs ("m4_define([b4_tokens], \n[", out); 350 for (i = 0; i < ntokens; ++i) 351 { 352 symbol *sym = symbols[i]; 353 int number = sym->user_token_number; 354 355 /* At this stage, if there are literal string aliases, they are 356 part of SYMBOLS, so we should not find their aliased symbols 357 here. */ 358 aver (number != USER_NUMBER_HAS_STRING_ALIAS); 359 360 /* Skip error token. */ 361 if (sym == errtoken) 362 continue; 363 364 /* If this string has an alias, then it is necessarily the alias 365 which is to be output. */ 366 if (sym->alias) 367 sym = sym->alias; 368 369 /* Don't output literal chars or strings (when defined only as a 370 string). Note that must be done after the alias resolution: 371 think about `%token 'f' "f"'. */ 372 if (sym->tag[0] == '\'' || sym->tag[0] == '\"') 373 continue; 374 375 /* Don't #define nonliteral tokens whose names contain periods, 376 dashes or '$' (as does the default value of the EOF token). */ 377 if (mbschr (sym->tag, '.') 378 || mbschr (sym->tag, '-') 379 || mbschr (sym->tag, '$')) 380 continue; 381 382 fprintf (out, "%s[[[%s]], %d]", 383 sep, sym->tag, number); 384 sep = ",\n"; 385 } 386 fputs ("])\n\n", out); 387 } 388 389 390 /*---------------------------------------------------. 391 | Output the symbol destructors or printers to OUT. | 392 `---------------------------------------------------*/ 393 394 static void 395 symbol_code_props_output (FILE *out, char const *what, 396 code_props const *(*get)(symbol const *)) 397 { 398 int i; 399 char const *sep = ""; 400 401 fputs ("m4_define([b4_symbol_", out); 402 fputs (what, out); 403 fputs ("], \n[", out); 404 for (i = 0; i < nsyms; ++i) 405 { 406 symbol *sym = symbols[i]; 407 char const *code = (*get) (sym)->code; 408 if (code) 409 { 410 location loc = (*get) (sym)->location; 411 /* Filename, lineno, 412 Symbol-name, Symbol-number, 413 code, optional typename. */ 414 fprintf (out, "%s[", sep); 415 sep = ",\n"; 416 string_output (out, loc.start.file); 417 fprintf (out, ", %d, ", loc.start.line); 418 quoted_output (out, sym->tag); 419 fprintf (out, ", %d, [[%s]]", sym->number, code); 420 if (sym->type_name) 421 { 422 fputs (", ", out); 423 quoted_output (out, sym->type_name); 424 } 425 fputc (']', out); 426 } 427 } 428 fputs ("])\n\n", out); 429 } 430 431 432 static void 433 prepare_actions (void) 434 { 435 /* Figure out the actions for the specified state, indexed by 436 lookahead token type. */ 437 438 muscle_insert_rule_number_table ("defact", yydefact, 439 yydefact[0], 1, nstates); 440 441 /* Figure out what to do after reducing with each rule, depending on 442 the saved state from before the beginning of parsing the data 443 that matched this rule. */ 444 muscle_insert_state_number_table ("defgoto", yydefgoto, 445 yydefgoto[0], 1, nsyms - ntokens); 446 447 448 /* Output PACT. */ 449 muscle_insert_base_table ("pact", base, 450 base[0], 1, nstates); 451 MUSCLE_INSERT_INT ("pact_ninf", base_ninf); 452 453 /* Output PGOTO. */ 454 muscle_insert_base_table ("pgoto", base, 455 base[nstates], nstates + 1, nvectors); 456 457 muscle_insert_base_table ("table", table, 458 table[0], 1, high + 1); 459 MUSCLE_INSERT_INT ("table_ninf", table_ninf); 460 461 muscle_insert_base_table ("check", check, 462 check[0], 1, high + 1); 463 464 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus 465 YYPACT) so that in states with unresolved conflicts, the default 466 reduction is not used in the conflicted entries, so that there is 467 a place to put a conflict pointer. 468 469 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR 470 parser, so we could avoid accidents by not writing them out in 471 that case. Nevertheless, it seems even better to be able to use 472 the GLR skeletons even without the non-deterministic tables. */ 473 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table, 474 conflict_table[0], 1, high + 1); 475 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list, 476 0, 1, conflict_list_cnt); 477 } 478 479 /*--------------------------------------------. 480 | Output the definitions of all the muscles. | 481 `--------------------------------------------*/ 482 483 static void 484 muscles_output (FILE *out) 485 { 486 fputs ("m4_init()\n", out); 487 488 user_actions_output (out); 489 merger_output (out); 490 token_definitions_output (out); 491 symbol_code_props_output (out, "destructors", &symbol_destructor_get); 492 symbol_code_props_output (out, "printers", &symbol_printer_get); 493 494 muscles_m4_output (out); 495 } 496 497 /*---------------------------. 499 | Call the skeleton parser. | 500 `---------------------------*/ 501 502 static void 503 output_skeleton (void) 504 { 505 FILE *in; 506 int filter_fd[2]; 507 char const *argv[10]; 508 pid_t pid; 509 510 /* Compute the names of the package data dir and skeleton files. */ 511 char const m4sugar[] = "m4sugar/m4sugar.m4"; 512 char const m4bison[] = "bison.m4"; 513 char *full_m4sugar; 514 char *full_m4bison; 515 char *full_skeleton; 516 char const *p; 517 char const *m4 = (p = getenv ("M4")) ? p : M4; 518 char const *pkgdatadir = compute_pkgdatadir (); 519 size_t skeleton_size = strlen (skeleton) + 1; 520 size_t pkgdatadirlen = strlen (pkgdatadir); 521 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/') 522 pkgdatadirlen--; 523 full_skeleton = xmalloc (pkgdatadirlen + 1 524 + (skeleton_size < sizeof m4sugar 525 ? sizeof m4sugar : skeleton_size)); 526 memcpy (full_skeleton, pkgdatadir, pkgdatadirlen); 527 full_skeleton[pkgdatadirlen] = '/'; 528 strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar); 529 full_m4sugar = xstrdup (full_skeleton); 530 strcpy (full_skeleton + pkgdatadirlen + 1, m4bison); 531 full_m4bison = xstrdup (full_skeleton); 532 if (mbschr (skeleton, '/')) 533 strcpy (full_skeleton, skeleton); 534 else 535 strcpy (full_skeleton + pkgdatadirlen + 1, skeleton); 536 537 /* Test whether m4sugar.m4 is readable, to check for proper 538 installation. A faulty installation can cause deadlock, so a 539 cheap sanity check is worthwhile. */ 540 xfclose (xfopen (full_m4sugar, "r")); 541 542 /* Create an m4 subprocess connected to us via two pipes. */ 543 544 if (trace_flag & trace_tools) 545 fprintf (stderr, "running: %s %s - %s %s\n", 546 m4, full_m4sugar, full_m4bison, full_skeleton); 547 548 /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a 549 position-dependent manner. Keep it as the first argument so that all 550 files are traced. 551 552 See the thread starting at 553 <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html> 554 for details. */ 555 { 556 int i = 0; 557 argv[i++] = m4; 558 559 /* When POSIXLY_CORRECT is set, GNU M4 1.6 and later disable GNU 560 extensions, which Bison's skeletons depend on. With older M4, 561 it has no effect. M4 1.4.12 added a -g/--gnu command-line 562 option to make it explicit that a program wants GNU M4 563 extensions even when POSIXLY_CORRECT is set. 564 565 See the thread starting at 566 <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html> 567 for details. */ 568 if (*M4_GNU_OPTION) 569 argv[i++] = M4_GNU_OPTION; 570 571 argv[i++] = "-I"; 572 argv[i++] = pkgdatadir; 573 if (trace_flag & trace_m4) 574 argv[i++] = "-dV"; 575 argv[i++] = full_m4sugar; 576 argv[i++] = "-"; 577 argv[i++] = full_m4bison; 578 argv[i++] = full_skeleton; 579 argv[i++] = NULL; 580 aver (i <= ARRAY_CARDINALITY (argv)); 581 } 582 583 /* The ugly cast is because gnulib gets the const-ness wrong. */ 584 pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true, 585 true, filter_fd); 586 free (full_m4sugar); 587 free (full_m4bison); 588 free (full_skeleton); 589 590 if (trace_flag & trace_muscles) 591 muscles_output (stderr); 592 { 593 FILE *out = fdopen (filter_fd[1], "w"); 594 if (! out) 595 error (EXIT_FAILURE, get_errno (), 596 "fdopen"); 597 muscles_output (out); 598 xfclose (out); 599 } 600 601 /* Read and process m4's output. */ 602 timevar_push (TV_M4); 603 in = fdopen (filter_fd[0], "r"); 604 if (! in) 605 error (EXIT_FAILURE, get_errno (), 606 "fdopen"); 607 scan_skel (in); 608 /* scan_skel should have read all of M4's output. Otherwise, when we 609 close the pipe, we risk letting M4 report a broken-pipe to the 610 Bison user. */ 611 aver (feof (in)); 612 xfclose (in); 613 wait_subprocess (pid, "m4", false, false, true, true, NULL); 614 timevar_pop (TV_M4); 615 } 616 617 static void 618 prepare (void) 619 { 620 /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be documented 621 for the user. */ 622 char const *use_push_for_pull_env = getenv ("BISON_USE_PUSH_FOR_PULL"); 623 bool use_push_for_pull_flag = false; 624 if (use_push_for_pull_env != NULL 625 && use_push_for_pull_env[0] != '\0' 626 && 0 != strcmp (use_push_for_pull_env, "0")) 627 use_push_for_pull_flag = true; 628 629 /* Flags. */ 630 MUSCLE_INSERT_BOOL ("debug_flag", debug); 631 MUSCLE_INSERT_BOOL ("defines_flag", defines_flag); 632 MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose); 633 MUSCLE_INSERT_BOOL ("glr_flag", glr_parser); 634 MUSCLE_INSERT_BOOL ("locations_flag", locations_flag); 635 MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser); 636 MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag); 637 MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen); 638 MUSCLE_INSERT_BOOL ("token_table_flag", token_table_flag); 639 MUSCLE_INSERT_BOOL ("use_push_for_pull_flag", use_push_for_pull_flag); 640 MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag); 641 642 /* File names. */ 643 if (spec_name_prefix) 644 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix); 645 646 MUSCLE_INSERT_STRING ("file_name_all_but_ext", all_but_ext); 647 648 #define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "") 649 DEFINE (dir_prefix); 650 DEFINE (parser_file_name); 651 DEFINE (spec_defines_file); 652 DEFINE (spec_file_prefix); 653 DEFINE (spec_graph_file); 654 DEFINE (spec_name_prefix); 655 DEFINE (spec_outfile); 656 DEFINE (spec_verbose_file); 657 #undef DEFINE 658 659 /* Find the right skeleton file, and add muscles about the skeletons. */ 660 if (skeleton) 661 MUSCLE_INSERT_C_STRING ("skeleton", skeleton); 662 else 663 skeleton = language->skeleton; 664 665 /* About the skeletons. */ 666 { 667 /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs 668 would never be expanded. Hopefully no one has M4-special characters in 669 his Bison installation path. */ 670 MUSCLE_INSERT_STRING_RAW ("pkgdatadir", compute_pkgdatadir ()); 671 } 672 } 673 674 675 /*----------------------------------------------------------. 676 | Output the parsing tables and the parser code to ftable. | 677 `----------------------------------------------------------*/ 678 679 void 680 output (void) 681 { 682 obstack_init (&format_obstack); 683 684 prepare_symbols (); 685 prepare_rules (); 686 prepare_states (); 687 prepare_actions (); 688 689 prepare (); 690 691 /* Process the selected skeleton file. */ 692 output_skeleton (); 693 694 obstack_free (&format_obstack, NULL); 695 } 696 697 char const * 698 compute_pkgdatadir (void) 699 { 700 char const *pkgdatadir = getenv ("BISON_PKGDATADIR"); 701 return pkgdatadir ? pkgdatadir : PKGDATADIR; 702 } 703