1 /* Output the generated parsing program for Bison. 
   3    Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 
   4    2005, 2006, 2007, 2008 Free Software Foundation, Inc. 
   6    This file is part of Bison, the GNU Compiler Compiler. 
   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. 
  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. 
  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/>.  */ 
  24 #include <configmake.h> 
  26 #include <get-errno.h> 
  35 #include "muscle_tab.h" 
  38 #include "scan-code.h"    /* max_left_semantic_context */ 
  39 #include "scan-skel.h" 
  44 static struct obstack format_obstack
; 
  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            | 
  52 `-------------------------------------------------------------------*/ 
  55 #define GENERATE_MUSCLE_INSERT_TABLE(Name, Type)                        \ 
  58 Name (char const *name,                                                 \ 
  71   obstack_fgrow1 (&format_obstack, "%6d", first);                       \ 
  72   for (i = begin; i < end; ++i)                                         \ 
  74       obstack_1grow (&format_obstack, ',');                             \ 
  77           obstack_sgrow (&format_obstack, "\n  ");                      \ 
  82       obstack_fgrow1 (&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];                                            \ 
  88   obstack_1grow (&format_obstack, 0);                                   \ 
  89   muscle_insert (name, obstack_finish (&format_obstack));               \ 
  93   /* Build `NAME_min' and `NAME_max' in the obstack. */                 \ 
  94   obstack_fgrow1 (&format_obstack, "%s_min", name);                     \ 
  95   obstack_1grow (&format_obstack, 0);                                   \ 
  96   MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin);      \ 
  97   obstack_fgrow1 (&format_obstack, "%s_max", name);                     \ 
  98   obstack_1grow (&format_obstack, 0);                                   \ 
  99   MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax);      \ 
 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
) 
 111 /*--------------------------------------------------------------------. 
 112 | Print to OUT a representation of STRING escaped both for C and M4.  | 
 113 `--------------------------------------------------------------------*/ 
 116 escaped_output (FILE *out
, char const *string
) 
 121   for (p 
= quotearg_style (c_quoting_style
, string
); *p
; p
++) 
 124       case '$': fputs ("$][", out
); break; 
 125       case '@': fputs ("@@",  out
); break; 
 126       case '[': fputs ("@{",  out
); break; 
 127       case ']': fputs ("@}",  out
); break; 
 128       default: fputc (*p
, out
); break; 
 135 /*------------------------------------------------------------------. 
 136 | Prepare the muscles related to the symbols: translate, tname, and | 
 138 `------------------------------------------------------------------*/ 
 141 prepare_symbols (void) 
 143   MUSCLE_INSERT_BOOL ("token_table", token_table_flag
); 
 144   MUSCLE_INSERT_INT ("tokens_number", ntokens
); 
 145   MUSCLE_INSERT_INT ("nterms_number", nvars
); 
 146   MUSCLE_INSERT_INT ("symbols_number", nsyms
); 
 147   MUSCLE_INSERT_INT ("undef_token_number", undeftoken
->number
); 
 148   MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number
); 
 150   muscle_insert_symbol_number_table ("translate", 
 152                                      token_translations
[0], 
 153                                      1, max_user_token_number 
+ 1); 
 155   /* tname -- token names.  */ 
 158     /* We assume that the table will be output starting at column 2. */ 
 160     struct quoting_options 
*qo 
= clone_quoting_options (0); 
 161     set_quoting_style (qo
, c_quoting_style
); 
 162     set_quoting_flags (qo
, QA_SPLIT_TRIGRAPHS
); 
 163     for (i 
= 0; i 
< nsyms
; i
++) 
 165         char *cp 
= quotearg_alloc (symbols
[i
]->tag
, -1, qo
); 
 166         /* Width of the next token, including the two quotes, the 
 167            comma and the space.  */ 
 168         int width 
