1 /* Output the generated parsing program for Bison. 
   3    Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005 
   4    Free Software Foundation, Inc. 
   6    This file is part of Bison, the GNU Compiler Compiler. 
   8    Bison is free software; you can redistribute it and/or modify it 
   9    under the terms of the GNU General Public License as published by 
  10    the Free Software Foundation; either version 2, or (at your option) 
  13    Bison is distributed in the hope that it will be useful, but 
  14    WITHOUT ANY WARRANTY; without even the implied warranty of 
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  16    General Public License for more details. 
  18    You should have received a copy of the GNU General Public License 
  19    along with Bison; see the file COPYING.  If not, write to the Free 
  20    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
  27 #include <get-errno.h> 
  36 #include "muscle_tab.h" 
  42 /* From src/scan-skel.l. */ 
  43 void scan_skel (FILE *); 
  46 static struct obstack format_obstack
; 
  48 bool error_verbose 
= false; 
  52 /*-------------------------------------------------------------------. 
  53 | Create a function NAME which associates to the muscle NAME the     | 
  54 | result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of | 
  55 | TYPE), and to the muscle NAME_max, the max value of the            | 
  57 `-------------------------------------------------------------------*/ 
  60 #define GENERATE_MUSCLE_INSERT_TABLE(Name, Type)                        \ 
  63 Name (const char *name,                                                 \ 
  76   obstack_fgrow1 (&format_obstack, "%6d", first);                       \ 
  77   for (i = begin; i < end; ++i)                                         \ 
  79       obstack_1grow (&format_obstack, ',');                             \ 
  82           obstack_sgrow (&format_obstack, "\n  ");                      \ 
  87       obstack_fgrow1 (&format_obstack, "%6d", table_data[i]);           \ 
  88       if (table_data[i] < min)                                          \ 
  89         min = table_data[i];                                            \ 
  90       if (max < table_data[i])                                          \ 
  91         max = table_data[i];                                            \ 
  93   obstack_1grow (&format_obstack, 0);                                   \ 
  94   muscle_insert (name, obstack_finish (&format_obstack));               \ 
  98   /* Build `NAME_min' and `NAME_max' in the obstack. */                 \ 
  99   obstack_fgrow1 (&format_obstack, "%s_min", name);                     \ 
 100   obstack_1grow (&format_obstack, 0);                                   \ 
 101   MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin);      \ 
 102   obstack_fgrow1 (&format_obstack, "%s_max", name);                     \ 
 103   obstack_1grow (&format_obstack, 0);                                   \ 
 104   MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax);      \ 
 107 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table
, unsigned int) 
 108 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table
, int) 
 109 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table
, base_number
) 
 110 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table
, rule_number
) 
 111 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table
, symbol_number
) 
 112 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table
, item_number
) 
 113 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table
, state_number
) 
 116 /*--------------------------------------------------------------------. 
 117 | Print to OUT a representation of STRING escaped both for C and M4.  | 
 118 `--------------------------------------------------------------------*/ 
 121 escaped_output (FILE *out
, char const *string
) 
 126   for (p 
= quotearg_style (c_quoting_style
, string
); *p
; p
++) 
 129       case '$': fputs ("$][", out
); break; 
 130       case '@': fputs ("@@",  out
); break; 
 131       case '[': fputs ("@{",  out
); break; 
 132       case ']': fputs ("@}",  out
); break; 
 133       default: fputc (*p
, out
); break; 
 140 /*------------------------------------------------------------------. 
 141 | Prepare the muscles related to the symbols: translate, tname, and | 
 143 `------------------------------------------------------------------*/ 
 146 prepare_symbols (void) 
 148   MUSCLE_INSERT_INT ("tokens_number", ntokens
); 
 149   MUSCLE_INSERT_INT ("nterms_number", nvars
); 
 150   MUSCLE_INSERT_INT ("undef_token_number", undeftoken
->number
); 
 151   MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number
); 
 153   muscle_insert_symbol_number_table ("translate", 
 155                                      token_translations
[0], 
 156                                      1, max_user_token_number 
+ 1); 
 158   /* tname -- token names.  */ 
 161     /* We assume that the table will be output starting at column 2. */ 
 163     for (i 
= 0; i 
< nsyms
; i
++) 
 165         const char *cp 
