]> git.saurik.com Git - bison.git/blob - src/output.c
Various DJGGP specific issues in /djgpp.
[bison.git] / src / output.c
1 /* Output the generated parsing program for Bison.
2
3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006 Free Software Foundation, Inc.
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
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)
11 any later version.
12
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.
17
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., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
22
23 #include <config.h>
24 #include "system.h"
25
26 #include <error.h>
27 #include <get-errno.h>
28 #include <quotearg.h>
29 #include <subpipe.h>
30 #include <timevar.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-skel.h"
40 #include "symtab.h"
41 #include "tables.h"
42
43
44 static struct obstack format_obstack;
45
46 bool error_verbose = false;
47
48
49
50 /*-------------------------------------------------------------------.
51 | Create a function NAME which associates to the muscle NAME the |
52 | result of formatting the FIRST and then TABLE_DATA[BEGIN..END[ (of |
53 | TYPE), and to the muscle NAME_max, the max value of the |
54 | TABLE_DATA. |
55 `-------------------------------------------------------------------*/
56
57
58 #define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \
59 \
60 static void \
61 Name (char const *name, \
62 Type *table_data, \
63 Type first, \
64 int begin, \
65 int end) \
66 { \
67 Type min = first; \
68 Type max = first; \
69 long int lmin; \
70 long int lmax; \
71 int i; \
72 int j = 1; \
73 \
74 obstack_fgrow1 (&format_obstack, "%6d", first); \
75 for (i = begin; i < end; ++i) \
76 { \
77 obstack_1grow (&format_obstack, ','); \
78 if (j >= 10) \
79 { \
80 obstack_sgrow (&format_obstack, "\n "); \
81 j = 1; \
82 } \
83 else \
84 ++j; \
85 obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \
86 if (table_data[i] < min) \
87 min = table_data[i]; \
88 if (max < table_data[i]) \
89 max = table_data[i]; \
90 } \
91 obstack_1grow (&format_obstack, 0); \
92 muscle_insert (name, obstack_finish (&format_obstack)); \
93 \
94 lmin = min; \
95 lmax = max; \
96 /* Build `NAME_min' and `NAME_max' in the obstack. */ \
97 obstack_fgrow1 (&format_obstack, "%s_min", name); \
98 obstack_1grow (&format_obstack, 0); \
99 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \
100 obstack_fgrow1 (&format_obstack, "%s_max", name); \
101 obstack_1grow (&format_obstack, 0); \
102 MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \
103 }
104
105 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int)
106 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table, int)
107 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number)
108 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number)
109 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number)
110 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number)
111 GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
112
113
114 /*--------------------------------------------------------------------.
115 | Print to OUT a representation of STRING escaped both for C and M4. |
116 `--------------------------------------------------------------------*/
117
118 static void
119 escaped_output (FILE *out, char const *string)
120 {
121 char const *p;
122 fprintf (out, "[[");
123
124 for (p = quotearg_style (c_quoting_style, string); *p; p++)
125 switch (*p)
126 {
127 case '$': fputs ("$][", out); break;
128 case '@': fputs ("@@", out); break;
129 case '[': fputs ("@{", out); break;
130 case ']': fputs ("@}", out); break;
131 default: fputc (*p, out); break;
132 }
133
134 fprintf (out, "]]");
135 }
136
137
138 /*------------------------------------------------------------------.
139 | Prepare the muscles related to the symbols: translate, tname, and |
140 | toknum. |
141 `------------------------------------------------------------------*/
142
143 static void
144 prepare_symbols (void)
145 {
146 MUSCLE_INSERT_BOOL ("token_table", token_table_flag);
147 MUSCLE_INSERT_INT ("tokens_number", ntokens);
148 MUSCLE_INSERT_INT ("nterms_number", nvars);
149 MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
150 MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
151
152 muscle_insert_symbol_number_table ("translate",
153 token_translations,
154 token_translations[0],
155 1, max_user_token_number + 1);
156
157 /* tname -- token names. */
158 {
159 int i;
160 /* We assume that the table will be output starting at column 2. */
161 int j = 2;
162 for (i = 0; i < nsyms; i++)
163 {
164 char const *cp = quotearg_style (c_quoting_style, symbols[i]->tag);
165 /* Width of the next token, including the two quotes, the
166 comma and the space. */
167 int width = strlen (cp) + 2;
168
169 if (j + width > 75)
170 {
171 obstack_sgrow (&format_obstack, "\n ");
172 j = 1;
173 }
174
175 if (i)
176 obstack_1grow (&format_obstack, ' ');
177 MUSCLE_OBSTACK_SGROW (&format_obstack, cp);
178 obstack_1grow (&format_obstack, ',');
179 j += width;
180 }
181 /* Add a NULL entry to list of tokens (well, 0, as NULL might not be
182 defined). */
183 obstack_sgrow (&format_obstack, " 0");
184
185 /* Finish table and store. */
186 obstack_1grow (&format_obstack, 0);
187 muscle_insert ("tname", obstack_finish (&format_obstack));
188 }
189
190 /* Output YYTOKNUM. */
191 {
192 int i;
193 int *values = xnmalloc (ntokens, sizeof *values);
194 for (i = 0; i < ntokens; ++i)
195 values[i] = symbols[i]->user_token_number;
196 muscle_insert_int_table ("toknum", values,
197 values[0], 1, ntokens);
198 free (values);
199 }
200 }
201
202
203 /*-------------------------------------------------------------.
204 | Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
205 | rline, dprec, merger. |
206 `-------------------------------------------------------------*/
207
208 static void
209 prepare_rules (void)
210 {
211 rule_number r;
212 unsigned int i = 0;
213 item_number *rhs = xnmalloc (nritems, sizeof *rhs);
214 unsigned int *prhs = xnmalloc (nrules, sizeof *prhs);
215 unsigned int *rline = xnmalloc (nrules, sizeof *rline);
216 symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
217 unsigned int *r2 = xnmalloc (nrules, sizeof *r2);
218 int *dprec = xnmalloc (nrules, sizeof *dprec);
219 int *merger = xnmalloc (nrules, sizeof *merger);
220
221 for (r = 0; r < nrules; ++r)
222 {
223 item_number *rhsp = NULL;
224 /* Index of rule R in RHS. */
225 prhs[r] = i;
226 /* RHS of the rule R. */
227 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
228 rhs[i++] = *rhsp;
229 /* LHS of the rule R. */
230 r1[r] = rules[r].lhs->number;
231 /* Length of rule R's RHS. */
232 r2[r] = i - prhs[r];
233 /* Separator in RHS. */
234 rhs[i++] = -1;
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 }
242 assert (i == nritems);
243
244 muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
245 muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules);
246 muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
247 muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
248 muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
249 muscle_insert_int_table ("dprec", dprec, 0, 0, nrules);
250 muscle_insert_int_table ("merger", merger, 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 (rhs);
256 free (prhs);
257 free (rline);
258 free (r1);
259 free (r2);
260 free (dprec);
261 free (merger);
262 }
263
264 /*--------------------------------------------.
265 | Prepare the muscles related to the states. |
266 `--------------------------------------------*/
267
268 static void
269 prepare_states (void)
270 {
271 state_number i;
272 symbol_number *values = xnmalloc (nstates, sizeof *values);
273 for (i = 0; i < nstates; ++i)
274 values[i] = states[i]->accessing_symbol;
275 muscle_insert_symbol_number_table ("stos", values,
276 0, 1, nstates);
277 free (values);
278
279 MUSCLE_INSERT_INT ("last", high);
280 MUSCLE_INSERT_INT ("final_state_number", final_state->number);
281 MUSCLE_INSERT_INT ("states_number", nstates);
282 }
283
284
285
286 /*---------------------------------.
287 | Output the user actions to OUT. |
288 `---------------------------------*/
289
290 static void
291 user_actions_output (FILE *out)
292 {
293 rule_number r;
294
295 fputs ("m4_define([b4_actions], \n[[", out);
296 for (r = 0; r < nrules; ++r)
297 if (rules[r].action)
298 {
299 fprintf (out, " case %d:\n", r + 1);
300
301 fprintf (out, "]b4_syncline(%d, ",
302 rules[r].action_location.start.line);
303 escaped_output (out, rules[r].action_location.start.file);
304 fprintf (out, ")[\n");
305 fprintf (out, " %s\n break;\n\n",
306 rules[r].action);
307 }
308 fputs ("]])\n\n", out);
309 }
310
311 /*--------------------------------------.
312 | Output the merge functions to OUT. |
313 `--------------------------------------*/
314
315 static void
316 merger_output (FILE *out)
317 {
318 int n;
319 merger_list* p;
320
321 fputs ("m4_define([b4_mergers], \n[[", out);
322 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
323 {
324 if (p->type[0] == '\0')
325 fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
326 n, p->name);
327 else
328 fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
329 n, p->type, p->name);
330 }
331 fputs ("]])\n\n", out);
332 }
333
334 /*--------------------------------------.
335 | Output the tokens definition to OUT. |
336 `--------------------------------------*/
337
338 static void
339 token_definitions_output (FILE *out)
340 {
341 int i;
342 char const *sep = "";
343
344 fputs ("m4_define([b4_tokens], \n[", out);
345 for (i = 0; i < ntokens; ++i)
346 {
347 symbol *sym = symbols[i];
348 int number = sym->user_token_number;
349
350 /* At this stage, if there are literal aliases, they are part of
351 SYMBOLS, so we should not find symbols which are the aliases
352 here. */
353 assert (number != USER_NUMBER_ALIAS);
354
355 /* Skip error token. */
356 if (sym == errtoken)
357 continue;
358
359 /* If this string has an alias, then it is necessarily the alias
360 which is to be output. */
361 if (sym->alias)
362 sym = sym->alias;
363
364 /* Don't output literal chars or strings (when defined only as a
365 string). Note that must be done after the alias resolution:
366 think about `%token 'f' "f"'. */
367 if (sym->tag[0] == '\'' || sym->tag[0] == '\"')
368 continue;
369
370 /* Don't #define nonliteral tokens whose names contain periods
371 or '$' (as does the default value of the EOF token). */
372 if (strchr (sym->tag, '.') || strchr (sym->tag, '$'))
373 continue;
374
375 fprintf (out, "%s[[[%s]], %d]",
376 sep, sym->tag, number);
377 sep = ",\n";
378 }
379 fputs ("])\n\n", out);
380 }
381
382
383 /*---------------------------------------.
384 | Output the symbol destructors to OUT. |
385 `---------------------------------------*/
386
387 static void
388 symbol_destructors_output (FILE *out)
389 {
390 int i;
391 char const *sep = "";
392
393 fputs ("m4_define([b4_symbol_destructors], \n[", out);
394 for (i = 0; i < nsyms; ++i)
395 if (symbols[i]->destructor)
396 {
397 symbol *sym = symbols[i];
398
399 /* Filename, lineno,
400 Symbol-name, Symbol-number,
401 destructor, optional typename. */
402 fprintf (out, "%s[", sep);
403 sep = ",\n";
404 escaped_output (out, sym->destructor_location.start.file);
405 fprintf (out, ", %d, ", sym->destructor_location.start.line);
406 escaped_output (out, sym->tag);
407 fprintf (out, ", %d, [[%s]]", sym->number, sym->destructor);
408 if (sym->type_name)
409 fprintf (out, ", [[%s]]", sym->type_name);
410 fputc (']', out);
411 }
412 fputs ("])\n\n", out);
413 }
414
415
416 /*------------------------------------.
417 | Output the symbol printers to OUT. |
418 `------------------------------------*/
419
420 static void
421 symbol_printers_output (FILE *out)
422 {
423 int i;
424 char const *sep = "";
425
426 fputs ("m4_define([b4_symbol_printers], \n[", out);
427 for (i = 0; i < nsyms; ++i)
428 if (symbols[i]->printer)
429 {
430 symbol *sym = symbols[i];
431
432 /* Filename, lineno,
433 Symbol-name, Symbol-number,
434 printer, optional typename. */
435 fprintf (out, "%s[", sep);
436 sep = ",\n";
437 escaped_output (out, sym->printer_location.start.file);
438 fprintf (out, ", %d, ", sym->printer_location.start.line);
439 escaped_output (out, sym->tag);
440 fprintf (out, ", %d, [[%s]]", sym->number, sym->printer);
441 if (sym->type_name)
442 fprintf (out, ", [[%s]]", sym->type_name);
443 fputc (']', out);
444 }
445 fputs ("])\n\n", out);
446 }
447
448
449 static void
450 prepare_actions (void)
451 {
452 /* Figure out the actions for the specified state, indexed by
453 look-ahead token type. */
454
455 muscle_insert_rule_number_table ("defact", yydefact,
456 yydefact[0], 1, nstates);
457
458 /* Figure out what to do after reducing with each rule, depending on
459 the saved state from before the beginning of parsing the data
460 that matched this rule. */
461 muscle_insert_state_number_table ("defgoto", yydefgoto,
462 yydefgoto[0], 1, nsyms - ntokens);
463
464
465 /* Output PACT. */
466 muscle_insert_base_table ("pact", base,
467 base[0], 1, nstates);
468 MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
469
470 /* Output PGOTO. */
471 muscle_insert_base_table ("pgoto", base,
472 base[nstates], nstates + 1, nvectors);
473
474 muscle_insert_base_table ("table", table,
475 table[0], 1, high + 1);
476 MUSCLE_INSERT_INT ("table_ninf", table_ninf);
477
478 muscle_insert_base_table ("check", check,
479 check[0], 1, high + 1);
480
481 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
482 YYPACT) so that in states with unresolved conflicts, the default
483 reduction is not used in the conflicted entries, so that there is
484 a place to put a conflict pointer.
485
486 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
487 parser, so we could avoid accidents by not writing them out in
488 that case. Nevertheless, it seems even better to be able to use
489 the GLR skeletons even without the non-deterministic tables. */
490 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
491 conflict_table[0], 1, high + 1);
492 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
493 0, 1, conflict_list_cnt);
494 }
495
496 \f
497 /*---------------------------.
498 | Call the skeleton parser. |
499 `---------------------------*/
500
501 static void
502 output_skeleton (void)
503 {
504 FILE *in;
505 FILE *out;
506 int filter_fd[2];
507 char const *argv[5];
508 pid_t pid;
509
510 /* Compute the names of the package data dir and skeleton file.
511 Test whether m4sugar.m4 is readable, to check for proper
512 installation. A faulty installation can cause deadlock, so a
513 cheap sanity check is worthwhile. */
514 char const m4sugar[] = "m4sugar/m4sugar.m4";
515 char *full_m4sugar;
516 char *full_skeleton;
517 char const *p;
518 char const *m4 = (p = getenv ("M4")) ? p : M4;
519 char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR;
520 size_t skeleton_size = strlen (skeleton) + 1;
521 size_t pkgdatadirlen = strlen (pkgdatadir);
522 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
523 pkgdatadirlen--;
524 full_skeleton = xmalloc (pkgdatadirlen + 1
525 + (skeleton_size < sizeof m4sugar
526 ? sizeof m4sugar : skeleton_size));
527 strcpy (full_skeleton, pkgdatadir);
528 full_skeleton[pkgdatadirlen] = '/';
529 strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
530 full_m4sugar = xstrdup (full_skeleton);
531 strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
532 xfclose (xfopen (full_m4sugar, "r"));
533
534 /* Create an m4 subprocess connected to us via two pipes. */
535
536 if (trace_flag & trace_tools)
537 fprintf (stderr, "running: %s %s - %s\n",
538 m4, full_m4sugar, full_skeleton);
539
540 argv[0] = m4;
541 argv[1] = full_m4sugar;
542 argv[2] = "-";
543 argv[3] = full_skeleton;
544 argv[4] = NULL;
545
546 init_subpipe ();
547 pid = create_subpipe (argv, filter_fd);
548 free (full_m4sugar);
549 free (full_skeleton);
550
551 out = fdopen (filter_fd[0], "w");
552 if (! out)
553 error (EXIT_FAILURE, get_errno (),
554 "fdopen");
555
556 /* Output the definitions of all the muscles. */
557 fputs ("m4_init()\n", out);
558
559 user_actions_output (out);
560 merger_output (out);
561 token_definitions_output (out);
562 symbol_destructors_output (out);
563 symbol_printers_output (out);
564
565 muscles_m4_output (out);
566
567 fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
568 fputs ("m4_divert_push(0)dnl\n", out);
569 xfclose (out);
570
571 /* Read and process m4's output. */
572 timevar_push (TV_M4);
573 end_of_output_subpipe (pid, filter_fd);
574 in = fdopen (filter_fd[1], "r");
575 if (! in)
576 error (EXIT_FAILURE, get_errno (),
577 "fdopen");
578 scan_skel (in);
579 xfclose (in);
580 reap_subpipe (pid, m4);
581 timevar_pop (TV_M4);
582 }
583
584 static void
585 prepare (void)
586 {
587 /* Flags. */
588 MUSCLE_INSERT_BOOL ("debug", debug_flag);
589 MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
590 MUSCLE_INSERT_BOOL ("error_verbose", error_verbose);
591 MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
592 MUSCLE_INSERT_BOOL ("pure", pure_parser);
593 MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
594
595 /* File names. */
596 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
597 #define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "")
598 DEFINE (dir_prefix);
599 DEFINE (parser_file_name);
600 DEFINE (spec_defines_file);
601 DEFINE (spec_file_prefix);
602 DEFINE (spec_graph_file);
603 DEFINE (spec_name_prefix);
604 DEFINE (spec_outfile);
605 DEFINE (spec_verbose_file);
606 #undef DEFINE
607
608 /* User Code. */
609 obstack_1grow (&pre_prologue_obstack, 0);
610 obstack_1grow (&post_prologue_obstack, 0);
611 muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack));
612 muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack));
613
614 /* Find the right skeleton file. */
615 if (!skeleton)
616 {
617 if (glr_parser || nondeterministic_parser)
618 skeleton = "glr.c";
619 else
620 skeleton = "yacc.c";
621 }
622
623 /* About the skeletons. */
624 {
625 char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
626 MUSCLE_INSERT_STRING ("pkgdatadir", pkgdatadir ? pkgdatadir : PKGDATADIR);
627 MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
628 }
629 }
630
631
632 /*----------------------------------------------------------.
633 | Output the parsing tables and the parser code to ftable. |
634 `----------------------------------------------------------*/
635
636 void
637 output (void)
638 {
639 obstack_init (&format_obstack);
640
641 prepare_symbols ();
642 prepare_rules ();
643 prepare_states ();
644 prepare_actions ();
645
646 prepare ();
647
648 /* Process the selected skeleton file. */
649 output_skeleton ();
650
651 obstack_free (&format_obstack, NULL);
652 obstack_free (&pre_prologue_obstack, NULL);
653 obstack_free (&post_prologue_obstack, NULL);
654 }