= strlen (cp
) + 2; 
 172             obstack_sgrow (&format_obstack
, "\n "); 
 177           obstack_1grow (&format_obstack
, ' '); 
 178         MUSCLE_OBSTACK_SGROW (&format_obstack
, cp
); 
 180         obstack_1grow (&format_obstack
, ','); 
 184     obstack_sgrow (&format_obstack
, " ]b4_null["); 
 186     /* Finish table and store. */ 
 187     obstack_1grow (&format_obstack
, 0); 
 188     muscle_insert ("tname", obstack_finish (&format_obstack
)); 
 191   /* Output YYTOKNUM. */ 
 194     int *values 
= xnmalloc (ntokens
, sizeof *values
); 
 195     for (i 
= 0; i 
< ntokens
; ++i
) 
 196       values
[i
] = symbols
[i
]->user_token_number
; 
 197     muscle_insert_int_table ("toknum", values
, 
 198                              values
[0], 1, ntokens
); 
 204 /*-------------------------------------------------------------. 
 205 | Prepare the muscles related to the rules: rhs, prhs, r1, r2, | 
 206 | rline, dprec, merger.                                        | 
 207 `-------------------------------------------------------------*/ 
 214   item_number 
*rhs 
= xnmalloc (nritems
, sizeof *rhs
); 
 215   unsigned int *prhs 
= xnmalloc (nrules
, sizeof *prhs
); 
 216   unsigned int *rline 
= xnmalloc (nrules
, sizeof *rline
); 
 217   symbol_number 
*r1 
= xnmalloc (nrules
, sizeof *r1
); 
 218   unsigned int *r2 
= xnmalloc (nrules
, sizeof *r2
); 
 219   int *dprec 
= xnmalloc (nrules
, sizeof *dprec
); 
 220   int *merger 
= xnmalloc (nrules
, sizeof *merger
); 
 222   for (r 
= 0; r 
< nrules
; ++r
) 
 224       item_number 
*rhsp 
= NULL
; 
 225       /* Index of rule R in RHS. */ 
 227       /* RHS of the rule R. */ 
 228       for (rhsp 
= rules
[r
].rhs
; *rhsp 
>= 0; ++rhsp
) 
 230       /* LHS of the rule R. */ 
 231       r1
[r
] = rules
[r
].lhs
->number
; 
 232       /* Length of rule R's RHS. */ 
 234       /* Separator in RHS. */ 
 236       /* Line where rule was defined. */ 
 237       rline
[r
] = rules
[r
].location
.start
.line
; 
 238       /* Dynamic precedence (GLR).  */ 
 239       dprec
[r
] = rules
[r
].dprec
; 
 240       /* Merger-function index (GLR).  */ 
 241       merger
[r
] = rules
[r
].merger
; 
 245   muscle_insert_item_number_table ("rhs", rhs
, ritem
[0], 1, nritems
); 
 246   muscle_insert_unsigned_int_table ("prhs", prhs
, 0, 0, nrules
); 
 247   muscle_insert_unsigned_int_table ("rline", rline
, 0, 0, nrules
); 
 248   muscle_insert_symbol_number_table ("r1", r1
, 0, 0, nrules
); 
 249   muscle_insert_unsigned_int_table ("r2", r2
, 0, 0, nrules
); 
 250   muscle_insert_int_table ("dprec", dprec
, 0, 0, nrules
); 
 251   muscle_insert_int_table ("merger", merger
, 0, 0, nrules
); 
 253   MUSCLE_INSERT_INT ("rules_number", nrules
); 
 254   MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context
); 
 265 /*--------------------------------------------. 
 266 | Prepare the muscles related to the states.  | 
 267 `--------------------------------------------*/ 
 270 prepare_states (void) 
 273   symbol_number 
*values 
= xnmalloc (nstates
, sizeof *values
); 
 274   for (i 
= 0; i 
< nstates
; ++i
) 
 275     values