= quotearg_style (c_quoting_style
, symbols
[i
]->tag
); 
 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
); 
 179         obstack_1grow (&format_obstack
, ','); 
 182     /* Add a NULL entry to list of tokens (well, 0, as NULL might not be 
 184     obstack_sgrow (&format_obstack
, " 0"); 
 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
; 
 246   muscle_insert_item_number_table ("rhs", rhs
, ritem
[0], 1, nritems
); 
 247   muscle_insert_unsigned_int_table ("prhs", prhs
, 0, 0, nrules
); 
 248   muscle_insert_unsigned_int_table ("rline", rline
, 0, 0, nrules
); 
 249   muscle_insert_symbol_number_table ("r1", r1
, 0, 0, nrules
); 
 250   muscle_insert_unsigned_int_table ("r2", r2
, 0, 0, nrules
); 
 251   muscle_insert_int_table ("dprec", dprec
, 0, 0, nrules
); 
 252   muscle_insert_int_table ("merger", merger
, 0, 0, nrules
); 
 254   MUSCLE_INSERT_INT ("rules_number", nrules
); 
 255   MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context
); 
 266 /*--------------------------------------------. 
 267 | Prepare the muscles related to the states.  | 
 268 `--------------------------------------------*/ 
 271 prepare_states (void) 
 274   symbol_number 
*values 
= xnmalloc (nstates
, sizeof *values
); 
 275   for (i 
= 0; i 
< nstates
; ++i
) 
 276     values
