]> git.saurik.com Git - bison.git/blob - src/output.c
705db814fccafdf6216065b8a9dc8c8db3d63a6b
[bison.git] / src / output.c
1 /* Output the generated parsing program for bison,
2 Copyright 1984, 1986, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of Bison, the GNU Compiler Compiler.
5
6 Bison is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 Bison is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21
22 /* The parser tables consist of these tables.
23 Starred ones needed only for the semantic parser.
24 Double starred are output only if switches are set.
25
26 yytranslate = vector mapping yylex's token numbers into bison's token
27 numbers.
28
29 ** yytname = vector of string-names indexed by bison token number
30
31 ** yytoknum = vector of yylex token numbers corresponding to entries
32 in yytname
33
34 yyrline = vector of line-numbers of all rules. For yydebug printouts.
35
36 yyrhs = vector of items of all rules.
37 This is exactly what ritems contains. For yydebug and for semantic
38 parser.
39
40 yyprhs[r] = index in yyrhs of first item for rule r.
41
42 yyr1[r] = symbol number of symbol that rule r derives.
43
44 yyr2[r] = number of symbols composing right hand side of rule r.
45
46 * yystos[s] = the symbol number of the symbol that leads to state s.
47
48 yydefact[s] = default rule to reduce with in state s,
49 when yytable doesn't specify something else to do.
50 Zero means the default is an error.
51
52 yydefgoto[i] = default state to go to after a reduction of a rule that
53 generates variable ntokens + i, except when yytable
54 specifies something else to do.
55
56 yypact[s] = index in yytable of the portion describing state s.
57 The lookahead token's type is used to index that portion
58 to find out what to do.
59
60 If the value in yytable is positive,
61 we shift the token and go to that state.
62
63 If the value is negative, it is minus a rule number to reduce by.
64
65 If the value is zero, the default action from yydefact[s] is used.
66
67 yypgoto[i] = the index in yytable of the portion describing
68 what to do after reducing a rule that derives variable i + ntokens.
69 This portion is indexed by the parser state number, s,
70 as of before the text for this nonterminal was read.
71 The value from yytable is the state to go to if
72 the corresponding value in yycheck is s.
73
74 yytable = a vector filled with portions for different uses,
75 found via yypact and yypgoto.
76
77 yycheck = a vector indexed in parallel with yytable.
78 It indicates, in a roundabout way, the bounds of the
79 portion you are trying to examine.
80
81 Suppose that the portion of yytable starts at index p
82 and the index to be examined within the portion is i.
83 Then if yycheck[p+i] != i, i is outside the bounds
84 of what is actually allocated, and the default
85 (from yydefact or yydefgoto) should be used.
86 Otherwise, yytable[p+i] should be used.
87
88 YYFINAL = the state number of the termination state.
89 YYFLAG = most negative short int. Used to flag ??
90 YYNTBASE = ntokens.
91 */
92
93 #include "system.h"
94 #include "quotearg.h"
95 #include "getargs.h"
96 #include "files.h"
97 #include "gram.h"
98 #include "LR0.h"
99 #include "complain.h"
100 #include "output.h"
101 #include "lalr.h"
102 #include "reader.h"
103 #include "conflicts.h"
104 #include "muscle_tab.h"
105
106
107 static int nvectors;
108 static int nentries;
109 static short **froms = NULL;
110 static short **tos = NULL;
111 static short *tally = NULL;
112 static short *width = NULL;
113 static short *actrow = NULL;
114 static short *state_count = NULL;
115 static short *order = NULL;
116 static short *base = NULL;
117 static short *pos = NULL;
118 static short *table = NULL;
119 static short *check = NULL;
120 static int lowzero;
121 static int high;
122
123 struct obstack muscle_obstack;
124 static struct obstack format_obstack;
125
126 int error_verbose = 0;
127
128 /* Returns the number of lines of S. */
129 static size_t
130 get_lines_number (const char *s)
131 {
132 size_t lines = 0;
133
134 size_t i;
135 for (i = 0; s[i]; ++i)
136 {
137 if (s[i] == '\n')
138 ++lines;
139 }
140
141 return lines;
142 }
143
144
145 /* FIXME. */
146
147 static inline void
148 output_table_data (struct obstack *oout,
149 short *table_data,
150 short first,
151 int begin,
152 int end)
153 {
154 int i;
155 int j = 1;
156
157 obstack_fgrow1 (oout, "%6d", first);
158 for (i = begin; i < end; ++i)
159 {
160 obstack_1grow (oout, ',');
161 if (j >= 10)
162 {
163 obstack_sgrow (oout, "\n ");
164 j = 1;
165 }
166 else
167 ++j;
168 obstack_fgrow1 (oout, "%6d", table_data[i]);
169 }
170 obstack_1grow (oout, 0);
171 }
172
173
174 static void
175 output_token_translations (void)
176 {
177 output_table_data (&format_obstack, token_translations,
178 0, 1, max_user_token_number + 1);
179 muscle_insert ("translate", obstack_finish (&format_obstack));
180 XFREE (token_translations);
181 }
182
183
184 static void
185 output_gram (void)
186 {
187 {
188 int i;
189 short *values = XCALLOC (short, nrules + 1);
190 for (i = 0; i < nrules + 1; ++i)
191 values[i] = rule_table[i].rhs;
192 output_table_data (&format_obstack, values,
193 0, 1, nrules + 1);
194 XFREE (values);
195 }
196
197 muscle_insert ("prhs", obstack_finish (&format_obstack));
198
199 {
200 size_t yyrhs_size = 1;
201 short *yyrhs, *sp;
202 int i;
203
204 for (sp = ritem + 1; *sp; sp++)
205 ++yyrhs_size;
206 yyrhs = XMALLOC (short, yyrhs_size);
207
208 for (sp = ritem + 1, i = 1; *sp; ++sp, ++i)
209 yyrhs[i] = *sp > 0 ? *sp : 0;
210
211 output_table_data (&format_obstack, yyrhs,
212 ritem[0], 1, yyrhs_size);
213 muscle_insert ("rhs", obstack_finish (&format_obstack));
214
215 XFREE (yyrhs);
216 }
217
218 #if 0
219 if (!semantic_parser)
220 obstack_sgrow (&table_obstack, "\n#endif\n");
221 #endif
222 }
223
224
225 static void
226 output_stos (void)
227 {
228 int i;
229 short *values = (short *) alloca (sizeof (short) * nstates);
230 for (i = 0; i < nstates; ++i)
231 values[i] = state_table[i]->accessing_symbol;
232 output_table_data (&format_obstack, values,
233 0, 1, nstates);
234 muscle_insert ("stos", obstack_finish (&format_obstack));
235 }
236
237
238 static void
239 output_rule_data (void)
240 {
241 int i;
242 int j;
243 short *short_tab = NULL;
244
245 {
246 short *values = XCALLOC (short, nrules + 1);
247 for (i = 0; i < nrules + 1; ++i)
248 values[i] = rule_table[i].line;
249 output_table_data (&format_obstack, values,
250 0, 1, nrules + 1);
251 muscle_insert ("rline", obstack_finish (&format_obstack));
252 XFREE (values);
253 }
254
255
256 j = 0;
257 for (i = 0; i < nsyms; i++)
258 {
259 /* Be sure not to use twice the same quotearg slot. */
260 const char *cp =
261 quotearg_n_style (1, c_quoting_style,
262 quotearg_style (escape_quoting_style, tags[i]));
263 /* Width of the next token, including the two quotes, the coma
264 and the space. */
265 int strsize = strlen (cp) + 2;
266
267 if (j + strsize > 75)
268 {
269 obstack_sgrow (&format_obstack, "\n ");
270 j = 2;
271 }
272
273 obstack_sgrow (&format_obstack, cp);
274 obstack_sgrow (&format_obstack, ", ");
275 j += strsize;
276 }
277 /* add a NULL entry to list of tokens */
278 obstack_sgrow (&format_obstack, "NULL");
279
280 /* Finish table and store. */
281 obstack_1grow (&format_obstack, 0);
282 muscle_insert ("tname", obstack_finish (&format_obstack));
283
284 /* Output YYTOKNUM. */
285 output_table_data (&format_obstack, user_toknums,
286 0, 1, ntokens + 1);
287 muscle_insert ("toknum", obstack_finish (&format_obstack));
288
289 /* Output YYR1. */
290 {
291 short *values = XCALLOC (short, nrules + 1);
292 for (i = 0; i < nrules + 1; ++i)
293 values[i] = rule_table[i].lhs;
294 output_table_data (&format_obstack, values,
295 0, 1, nrules + 1);
296 muscle_insert ("r1", obstack_finish (&format_obstack));
297 XFREE (values);
298 }
299
300 /* Output YYR2. */
301 short_tab = XMALLOC (short, nrules + 1);
302 for (i = 1; i < nrules; i++)
303 short_tab[i] = rule_table[i + 1].rhs - rule_table[i].rhs - 1;
304 short_tab[nrules] = nitems - rule_table[nrules].rhs - 1;
305 output_table_data (&format_obstack, short_tab,
306 0, 1, nrules + 1);
307 muscle_insert ("r2", obstack_finish (&format_obstack));
308 XFREE (short_tab);
309 }
310
311 /*------------------------------------------------------------------.
312 | Decide what to do for each type of token if seen as the lookahead |
313 | token in specified state. The value returned is used as the |
314 | default action (yydefact) for the state. In addition, actrow is |
315 | filled with what to do for each kind of token, index by symbol |
316 | number, with zero meaning do the default action. The value |
317 | MINSHORT, a very negative number, means this situation is an |
318 | error. The parser recognizes this value specially. |
319 | |
320 | This is where conflicts are resolved. The loop over lookahead |
321 | rules considered lower-numbered rules last, and the last rule |
322 | considered that likes a token gets to handle it. |
323 `------------------------------------------------------------------*/
324
325 static int
326 action_row (state_t *state)
327 {
328 int i;
329 int default_rule = 0;
330 reductions *redp = state->reductions;
331 int nreds = redp ? redp->nreds : 0;
332 shifts *shiftp = state->shifts;
333 errs *errp = state->errs;
334 /* set nonzero to inhibit having any default reduction */
335 int nodefault = 0;
336
337 for (i = 0; i < ntokens; i++)
338 actrow[i] = 0;
339
340 if (nreds >= 1)
341 {
342 int j;
343 /* loop over all the rules available here which require
344 lookahead */
345 for (i = state->nlookaheads - 1; i >= 0; --i)
346 /* and find each token which the rule finds acceptable
347 to come next */
348 for (j = 0; j < ntokens; j++)
349 /* and record this rule as the rule to use if that
350 token follows. */
351 if (BITISSET (LA (state->lookaheadsp + i), j))
352 actrow[j] = -LAruleno[state->lookaheadsp + i];
353 }
354
355 /* Now see which tokens are allowed for shifts in this state. For
356 them, record the shift as the thing to do. So shift is preferred
357 to reduce. */
358 for (i = 0; i < shiftp->nshifts; i++)
359 {
360 int symbol;
361 int shift_state = shiftp->shifts[i];
362 if (!shift_state)
363 continue;
364
365 symbol = state_table[shift_state]->accessing_symbol;
366
367 if (ISVAR (symbol))
368 break;
369
370 actrow[symbol] = shift_state;
371
372 /* Do not use any default reduction if there is a shift for
373 error */
374 if (symbol == error_token_number)
375 nodefault = 1;
376 }
377
378 /* See which tokens are an explicit error in this state (due to
379 %nonassoc). For them, record MINSHORT as the action. */
380 if (errp)
381 for (i = 0; i < errp->nerrs; i++)
382 {
383 int symbol = errp->errs[i];
384 actrow[symbol] = MINSHORT;
385 }
386
387 /* Now find the most common reduction and make it the default action
388 for this state. */
389
390 if (nreds >= 1 && !nodefault)
391 {
392 if (state->consistent)
393 default_rule = redp->rules[0];
394 else
395 {
396 int max = 0;
397 for (i = 0; i < state->nlookaheads; i++)
398 {
399 int count = 0;
400 int rule = -LAruleno[state->lookaheadsp + i];
401 int j;
402
403 for (j = 0; j < ntokens; j++)
404 if (actrow[j] == rule)
405 count++;
406
407 if (count > max)
408 {
409 max = count;
410 default_rule = rule;
411 }
412 }
413
414 /* actions which match the default are replaced with zero,
415 which means "use the default" */
416
417 if (max > 0)
418 {
419 int j;
420 for (j = 0; j < ntokens; j++)
421 if (actrow[j] == default_rule)
422 actrow[j] = 0;
423
424 default_rule = -default_rule;
425 }
426 }
427 }
428
429 /* If have no default rule, the default is an error.
430 So replace any action which says "error" with "use default". */
431
432 if (default_rule == 0)
433 for (i = 0; i < ntokens; i++)
434 if (actrow[i] == MINSHORT)
435 actrow[i] = 0;
436
437 return default_rule;
438 }
439
440
441 static void
442 save_row (int state)
443 {
444 int i;
445 int count;
446 short *sp;
447 short *sp1;
448 short *sp2;
449
450 count = 0;
451 for (i = 0; i < ntokens; i++)
452 if (actrow[i] != 0)
453 count++;
454
455 if (count == 0)
456 return;
457
458 froms[state] = sp1 = sp = XCALLOC (short, count);
459 tos[state] = sp2 = XCALLOC (short, count);
460
461 for (i = 0; i < ntokens; i++)
462 if (actrow[i] != 0)
463 {
464 *sp1++ = i;
465 *sp2++ = actrow[i];
466 }
467
468 tally[state] = count;
469 width[state] = sp1[-1] - sp[0] + 1;
470 }
471
472
473 /*------------------------------------------------------------------.
474 | Figure out the actions for the specified state, indexed by |
475 | lookahead token type. |
476 | |
477 | The YYDEFACT table is output now. The detailed info is saved for |
478 | putting into YYTABLE later. |
479 `------------------------------------------------------------------*/
480
481 static void
482 token_actions (void)
483 {
484 int i;
485 short *yydefact = XCALLOC (short, nstates);
486
487 actrow = XCALLOC (short, ntokens);
488 for (i = 0; i < nstates; ++i)
489 {
490 yydefact[i] = action_row (state_table[i]);
491 save_row (i);
492 }
493
494 output_table_data (&format_obstack, yydefact,
495 yydefact[0], 1, nstates);
496 muscle_insert ("defact", obstack_finish (&format_obstack));
497
498 XFREE (actrow);
499 XFREE (yydefact);
500 }
501
502
503 /*-----------------------------.
504 | Output the actions to OOUT. |
505 `-----------------------------*/
506
507 static void
508 actions_output (FILE *out, size_t *line)
509 {
510 int rule;
511 for (rule = 1; rule < nrules + 1; ++rule)
512 if (rule_table[rule].action)
513 {
514 fprintf (out, " case %d:\n", rule);
515
516 if (!no_lines_flag)
517 fprintf (out, muscle_find ("linef"),
518 rule_table[rule].action_line,
519 quotearg_style (c_quoting_style,
520 muscle_find ("filename")));
521 /* As a Bison extension, add the ending semicolon. Since some
522 Yacc don't do that, help people using bison as a Yacc
523 finding their missing semicolons. */
524 fprintf (out, "{ %s%s }\n break;\n\n",
525 rule_table[rule].action,
526 yacc_flag ? ";" : "");
527
528 /* We always output 4 '\n' per action. */
529 *line += 4;
530 /* Plus one if !no_lines_flag. */
531 if (!no_lines_flag)
532 ++*line;
533 /* Get the number of lines written by the user. */
534 *line += get_lines_number (rule_table[rule].action);
535 }
536 }
537
538
539 static void
540 save_column (int symbol, int default_state)
541 {
542 int i;
543 short *sp;
544 short *sp1;
545 short *sp2;
546 int count;
547 int symno = symbol - ntokens + nstates;
548
549 short begin = goto_map[symbol];
550 short end = goto_map[symbol + 1];
551
552 count = 0;
553 for (i = begin; i < end; i++)
554 if (to_state[i] != default_state)
555 count++;
556
557 if (count == 0)
558 return;
559
560 froms[symno] = sp1 = sp = XCALLOC (short, count);
561 tos[symno] = sp2 = XCALLOC (short, count);
562
563 for (i = begin; i < end; i++)
564 if (to_state[i] != default_state)
565 {
566 *sp1++ = from_state[i];
567 *sp2++ = to_state[i];
568 }
569
570 tally[symno] = count;
571 width[symno] = sp1[-1] - sp[0] + 1;
572 }
573
574 static int
575 default_goto (int symbol)
576 {
577 int i;
578 int m = goto_map[symbol];
579 int n = goto_map[symbol + 1];
580 int default_state = -1;
581 int max = 0;
582
583 if (m == n)
584 return -1;
585
586 for (i = 0; i < nstates; i++)
587 state_count[i] = 0;
588
589 for (i = m; i < n; i++)
590 state_count[to_state[i]]++;
591
592 for (i = 0; i < nstates; i++)
593 if (state_count[i] > max)
594 {
595 max = state_count[i];
596 default_state = i;
597 }
598
599 return default_state;
600 }
601
602
603 /*-------------------------------------------------------------------.
604 | Figure out what to do after reducing with each rule, depending on |
605 | the saved state from before the beginning of parsing the data that |
606 | matched this rule. |
607 | |
608 | The YYDEFGOTO table is output now. The detailed info is saved for |
609 | putting into YYTABLE later. |
610 `-------------------------------------------------------------------*/
611
612 static void
613 goto_actions (void)
614 {
615 int i;
616 short *yydefgoto = XMALLOC (short, nsyms - ntokens);
617
618 state_count = XCALLOC (short, nstates);
619 for (i = ntokens; i < nsyms; ++i)
620 {
621 int default_state = default_goto (i);
622 save_column (i, default_state);
623 yydefgoto[i - ntokens] = default_state;
624 }
625
626 output_table_data (&format_obstack, yydefgoto,
627 yydefgoto[0], 1, nsyms - ntokens);
628 muscle_insert ("defgoto", obstack_finish (&format_obstack));
629
630 XFREE (state_count);
631 XFREE (yydefgoto);
632 }
633
634
635 /* The next few functions decide how to pack the actions and gotos
636 information into yytable. */
637
638 static void
639 sort_actions (void)
640 {
641 int i;
642
643 order = XCALLOC (short, nvectors);
644 nentries = 0;
645
646 for (i = 0; i < nvectors; i++)
647 if (tally[i] > 0)
648 {
649 int k;
650 int t = tally[i];
651 int w = width[i];
652 int j = nentries - 1;
653
654 while (j >= 0 && (width[order[j]] < w))
655 j--;
656
657 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
658 j--;
659
660 for (k = nentries - 1; k > j; k--)
661 order[k + 1] = order[k];
662
663 order[j + 1] = i;
664 nentries++;
665 }
666 }
667
668
669 static int
670 matching_state (int vector)
671 {
672 int i = order[vector];
673 int t;
674 int w;
675 int prev;
676
677 if (i >= nstates)
678 return -1;
679
680 t = tally[i];
681 w = width[i];
682
683 for (prev = vector - 1; prev >= 0; prev--)
684 {
685 int j = order[prev];
686 int k;
687 int match = 1;
688
689 if (width[j] != w || tally[j] != t)
690 return -1;
691
692 for (k = 0; match && k < t; k++)
693 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
694 match = 0;
695
696 if (match)
697 return j;
698 }
699
700 return -1;
701 }
702
703
704 static int
705 pack_vector (int vector)
706 {
707 int i = order[vector];
708 int j;
709 int t = tally[i];
710 int loc = 0;
711 short *from = froms[i];
712 short *to = tos[i];
713
714 assert (t);
715
716 for (j = lowzero - from[0]; j < MAXTABLE; j++)
717 {
718 int k;
719 int ok = 1;
720
721 for (k = 0; ok && k < t; k++)
722 {
723 loc = j + from[k];
724 if (loc > MAXTABLE)
725 fatal (_("maximum table size (%d) exceeded"), MAXTABLE);
726
727 if (table[loc] != 0)
728 ok = 0;
729 }
730
731 for (k = 0; ok && k < vector; k++)
732 if (pos[k] == j)
733 ok = 0;
734
735 if (ok)
736 {
737 for (k = 0; k < t; k++)
738 {
739 loc = j + from[k];
740 table[loc] = to[k];
741 check[loc] = from[k];
742 }
743
744 while (table[lowzero] != 0)
745 lowzero++;
746
747 if (loc > high)
748 high = loc;
749
750 return j;
751 }
752 }
753 #define pack_vector_succeeded 0
754 assert (pack_vector_succeeded);
755 return 0;
756 }
757
758
759 static void
760 pack_table (void)
761 {
762 int i;
763 int place;
764 int state;
765
766 base = XCALLOC (short, nvectors);
767 pos = XCALLOC (short, nentries);
768 table = XCALLOC (short, MAXTABLE);
769 check = XCALLOC (short, MAXTABLE);
770
771 lowzero = 0;
772 high = 0;
773
774 for (i = 0; i < nvectors; i++)
775 base[i] = MINSHORT;
776
777 for (i = 0; i < MAXTABLE; i++)
778 check[i] = -1;
779
780 for (i = 0; i < nentries; i++)
781 {
782 state = matching_state (i);
783
784 if (state < 0)
785 place = pack_vector (i);
786 else
787 place = base[state];
788
789 pos[i] = place;
790 base[order[i]] = place;
791 }
792
793 for (i = 0; i < nvectors; i++)
794 {
795 XFREE (froms[i]);
796 XFREE (tos[i]);
797 }
798
799 XFREE (froms);
800 XFREE (tos);
801 XFREE (pos);
802 }
803
804 /* the following functions output yytable, yycheck
805 and the vectors whose elements index the portion starts */
806
807 static void
808 output_base (void)
809 {
810 /* Output pact. */
811 output_table_data (&format_obstack, base,
812 base[0], 1, nstates);
813 muscle_insert ("pact", obstack_finish (&format_obstack));
814
815 /* Output pgoto. */
816 output_table_data (&format_obstack, base,
817 base[nstates], nstates + 1, nvectors);
818 muscle_insert ("pgoto", obstack_finish (&format_obstack));
819
820 XFREE (base);
821 }
822
823
824 static void
825 output_table (void)
826 {
827 output_table_data (&format_obstack, table,
828 table[0], 1, high + 1);
829 muscle_insert ("table", obstack_finish (&format_obstack));
830 XFREE (table);
831 }
832
833
834 static void
835 output_check (void)
836 {
837 output_table_data (&format_obstack, check,
838 check[0], 1, high + 1);
839 muscle_insert ("check", obstack_finish (&format_obstack));
840 XFREE (check);
841 }
842
843 /* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
844 and yycheck. */
845
846 static void
847 output_actions (void)
848 {
849 int i;
850 nvectors = nstates + nvars;
851
852 froms = XCALLOC (short *, nvectors);
853 tos = XCALLOC (short *, nvectors);
854 tally = XCALLOC (short, nvectors);
855 width = XCALLOC (short, nvectors);
856
857 token_actions ();
858 XFREE (LA);
859 XFREE (LAruleno);
860
861 goto_actions ();
862 XFREE (goto_map + ntokens);
863 XFREE (from_state);
864 XFREE (to_state);
865
866 sort_actions ();
867 pack_table ();
868
869 output_base ();
870 output_table ();
871
872 output_check ();
873
874 for (i = 0; i < nstates; ++i)
875 {
876 XFREE (state_table[i]->shifts);
877 XFREE (state_table[i]->reductions);
878 XFREE (state_table[i]->errs);
879 free (state_table[i]);
880 }
881 XFREE (state_table);
882 }
883
884 \f
885 /*------------------------------------------------------------.
886 | Copy the parser code from SKEL_FILENAME into OOUT obstack. |
887 | and do the muscle substitution. |
888 `------------------------------------------------------------*/
889
890 static void
891 output_parser (const char *skel_filename, FILE *out)
892 {
893 int c;
894 FILE *fskel;
895 size_t output_line;
896 size_t skeleton_line;
897
898 fskel = xfopen (skel_filename, "r");
899
900 /* New output code. */
901 output_line = 1;
902 skeleton_line = 1;
903 c = getc (fskel);
904 while (c != EOF)
905 {
906 if (c != '%')
907 {
908 if (c == '\n')
909 {
910 ++output_line;
911 ++skeleton_line;
912 }
913 putc (c, out);
914 c = getc (fskel);
915 }
916 else if ((c = getc (fskel)) == '%')
917 {
918 /* Read the muscle. */
919 const char *muscle_key = 0;
920 const char *muscle_value = 0;
921
922 while (isalnum (c = getc (fskel)) || c == '-')
923 obstack_1grow (&muscle_obstack, c);
924 obstack_1grow (&muscle_obstack, 0);
925
926 /* Output the right value, or see if it's something special. */
927 muscle_key = obstack_finish (&muscle_obstack);
928 muscle_value = muscle_find (muscle_key);
929 if (!strcmp (muscle_key, "actions"))
930 actions_output (out, &output_line);
931 else if (!strcmp (muscle_key, "line"))
932 fprintf (out, "%d", output_line);
933 else if (!strcmp (muscle_key, "skeleton-line"))
934 fprintf (out, "%d", skeleton_line);
935 else if (muscle_value)
936 {
937 fputs (muscle_value, out);
938 output_line += get_lines_number (muscle_value);
939 }
940 else
941 {
942 fputs ("%%", out);
943 fputs (muscle_key, out);
944 }
945 }
946 else
947 putc ('%', out);
948 }
949
950 /* End. */
951 xfclose (fskel);
952 }
953
954 /*----------------------------------------.
955 | Prepare the master parser to be output |
956 `----------------------------------------*/
957
958 static void
959 output_master_parser (void)
960 {
961 FILE *parser = xfopen (parser_file_name, "w");
962 if (!skeleton)
963 {
964 if (semantic_parser)
965 skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
966 else
967 skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
968 }
969 muscle_insert ("skeleton", skeleton);
970 muscle_insert ("parser-file-name", parser_file_name);
971
972 output_parser (skeleton, parser);
973 xfclose (parser);
974 }
975
976
977 /* FIXME. */
978
979 #define MUSCLE_INSERT_INT(Key, Value) \
980 { \
981 obstack_fgrow1 (&muscle_obstack, "%d", Value); \
982 obstack_1grow (&muscle_obstack, 0); \
983 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
984 }
985
986 #define MUSCLE_INSERT_STRING(Key, Value) \
987 { \
988 obstack_sgrow (&muscle_obstack, Value); \
989 obstack_1grow (&muscle_obstack, 0); \
990 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
991 }
992
993 #define MUSCLE_INSERT_PREFIX(Key, Value) \
994 { \
995 obstack_fgrow2 (&muscle_obstack, "%s%s", spec_name_prefix, Value); \
996 obstack_1grow (&muscle_obstack, 0); \
997 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
998 }
999
1000 static void
1001 prepare (void)
1002 {
1003 MUSCLE_INSERT_INT ("last", high);
1004 MUSCLE_INSERT_INT ("flag", MINSHORT);
1005 MUSCLE_INSERT_INT ("pure", pure_parser);
1006 MUSCLE_INSERT_INT ("nsym", nsyms);
1007 MUSCLE_INSERT_INT ("debug", debug_flag);
1008 MUSCLE_INSERT_INT ("final", final_state);
1009 MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
1010 MUSCLE_INSERT_INT ("error-verbose", error_verbose);
1011 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
1012
1013 MUSCLE_INSERT_INT ("nnts", nvars);
1014 MUSCLE_INSERT_INT ("nrules", nrules);
1015 MUSCLE_INSERT_INT ("nstates", nstates);
1016 MUSCLE_INSERT_INT ("ntokens", ntokens);
1017
1018 MUSCLE_INSERT_INT ("locations-flag", locations_flag);
1019 }
1020
1021
1022 /*-------------------------.
1023 | Output the header file. |
1024 `-------------------------*/
1025
1026 static void
1027 header_output (void)
1028 {
1029 FILE *out = xfopen (spec_defines_file, "w");
1030 char *macro_name = compute_header_macro ();
1031
1032 fprintf (out, "#ifndef %s\n", macro_name);
1033 fprintf (out, "# define %s\n\n", macro_name);
1034
1035 fputs (muscle_find ("tokendef"), out);
1036 fprintf (out, "\
1037 #ifndef YYSTYPE\n\
1038 typedef %s
1039 yystype;\n\
1040 # define YYSTYPE yystype\n\
1041 #endif\n",
1042 muscle_find ("stype"));
1043
1044 if (!pure_parser)
1045 fprintf (out, "\nextern YYSTYPE %slval;\n",
1046 spec_name_prefix);
1047 if (semantic_parser)
1048 {
1049 int i;
1050
1051 for (i = ntokens; i < nsyms; i++)
1052 /* don't make these for dummy nonterminals made by gensym. */
1053 if (*tags[i] != '@')
1054 fprintf (out, "# define NT%s\t%d\n", tags[i], i);
1055 }
1056
1057 fprintf (out, "\n#endif /* not %s */\n", macro_name);
1058 free (macro_name);
1059 xfclose (out);
1060 }
1061
1062
1063 /*----------------------------------------------------------.
1064 | Output the parsing tables and the parser code to ftable. |
1065 `----------------------------------------------------------*/
1066
1067 void
1068 output (void)
1069 {
1070 obstack_init (&format_obstack);
1071
1072 output_token_translations ();
1073 output_gram ();
1074
1075 XFREE (ritem);
1076 if (semantic_parser)
1077 output_stos ();
1078 output_rule_data ();
1079 XFREE (user_toknums);
1080 output_actions ();
1081
1082 prepare ();
1083 /* Copy definitions in directive. */
1084 obstack_1grow (&attrs_obstack, 0);
1085 muscle_insert ("prologue", obstack_finish (&attrs_obstack));
1086
1087 /* Output the parser. */
1088 output_master_parser ();
1089 /* Output the header if needed. */
1090 if (defines_flag)
1091 header_output ();
1092
1093 free (rule_table + 1);
1094 obstack_free (&muscle_obstack, 0);
1095 obstack_free (&format_obstack, 0);
1096 obstack_free (&action_obstack, 0);
1097 }