[i
] = states
[i
]->accessing_symbol
; 
 276   muscle_insert_symbol_number_table ("stos", values
, 
 280   MUSCLE_INSERT_INT ("last", high
); 
 281   MUSCLE_INSERT_INT ("final_state_number", final_state
->number
); 
 282   MUSCLE_INSERT_INT ("states_number", nstates
); 
 287 /*-------------------------------------. 
 288 | The list of all the symbol numbers.  | 
 289 `-------------------------------------*/ 
 292 symbol_numbers_output (FILE *out
) 
 295   fputs ("m4_define([b4_symbol_numbers],\n[", out
); 
 296   for (i 
= 0; i 
< nsyms
; ++i
) 
 297     fprintf (out
, "%s[%d]", i 
? ", " : "", i
); 
 298   fputs ("])\n\n", out
); 
 302 /*---------------------------------. 
 303 | Output the user actions to OUT.  | 
 304 `---------------------------------*/ 
 307 user_actions_output (FILE *out
) 
 311   fputs ("m4_define([b4_actions], \n[", out
); 
 312   for (r 
= 0; r 
< nrules
; ++r
) 
 315         fprintf (out
, "b4_case(%d, [b4_syncline(%d, ", r 
+ 1, 
 316                  rules
[r
].action_location
.start
.line
); 
 317         escaped_output (out
, rules
[r
].action_location
.start
.file
); 
 318         fprintf (out
, ")\n[    %s]])\n\n", rules
[r
].action
); 
 320   fputs ("])\n\n", out
); 
 323 /*------------------------------------. 
 324 | Output the merge functions to OUT.  | 
 325 `------------------------------------*/ 
 328 merger_output (FILE *out
) 
 333   fputs ("m4_define([b4_mergers], \n[[", out
); 
 334   for (n 
= 1, p 
= merge_functions
; p 
!= NULL
; n 
+= 1, p 
= p
->next
) 
 336       if (p
->type
[0] == '\0') 
 337         fprintf (out
, "  case %d: *yy0 = %s (*yy0, *yy1); break;\n", 
 340         fprintf (out
, "  case %d: yy0->%s = %s (*yy0, *yy1); break;\n", 
 341                  n
, p
->type
, p
->name
); 
 343   fputs ("]])\n\n", out
); 
 347 /*---------------------------------------. 
 348 | Output the symbol definitions to OUT.  | 
 349 `---------------------------------------*/ 
 352 symbol_definitions_output (FILE *out
) 
 355   for (i 
= 0; i 
< nsyms
; ++i
) 
 357       symbol 
*sym 
= symbols
[i
]; 
 360 #define SET_KEY(Entry)                                                  \ 
 361       obstack_fgrow2 (&format_obstack, "symbol(%d, %s)", i, Entry);     \ 
 362       obstack_1grow (&format_obstack, 0);                               \ 
 363       key = obstack_finish (&format_obstack); 
 366       MUSCLE_INSERT_STRING (key
, sym
->tag
); 
 368       SET_KEY("user_number"); 
 369       MUSCLE_INSERT_INT (key
, sym
->user_token_number
); 
 372       MUSCLE_INSERT_INT (key
, sym
->number
); 
 374       SET_KEY("type_name"); 
 375       MUSCLE_INSERT_STRING (key
, sym
->type_name 
? sym
->type_name 
: ""); 
 382 /*--------------------------------------. 
 383 | Output the tokens definition to OUT.  | 
 384 `--------------------------------------*/ 
 387 token_definitions_output (FILE *out
) 
 390   char const *sep 
= ""; 
 392   fputs ("m4_define([b4_tokens], \n[", out
); 
 393   for (i 
= 0; i 
< ntokens
; ++i
) 
 395       symbol 
*sym 
= symbols
[i
]; 
 396       int number 
= sym
->user_token_number
; 
 398       /* At this stage, if there are literal aliases, they are part of 
 399          SYMBOLS, so we should not find symbols which are the aliases 
 401       aver (number 
!= USER_NUMBER_ALIAS
); 
 403       /* Skip error token.  */ 
 407       /* If this string has an alias, then it is necessarily the alias 
 408          which is to be output.  */ 
 412       /* Don't output literal chars or strings (when defined only as a 
 413          string).  Note that must be done after the alias resolution: 
 414          think about `%token 'f' "f"'.  */ 
 415       if (sym
->tag
[0] == '\'' || sym
->tag
[0] == '\"') 
 418       /* Don't #define nonliteral tokens whose names contain periods 
 419          or '$' (as does the default value of the EOF token).  */ 
 420       if (strchr (sym
->tag
, '.') || strchr (sym
->tag
, '$')) 
 423       fprintf (out
, "%s[[[%s]], %d]", 
 424                sep
, sym
->tag
, number
); 
 427   fputs ("])\n\n", out
); 
 431 /*---------------------------------------------------. 
 432 | Output the symbol destructors or printers to OUT.  | 
 433 `---------------------------------------------------*/ 
 436 symbol_code_props_output (FILE *out
, char const *what
, 
 437                           code_props 
const *(*get
)(symbol 
const *)) 
 440   char const *sep 
= ""; 
 442   fputs ("m4_define([b4_symbol_", out
); 
 444   fputs ("], \n[", out
); 
 445   for (i 
= 0; i 
< nsyms
; ++i
) 
 447       symbol 
*sym 
= symbols
[i
]; 
 448       char const *code 
= (*get
) (sym
)->code
; 
 451           location loc 
= (*get
) (sym
)->location
; 
 453              Symbol-name, Symbol-number, 
 454              code, optional typename.  */ 
 455           fprintf (out
, "%s[", sep
); 
 457           escaped_output (out
, loc
.start
.file
); 
 458           fprintf (out
, ", %d, ", loc
.start
.line
); 
 459           escaped_output (out
, sym
->tag
); 
 460           fprintf (out
, ", %d, [[%s]]", sym
->number
, code
); 
 462             fprintf (out
, ", [[%s]]", sym
->type_name
); 
 466   fputs ("])\n\n", out
); 
 471 prepare_actions (void) 
 473   /* Figure out the actions for the specified state, indexed by 
 474      lookahead token type.  */ 
 476   muscle_insert_rule_number_table ("defact", yydefact
, 
 477                                    yydefact
[0], 1, nstates
); 
 479   /* Figure out what to do after reducing with each rule, depending on 
 480      the saved state from before the beginning of parsing the data 
 481      that matched this rule.  */ 
 482   muscle_insert_state_number_table ("defgoto", yydefgoto
, 
 483                                     yydefgoto
[0], 1, nsyms 
- ntokens
); 
 487   muscle_insert_base_table ("pact", base
, 
 488                              base
[0], 1, nstates
); 
 489   MUSCLE_INSERT_INT ("pact_ninf", base_ninf
); 
 492   muscle_insert_base_table ("pgoto", base
, 
 493                              base
[nstates
], nstates 
+ 1, nvectors
); 
 495   muscle_insert_base_table ("table", table
, 
 496                             table
[0], 1, high 
+ 1); 
 497   MUSCLE_INSERT_INT ("table_ninf", table_ninf
); 
 499   muscle_insert_base_table ("check", check
, 
 500                             check
[0], 1, high 
+ 1); 
 502   /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus 
 503      YYPACT) so that in states with unresolved conflicts, the default 
 504      reduction is not used in the conflicted entries, so that there is 
 505      a place to put a conflict pointer. 
 507      This means that YYCONFLP and YYCONFL are nonsense for a non-GLR 
 508      parser, so we could avoid accidents by not writing them out in 
 509      that case.  Nevertheless, it seems even better to be able to use 
 510      the GLR skeletons even without the non-deterministic tables.  */ 
 511   muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table
, 
 512                                     conflict_table
[0], 1, high 
+ 1); 
 513   muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list