[i
] = states
[i
]->accessing_symbol
; 
 277   muscle_insert_symbol_number_table ("stos", values
, 
 281   MUSCLE_INSERT_INT ("last", high
); 
 282   MUSCLE_INSERT_INT ("final_state_number", final_state
->number
); 
 283   MUSCLE_INSERT_INT ("states_number", nstates
); 
 288 /*---------------------------------. 
 289 | Output the user actions to OUT.  | 
 290 `---------------------------------*/ 
 293 user_actions_output (FILE *out
) 
 297   fputs ("m4_define([b4_actions], \n[[", out
); 
 298   for (r 
= 0; r 
< nrules
; ++r
) 
 301         fprintf (out
, "  case %d:\n", r 
+ 1); 
 303         fprintf (out
, "]b4_syncline(%d, ", 
 304                  rules
[r
].action_location
.start
.line
); 
 305         escaped_output (out
, rules
[r
].action_location
.start
.file
); 
 306         fprintf (out
, ")[\n"); 
 307         fprintf (out
, "    %s\n    break;\n\n", 
 310   fputs ("]])\n\n", out
); 
 313 /*--------------------------------------. 
 314 | Output the merge functions to OUT.   | 
 315 `--------------------------------------*/ 
 318 merger_output (FILE *out
) 
 323   fputs ("m4_define([b4_mergers], \n[[", out
); 
 324   for (n 
= 1, p 
= merge_functions
; p 
!= NULL
; n 
+= 1, p 
= p
->next
) 
 326       if (p
->type
[0] == '\0') 
 327         fprintf (out
, "  case %d: *yy0 = %s (*yy0, *yy1); break;\n", 
 330         fprintf (out
, "  case %d: yy0->%s = %s (*yy0, *yy1); break;\n", 
 331                  n
, p
->type
, p
->name
); 
 333   fputs ("]])\n\n", out
); 
 336 /*--------------------------------------. 
 337 | Output the tokens definition to OUT.  | 
 338 `--------------------------------------*/ 
 341 token_definitions_output (FILE *out
) 
 344   char const *sep 
= ""; 
 346   fputs ("m4_define([b4_tokens], \n[", out
); 
 347   for (i 
= 0; i 
< ntokens
; ++i
) 
 349       symbol 
*sym 
= symbols
[i
]; 
 350       int number 
= sym
->user_token_number
; 
 352       /* At this stage, if there are literal aliases, they are part of 
 353          SYMBOLS, so we should not find symbols which are the aliases 
 355       if (number 
== USER_NUMBER_ALIAS
) 
 358       /* Skip error token.  */ 
 362       /* If this string has an alias, then it is necessarily the alias 
 363          which is to be output.  */ 
 367       /* Don't output literal chars or strings (when defined only as a 
 368          string).  Note that must be done after the alias resolution: 
 369          think about `%token 'f' "f"'.  */ 
 370       if (sym
->tag
[0] == '\'' || sym
->tag
[0] == '\"') 
 373       /* Don't #define nonliteral tokens whose names contain periods 
 374          or '$' (as does the default value of the EOF token).  */ 
 375       if (strchr (sym
->tag
, '.') || strchr (sym
->tag
, '$')) 
 378       fprintf (out
, "%s[[[%s]], %d]", 
 379                sep
, sym
->tag
, number
); 
 382   fputs ("])\n\n", out
); 
 386 /*---------------------------------------. 
 387 | Output the symbol destructors to OUT.  | 
 388 `---------------------------------------*/ 
 391 symbol_destructors_output (FILE *out
) 
 394   char const *sep 
= ""; 
 396   fputs ("m4_define([b4_symbol_destructors], \n[", out
); 
 397   for (i 
= 0; i 
< nsyms
; ++i
) 
 398     if (symbols
[i
]->destructor
) 
 400         symbol 
*sym 
= symbols
[i
]; 
 403            Symbol-name, Symbol-number, 
 404            destructor, optional typename.  */ 
 405         fprintf (out
, "%s[", sep
); 
 407         escaped_output (out
, sym
->destructor_location
.start
.file
); 
 408         fprintf (out
, ", %d, ", sym
->destructor_location
.start
.line
); 
 409         escaped_output (out
, sym
->tag
); 
 410         fprintf (out
, ", %d, [[%s]]", sym
->number
, sym
->destructor
); 
 412           fprintf (out
, ", [[%s]]", sym
->type_name
); 
 415   fputs ("])\n\n", out
); 
 419 /*------------------------------------. 
 420 | Output the symbol printers to OUT.  | 
 421 `------------------------------------*/ 
 424 symbol_printers_output (FILE *out
) 
 427   char const *sep 
= ""; 
 429   fputs ("m4_define([b4_symbol_printers], \n[", out
); 
 430   for (i 
= 0; i 
< nsyms
; ++i
) 
 431     if (symbols
[i
]->printer
) 
 433         symbol 
*sym 
= symbols
[i
]; 
 436            Symbol-name, Symbol-number, 
 437            printer, optional typename.  */ 
 438         fprintf (out
, "%s[", sep
); 
 440         escaped_output (out
, sym
->printer_location
.start
.file
); 
 441         fprintf (out
, ", %d, ", sym
->printer_location
.start
.line
); 
 442         escaped_output (out
, sym
->tag
); 
 443         fprintf (out
, ", %d, [[%s]]", sym
->number
, sym
->printer
); 
 445           fprintf (out
, ", [[%s]]", sym
->type_name
); 
 448   fputs ("])\n\n", out
); 
 453 prepare_actions (void) 
 455   /* Figure out the actions for the specified state, indexed by 
 456      look-ahead token type.  */ 
 458   muscle_insert_rule_number_table ("defact", yydefact
, 
 459                                    yydefact
[0], 1, nstates
); 
 461   /* Figure out what to do after reducing with each rule, depending on 
 462      the saved state from before the beginning of parsing the data 
 463      that matched this rule.  */ 
 464   muscle_insert_state_number_table ("defgoto", yydefgoto
, 
 465                                     yydefgoto
[0], 1, nsyms 
- ntokens
); 
 469   muscle_insert_base_table ("pact", base
, 
 470                              base
[0], 1, nstates
); 
 471   MUSCLE_INSERT_INT ("pact_ninf", base_ninf
); 
 474   muscle_insert_base_table ("pgoto", base
, 
 475                              base
[nstates
], nstates 
+ 1, nvectors
); 
 477   muscle_insert_base_table ("table", table
, 
 478                             table
[0], 1, high 
+ 1); 
 479   MUSCLE_INSERT_INT ("table_ninf", table_ninf
); 
 481   muscle_insert_base_table ("check", check
, 
 482                             check
[0], 1, high 
+ 1); 
 484   /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus 
 485      YYPACT) so that in states with unresolved conflicts, the default 
 486      reduction is not used in the conflicted entries, so that there is 
 487      a place to put a conflict pointer. 
 489      This means that YYCONFLP and YYCONFL are nonsense for a non-GLR 
 490      parser, so we could avoid accidents by not writing them out in 
 491      that case.  Nevertheless, it seems even better to be able to use 
 492      the GLR skeletons even without the non-deterministic tables.  */ 
 493   muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table
, 
 494                                     conflict_table
[0], 1, high 
+ 1); 
 495   muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list
, 
 496                                     0, 1, conflict_list_cnt
); 
 500 /*---------------------------. 
 501 | Call the skeleton parser.  | 
 502 `---------------------------*/ 
 505 output_skeleton (void) 
 513   /* Compute the names of the package data dir and skeleton file. 
 514      Test whether m4sugar.m4 is readable, to check for proper 
 515      installation.  A faulty installation can cause deadlock, so a 
 516      cheap sanity check is worthwhile.  */ 
 517   char const m4sugar
