]> git.saurik.com Git - bison.git/blob - src/output.c
DJGPP specific file.
[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, 2005
4 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 if (i != nritems)
243 abort ();
244
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);
252
253 MUSCLE_INSERT_INT ("rules_number", nrules);
254 MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
255
256 free (rhs);
257 free (prhs);
258 free (rline);
259 free (r1);
260 free (r2);
261 free (dprec);
262 free (merger);
263 }
264
265 /*--------------------------------------------.
266 | Prepare the muscles related to the states. |
267 `--------------------------------------------*/
268
269 static void
270 prepare_states (void)
271 {
272 state_number i;
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,
277 0, 1, nstates);
278 free (values);
279
280 MUSCLE_INSERT_INT ("last", high);
281 MUSCLE_INSERT_INT ("final_state_number", final_state->number);
282 MUSCLE_INSERT_INT ("states_number", nstates);
283 }
284
285
286
287 /*---------------------------------.
288 | Output the user actions to OUT. |
289 `---------------------------------*/
290
291 static void
292 user_actions_output (FILE *out)
293 {
294 rule_number r;
295
296 fputs ("m4_define([b4_actions], \n[[", out);
297 for (r = 0; r < nrules; ++r)
298 if (rules[r].action)
299 {
300 fprintf (out, " case %d:\n", r + 1);
301
302 fprintf (out, "]b4_syncline(%d, ",
303 rules[r].action_location.start.line);
304 escaped_output (out, rules[r].action_location.start.file);
305 fprintf (out, ")[\n");
306 fprintf (out, " %s\n break;\n\n",
307 rules[r].action);
308 }
309 fputs ("]])\n\n", out);
310 }
311
312 /*--------------------------------------.
313 | Output the merge functions to OUT. |
314 `--------------------------------------*/
315
316 static void
317 merger_output (FILE *out)
318 {
319 int n;
320 merger_list* p;
321
322 fputs ("m4_define([b4_mergers], \n[[", out);
323 for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
324 {
325 if (p->type[0] == '\0')
326 fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
327 n, p->name);
328 else
329 fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
330 n, p->type, p->name);
331 }
332 fputs ("]])\n\n", out);
333 }
334
335 /*--------------------------------------.
336 | Output the tokens definition to OUT. |
337 `--------------------------------------*/
338
339 static void
340 token_definitions_output (FILE *out)
341 {
342 int i;
343 char const *sep = "";
344
345 fputs ("m4_define([b4_tokens], \n[", out);
346 for (i = 0; i < ntokens; ++i)
347 {
348 symbol *sym = symbols[i];
349 int number = sym->user_token_number;
350
351 /* At this stage, if there are literal aliases, they are part of
352 SYMBOLS, so we should not find symbols which are the aliases
353 here. */
354 if (number == USER_NUMBER_ALIAS)
355 abort ();
356
357 /* Skip error token. */
358 if (sym == errtoken)
359 continue;
360
361 /* If this string has an alias, then it is necessarily the alias
362 which is to be output. */
363 if (sym->alias)
364 sym = sym->alias;
365
366 /* Don't output literal chars or strings (when defined only as a
367 string). Note that must be done after the alias resolution:
368 think about `%token 'f' "f"'. */
369 if (sym->tag[0] == '\'' || sym->tag[0] == '\"')
370 continue;
371
372 /* Don't #define nonliteral tokens whose names contain periods
373 or '$' (as does the default value of the EOF token). */
374 if (strchr (sym->tag, '.') || strchr (sym->tag, '$'))
375 continue;
376
377 fprintf (out, "%s[[[%s]], %d]",
378 sep, sym->tag, number);
379 sep = ",\n";
380 }
381 fputs ("])\n\n", out);
382 }
383
384
385 /*---------------------------------------.
386 | Output the symbol destructors to OUT. |
387 `---------------------------------------*/
388
389 static void
390 symbol_destructors_output (FILE *out)
391 {
392 int i;
393 char const *sep = "";
394
395 fputs ("m4_define([b4_symbol_destructors], \n[", out);
396 for (i = 0; i < nsyms; ++i)
397 if (symbols[i]->destructor)
398 {
399 symbol *sym = symbols[i];
400
401 /* Filename, lineno,
402 Symbol-name, Symbol-number,
403 destructor, optional typename. */
404 fprintf (out, "%s[", sep);
405 sep = ",\n";
406 escaped_output (out, sym->destructor_location.start.file);
407 fprintf (out, ", %d, ", sym->destructor_location.start.line);
408 escaped_output (out, sym->tag);
409 fprintf (out, ", %d, [[%s]]", sym->number, sym->destructor);
410 if (sym->type_name)
411 fprintf (out, ", [[%s]]", sym->type_name);
412 fputc (']', out);
413 }
414 fputs ("])\n\n", out);
415 }
416
417
418 /*------------------------------------.
419 | Output the symbol printers to OUT. |
420 `------------------------------------*/
421
422 static void
423 symbol_printers_output (FILE *out)
424 {
425 int i;
426 char const *sep = "";
427
428 fputs ("m4_define([b4_symbol_printers], \n[", out);
429 for (i = 0; i < nsyms; ++i)
430 if (symbols[i]->printer)
431 {
432 symbol *sym = symbols[i];
433
434 /* Filename, lineno,
435 Symbol-name, Symbol-number,
436 printer, optional typename. */
437 fprintf (out, "%s[", sep);
438 sep = ",\n";
439 escaped_output (out, sym->printer_location.start.file);
440 fprintf (out, ", %d, ", sym->printer_location.start.line);
441 escaped_output (out, sym->tag);
442 fprintf (out, ", %d, [[%s]]", sym->number, sym->printer);
443 if (sym->type_name)
444 fprintf (out, ", [[%s]]", sym->type_name);
445 fputc (']', out);
446 }
447 fputs ("])\n\n", out);
448 }
449
450
451 static void
452 prepare_actions (void)
453 {
454 /* Figure out the actions for the specified state, indexed by
455 look-ahead token type. */
456
457 muscle_insert_rule_number_table ("defact", yydefact,
458 yydefact[0], 1, nstates);
459
460 /* Figure out what to do after reducing with each rule, depending on
461 the saved state from before the beginning of parsing the data
462 that matched this rule. */
463 muscle_insert_state_number_table ("defgoto", yydefgoto,
464 yydefgoto[0], 1, nsyms - ntokens);
465
466
467 /* Output PACT. */
468 muscle_insert_base_table ("pact", base,
469 base[0], 1, nstates);
470 MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
471
472 /* Output PGOTO. */
473 muscle_insert_base_table ("pgoto", base,
474 base[nstates], nstates + 1, nvectors);
475
476 muscle_insert_base_table ("table", table,
477 table[0], 1, high + 1);
478 MUSCLE_INSERT_INT ("table_ninf", table_ninf);
479
480 muscle_insert_base_table ("check", check,
481 check[0], 1, high + 1);
482
483 /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
484 YYPACT) so that in states with unresolved conflicts, the default
485 reduction is not used in the conflicted entries, so that there is
486 a place to put a conflict pointer.
487
488 This means that YYCONFLP and YYCONFL are nonsense for a non-GLR
489 parser, so we could avoid accidents by not writing them out in
490 that case. Nevertheless, it seems even better to be able to use
491 the GLR skeletons even without the non-deterministic tables. */
492 muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
493 conflict_table[0], 1, high + 1);
494 muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
495 0, 1, conflict_list_cnt);
496 }
497
498 \f
499 /*---------------------------.
500 | Call the skeleton parser. |
501 `---------------------------*/
502
503 static void
504 output_skeleton (void)
505 {
506 FILE *in;
507 FILE *out;
508 int filter_fd[2];
509 char const *argv[6];
510 pid_t pid;
511
512 /* Compute the names of the package data dir and skeleton file.
513 Test whether m4sugar.m4 is readable, to check for proper
514 installation. A faulty installation can cause deadlock, so a
515 cheap sanity check is worthwhile. */
516 char const m4sugar[] = "m4sugar/m4sugar.m4";
517 char *full_m4sugar;
518 char *full_cm4;
519 char *full_skeleton;
520 char const *p;
521 char const *m4 = (p = getenv ("M4")) ? p : M4;
522 char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR;
523 size_t skeleton_size = strlen (skeleton) + 1;
524 size_t pkgdatadirlen = strlen (pkgdatadir);
525 while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
526 pkgdatadirlen--;
527 full_skeleton = xmalloc (pkgdatadirlen + 1
528 + (skeleton_size < sizeof m4sugar
529 ? sizeof m4sugar : skeleton_size));
530 strcpy (full_skeleton, pkgdatadir);
531 full_skeleton[pkgdatadirlen] = '/';
532 strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
533 full_m4sugar = xstrdup (full_skeleton);
534 strcpy (full_skeleton + pkgdatadirlen + 1, "c.m4");
535 full_cm4 = xstrdup (full_skeleton);
536 strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
537 xfclose (xfopen (full_m4sugar, "r"));
538
539 /* Create an m4 subprocess connected to us via two pipes. */
540
541 if (trace_flag & trace_tools)
542 fprintf (stderr, "running: %s %s - %s %s\n",
543 m4, full_m4sugar, full_cm4, full_skeleton);
544
545 argv[0] = m4;
546 argv[1] = full_m4sugar;
547 argv[2] = "-";
548 argv[3] = full_cm4;
549 argv[4] = full_skeleton;
550 argv[5] = NULL;
551
552 init_subpipe ();
553 pid = create_subpipe (argv, filter_fd);
554 free (full_m4sugar);
555 free (full_cm4);
556 free (full_skeleton);
557
558 out = fdopen (filter_fd[0], "w");
559 if (! out)
560 error (EXIT_FAILURE, get_errno (),
561 "fdopen");
562
563 /* Output the definitions of all the muscles. */
564 fputs ("m4_init()\n", out);
565
566 user_actions_output (out);
567 merger_output (out);
568 token_definitions_output (out);
569 symbol_destructors_output (out);
570 symbol_printers_output (out);
571
572 muscles_m4_output (out);
573
574 fputs ("m4_wrap([m4_divert_pop(0)])\n", out);
575 fputs ("m4_divert_push(0)dnl\n", out);
576 xfclose (out);
577
578 /* Read and process m4's output. */
579 timevar_push (TV_M4);
580 end_of_output_subpipe (pid, filter_fd);
581 in = fdopen (filter_fd[1], "r");
582 if (! in)
583 error (EXIT_FAILURE, get_errno (),
584 "fdopen");
585 scan_skel (in);
586 xfclose (in);
587 reap_subpipe (pid, m4);
588 timevar_pop (TV_M4);
589 }
590
591 static void
592 prepare (void)
593 {
594 /* Flags. */
595 MUSCLE_INSERT_BOOL ("debug", debug_flag);
596 MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
597 MUSCLE_INSERT_BOOL ("error_verbose", error_verbose);
598 MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
599 MUSCLE_INSERT_BOOL ("pure", pure_parser);
600 MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
601
602 /* File names. */
603 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
604 #define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "")
605 DEFINE (dir_prefix);
606 DEFINE (parser_file_name);
607 DEFINE (spec_defines_file);
608 DEFINE (spec_file_prefix);
609 DEFINE (spec_graph_file);
610 DEFINE (spec_name_prefix);
611 DEFINE (spec_outfile);
612 DEFINE (spec_verbose_file);
613 #undef DEFINE
614
615 /* User Code. */
616 obstack_1grow (&pre_prologue_obstack, 0);
617 obstack_1grow (&post_prologue_obstack, 0);
618 muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack));
619 muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack));
620
621 /* Find the right skeleton file. */
622 if (!skeleton)
623 {
624 if (glr_parser || nondeterministic_parser)
625 skeleton = "glr.c";
626 else
627 skeleton = "yacc.c";
628 }
629
630 /* About the skeletons. */
631 {
632 char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
633 MUSCLE_INSERT_STRING ("pkgdatadir", pkgdatadir ? pkgdatadir : PKGDATADIR);
634 MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
635 }
636 }
637
638
639 /*----------------------------------------------------------.
640 | Output the parsing tables and the parser code to ftable. |
641 `----------------------------------------------------------*/
642
643 void
644 output (void)
645 {
646 obstack_init (&format_obstack);
647
648 prepare_symbols ();
649 prepare_rules ();
650 prepare_states ();
651 prepare_actions ();
652
653 prepare ();
654
655 /* Process the selected skeleton file. */
656 output_skeleton ();
657
658 obstack_free (&format_obstack, NULL);
659 obstack_free (&pre_prologue_obstack, NULL);
660 obstack_free (&post_prologue_obstack, NULL);
661 }