, 
 514                                     0, 1, conflict_list_cnt
); 
 518 /*--------------------------------------------. 
 519 | Output the definitions of all the muscles.  | 
 520 `--------------------------------------------*/ 
 523 muscles_output (FILE *out
) 
 525   fputs ("m4_init()\n", out
); 
 528   symbol_code_props_output (out
, "destructors", &symbol_destructor_get
); 
 529   symbol_code_props_output (out
, "printers", &symbol_printer_get
); 
 530   symbol_definitions_output (out
); 
 531   symbol_numbers_output (out
); 
 532   token_definitions_output (out
); 
 533   user_actions_output (out
); 
 535   muscles_m4_output (out
); 
 538 /*---------------------------. 
 539 | Call the skeleton parser.  | 
 540 `---------------------------*/ 
 543 output_skeleton (void) 
 550   /* Compute the names of the package data dir and skeleton files.  */ 
 551   char const m4sugar
[] = "m4sugar/m4sugar.m4"; 
 552   char const m4bison
[] = "bison.m4"; 
 557   char const *m4 
= (p 
= getenv ("M4")) ? p 
: M4
; 
 558   char const *pkgdatadir 
= compute_pkgdatadir (); 
 559   size_t skeleton_size 
= strlen (skeleton
) + 1; 
 560   size_t pkgdatadirlen 