[] = "m4sugar/m4sugar.m4"; 
 522   char const *m4 
= (p 
= getenv ("M4")) ? p 
: M4
; 
 523   char const *pkgdatadir 
= (p 
= getenv ("BISON_PKGDATADIR")) ? p 
: PKGDATADIR
; 
 524   size_t skeleton_size 
= strlen (skeleton
) + 1; 
 525   size_t pkgdatadirlen 
= strlen (pkgdatadir
); 
 526   while (pkgdatadirlen 
&& pkgdatadir
[pkgdatadirlen 
- 1] == '/') 
 528   full_skeleton 
= xmalloc (pkgdatadirlen 
+ 1 
 529                            + (skeleton_size 
< sizeof m4sugar
 
 530                               ? sizeof m4sugar 
: skeleton_size
)); 
 531   strcpy (full_skeleton
, pkgdatadir
); 
 532   full_skeleton
[pkgdatadirlen
] = '/'; 
 533   strcpy (full_skeleton 
+ pkgdatadirlen 
+ 1, m4sugar
); 
 534   full_m4sugar 
= xstrdup (full_skeleton
); 
 535   strcpy (full_skeleton 
+ pkgdatadirlen 
+ 1, "c.m4"); 
 536   full_cm4 
= xstrdup (full_skeleton
); 
 537   strcpy (full_skeleton 
+ pkgdatadirlen 
+ 1, skeleton
); 
 538   xfclose (xfopen (full_m4sugar
, "r")); 
 540   /* Create an m4 subprocess connected to us via two pipes.  */ 
 542   if (trace_flag 
& trace_tools
) 
 543     fprintf (stderr
, "running: %s %s - %s %s\n", 
 544              m4
, full_m4sugar
, full_cm4
, full_skeleton
); 
 547   argv
[1] = full_m4sugar
; 
 550   argv
[4] = full_skeleton
; 
 554   pid 
= create_subpipe (argv
, filter_fd
); 
 557   free (full_skeleton
); 
 559   out 
= fdopen (filter_fd
[0], "w"); 
 561     error (EXIT_FAILURE
, get_errno (), "fdopen"); 
 563   /* Output the definitions of all the muscles.  */ 
 564   fputs ("m4_init()\n", out
); 
 566   user_actions_output (out
); 
 568   token_definitions_output (out
); 
 569   symbol_destructors_output (out
); 
 570   symbol_printers_output (out
); 
 572   muscles_m4_output (out
); 
 574   fputs ("m4_wrap([m4_divert_pop(0)])\n", out
); 
 575   fputs ("m4_divert_push(0)dnl\n", out
); 
 578   /* Read and process m4's output.  */ 
 579   timevar_push (TV_M4
); 
 580   in 
= fdopen (filter_fd
[1], "r"); 
 582     error (EXIT_FAILURE
, get_errno (), "fdopen"); 
 585   reap_subpipe (pid
, m4
); 
 593   MUSCLE_INSERT_BOOL ("debug", debug_flag
); 
 594   MUSCLE_INSERT_BOOL ("defines_flag", defines_flag
); 
 595   MUSCLE_INSERT_BOOL ("error_verbose", error_verbose
); 
 596   MUSCLE_INSERT_BOOL ("locations_flag", locations_flag
); 
 597   MUSCLE_INSERT_BOOL ("pure", pure_parser
); 
 598   MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag
); 
 601   MUSCLE_INSERT_STRING ("prefix", spec_name_prefix 
? spec_name_prefix 
: "yy"); 
 604   obstack_1grow (&pre_prologue_obstack
, 0); 
 605   obstack_1grow (&post_prologue_obstack
, 0); 
 606   muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack
)); 
 607   muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack
)); 
 609   /* Find the right skeleton file.  */ 
 612       if (glr_parser 
|| nondeterministic_parser
) 
 618   /* Parse the skeleton file and output the needed parsers.  */ 
 619   MUSCLE_INSERT_C_STRING ("skeleton", skeleton
); 
 623 /*----------------------------------------------------------. 
 624 | Output the parsing tables and the parser code to ftable.  | 
 625 `----------------------------------------------------------*/ 
 630   obstack_init (&format_obstack
); 
 639   /* Process the selected skeleton file.  */ 
 642   obstack_free (&format_obstack
, NULL
); 
 643   obstack_free (&pre_prologue_obstack
, NULL
); 
 644   obstack_free (&post_prologue_obstack
, NULL
);