= strlen (pkgdatadir
); 
 561   while (pkgdatadirlen 
&& pkgdatadir
[pkgdatadirlen 
- 1] == '/') 
 563   full_skeleton 
= xmalloc (pkgdatadirlen 
+ 1 
 564                            + (skeleton_size 
< sizeof m4sugar
 
 565                               ? sizeof m4sugar 
: skeleton_size
)); 
 566   strncpy (full_skeleton
, pkgdatadir
, pkgdatadirlen
); 
 567   full_skeleton
[pkgdatadirlen
] = '/'; 
 568   strcpy (full_skeleton 
+ pkgdatadirlen 
+ 1, m4sugar
); 
 569   full_m4sugar 
= xstrdup (full_skeleton
); 
 570   strcpy (full_skeleton 
+ pkgdatadirlen 
+ 1, m4bison
); 
 571   full_m4bison 
= xstrdup (full_skeleton
); 
 572   if (strchr (skeleton
, '/')) 
 573     strcpy (full_skeleton
, skeleton
); 
 575     strcpy (full_skeleton 
+ pkgdatadirlen 
+ 1, skeleton
); 
 577   /* Test whether m4sugar.m4 is readable, to check for proper 
 578      installation.  A faulty installation can cause deadlock, so a 
 579      cheap sanity check is worthwhile.  */ 
 580   xfclose (xfopen (full_m4sugar
, "r")); 
 582   /* Create an m4 subprocess connected to us via two pipes.  */ 
 584   if (trace_flag 
& trace_tools
) 
 585     fprintf (stderr
, "running: %s %s - %s %s\n", 
 586              m4
, full_m4sugar
, full_m4bison
, full_skeleton
); 
 588   /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a 
 589      position-dependent manner.  Keep it as the first argument so that all 
 592      See the thread starting at 
 593      <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html> 
 599     argv
[i
++] = pkgdatadir
; 
 600     if (trace_flag 
& trace_m4
) 
 602     argv
[i
++] = full_m4sugar
; 
 604     argv
[i
++] = full_m4bison
; 
 605     argv
[i
++] = full_skeleton
; 
 608   /* When POSIXLY_CORRECT is set, some future versions of GNU M4 (most likely 
 609      2.0) may drop some of the GNU extensions that Bison's skeletons depend 
 610      upon.  So that the next release of Bison is forward compatible with those 
 611      future versions of GNU M4, we unset POSIXLY_CORRECT here. 
 613      FIXME: A user might set POSIXLY_CORRECT to affect processes run from 
 614      macros like m4_syscmd in a custom skeleton.  For now, Bison makes no 
 615      promises about the behavior of custom skeletons, so this scenario is not a 
 616      concern.  However, we eventually want to eliminate this shortcoming.  The 
 617      next release of GNU M4 (1.4.12 or 1.6) will accept the -g command-line 
 618      option as a no-op, and later releases will accept it to indicate that 
 619      POSIXLY_CORRECT should be ignored.  Once the GNU M4 versions that accept 
 620      -g are pervasive, Bison should use -g instead of unsetting 
 623      See the thread starting at 
 624      <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html> 
 626   unsetenv ("POSIXLY_CORRECT"); 
 628   pid 
= create_subpipe (argv
, filter_fd
); 
 631   free (full_skeleton
); 
 634   if (trace_flag 
& trace_muscles
) 
 635     muscles_output (stderr
); 
 637     FILE *out 
= fdopen (filter_fd
[0], "w"); 
 639       error (EXIT_FAILURE
, get_errno (), 
 641     muscles_output (out
); 
 645   /* Read and process m4's output.  */ 
 646   timevar_push (TV_M4
); 
 647   end_of_output_subpipe (pid
, filter_fd
); 
 648   in 
= fdopen (filter_fd
[1], "r"); 
 650     error (EXIT_FAILURE
, get_errno (), 
 654   reap_subpipe (pid
, m4
); 
 661   /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be documented 
 663   char const *use_push_for_pull_env 
= getenv ("BISON_USE_PUSH_FOR_PULL"); 
 664   bool use_push_for_pull_flag 
= false; 
 665   if (use_push_for_pull_env 
!= NULL
 
 666       && use_push_for_pull_env
[0] != '\0' 
 667       && 0 != strcmp (use_push_for_pull_env
, "0")) 
 668     use_push_for_pull_flag 
= true; 
 671   MUSCLE_INSERT_BOOL ("debug_flag", debug_flag
); 
 672   MUSCLE_INSERT_BOOL ("defines_flag", defines_flag
); 
 673   MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose
); 
 674   MUSCLE_INSERT_BOOL ("glr_flag", glr_parser
); 
 675   MUSCLE_INSERT_BOOL ("locations_flag", locations_flag
); 
 676   MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser
); 
 677   MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag
); 
 678   MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen
); 
 679   MUSCLE_INSERT_BOOL ("use_push_for_pull_flag", use_push_for_pull_flag
); 
 680   MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag
); 
 683   if (spec_name_prefix
) 
 684     MUSCLE_INSERT_STRING ("prefix", spec_name_prefix
); 
 686   MUSCLE_INSERT_STRING ("file_name_all_but_ext", all_but_ext
); 
 688 #define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "") 
 690   DEFINE (parser_file_name
); 
 691   DEFINE (spec_defines_file
); 
 692   DEFINE (spec_file_prefix
); 
 693   DEFINE (spec_graph_file
); 
 694   DEFINE (spec_name_prefix
); 
 695   DEFINE (spec_outfile
); 
 696   DEFINE (spec_verbose_file
); 
 699   /* Find the right skeleton file, and add muscles about the skeletons.  */ 
 701     MUSCLE_INSERT_C_STRING ("skeleton", skeleton
); 
 703     skeleton 
= language
->skeleton
; 
 705   /* About the skeletons.  */ 
 707     /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs 
 708        would never be expanded.  Hopefully no one has M4-special characters in 
 709        his Bison installation path.  */ 
 710     MUSCLE_INSERT_STRING_RAW ("pkgdatadir", compute_pkgdatadir ()); 
 715 /*----------------------------------------------------------. 
 716 | Output the parsing tables and the parser code to ftable.  | 
 717 `----------------------------------------------------------*/ 
 722   obstack_init (&format_obstack
); 
 731   /* Process the selected skeleton file.  */ 
 734   obstack_free (&format_obstack
, NULL
); 
 738 compute_pkgdatadir (void) 
 740   char const *pkgdatadir 
= getenv ("BISON_PKGDATADIR"); 
 741   return pkgdatadir 
? pkgdatadir 
: PKGDATADIR
;