]> git.saurik.com Git - bison.git/blob - src/output.c
34560bb5eeced167215f719e16833a72b612cbbe
[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 struct obstack output_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 short begin,
152 short 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 (&output_obstack, token_translations,
178 0, 1, max_user_token_number + 1);
179 muscle_insert ("translate", obstack_finish (&output_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 (&output_obstack, values,
193 0, 1, nrules + 1);
194 XFREE (values);
195 }
196
197 muscle_insert ("prhs", obstack_finish (&output_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 (&output_obstack, yyrhs,
212 ritem[0], 1, yyrhs_size);
213 muscle_insert ("rhs", obstack_finish (&output_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 (&output_obstack, values,
233 0, 1, nstates);
234 muscle_insert ("stos", obstack_finish (&output_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 (&output_obstack, values,
250 0, 1, nrules + 1);
251 muscle_insert ("rline", obstack_finish (&output_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 (&output_obstack, "\n ");
270 j = 2;
271 }
272
273 obstack_sgrow (&output_obstack, cp);
274 obstack_sgrow (&output_obstack, ", ");
275 j += strsize;
276 }
277 /* add a NULL entry to list of tokens */
278 obstack_sgrow (&output_obstack, "NULL");
279
280 /* Finish table and store. */
281 obstack_1grow (&output_obstack, 0);
282 muscle_insert ("tname", obstack_finish (&output_obstack));
283
284 /* Output YYTOKNUM. */
285 output_table_data (&output_obstack, user_toknums,
286 0, 1, ntokens + 1);
287 muscle_insert ("toknum", obstack_finish (&output_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 (&output_obstack, values,
295 0, 1, nrules + 1);
296 muscle_insert ("r1", obstack_finish (&output_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 (&output_obstack, short_tab,
306 0, 1, nrules + 1);
307 muscle_insert ("r2", obstack_finish (&output_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 (int state)
327 {
328 int i;
329 int j;
330 int m = 0;
331 int n = 0;
332 int default_rule;
333 int nreds;
334 int rule;
335 int shift_state;
336 int symbol;
337 reductions *redp;
338 shifts *shiftp;
339 errs *errp;
340 int nodefault = 0; /* set nonzero to inhibit having any default reduction */
341
342 for (i = 0; i < ntokens; i++)
343 actrow[i] = 0;
344
345 default_rule = 0;
346 nreds = 0;
347 redp = state_table[state]->reductions;
348
349 if (redp)
350 {
351 nreds = redp->nreds;
352
353 if (nreds >= 1)
354 {
355 /* loop over all the rules available here which require
356 lookahead */
357 m = state_table[state]->lookaheads;
358 n = state_table[state + 1]->lookaheads;
359
360 for (i = n - 1; i >= m; i--)
361 /* and find each token which the rule finds acceptable
362 to come next */
363 for (j = 0; j < ntokens; j++)
364 /* and record this rule as the rule to use if that
365 token follows. */
366 if (BITISSET (LA (i), j))
367 actrow[j] = -LAruleno[i];
368 }
369 }
370
371 /* Now see which tokens are allowed for shifts in this state. For
372 them, record the shift as the thing to do. So shift is preferred
373 to reduce. */
374 shiftp = state_table[state]->shifts;
375 for (i = 0; i < shiftp->nshifts; i++)
376 {
377 shift_state = shiftp->shifts[i];
378 if (!shift_state)
379 continue;
380
381 symbol = state_table[shift_state]->accessing_symbol;
382
383 if (ISVAR (symbol))
384 break;
385
386 actrow[symbol] = shift_state;
387
388 /* Do not use any default reduction if there is a shift for
389 error */
390 if (symbol == error_token_number)
391 nodefault = 1;
392 }
393
394 /* See which tokens are an explicit error in this state (due to
395 %nonassoc). For them, record MINSHORT as the action. */
396 errp = state_table[state]->errs;
397
398 if (errp)
399 for (i = 0; i < errp->nerrs; i++)
400 {
401 symbol = errp->errs[i];
402 actrow[symbol] = MINSHORT;
403 }
404
405 /* Now find the most common reduction and make it the default action
406 for this state. */
407
408 if (nreds >= 1 && !nodefault)
409 {
410 if (state_table[state]->consistent)
411 default_rule = redp->rules[0];
412 else
413 {
414 int max = 0;
415 for (i = m; i < n; i++)
416 {
417 int count = 0;
418 rule = -LAruleno[i];
419
420 for (j = 0; j < ntokens; j++)
421 {
422 if (actrow[j] == rule)
423 count++;
424 }
425
426 if (count > max)
427 {
428 max = count;
429 default_rule = rule;
430 }
431 }
432
433 /* actions which match the default are replaced with zero,
434 which means "use the default" */
435
436 if (max > 0)
437 {
438 for (j = 0; j < ntokens; j++)
439 {
440 if (actrow[j] == default_rule)
441 actrow[j] = 0;
442 }
443
444 default_rule = -default_rule;
445 }
446 }
447 }
448
449 /* If have no default rule, the default is an error.
450 So replace any action which says "error" with "use default". */
451
452 if (default_rule == 0)
453 for (j = 0; j < ntokens; j++)
454 {
455 if (actrow[j] == MINSHORT)
456 actrow[j] = 0;
457 }
458
459 return default_rule;
460 }
461
462
463 static void
464 save_row (int state)
465 {
466 int i;
467 int count;
468 short *sp;
469 short *sp1;
470 short *sp2;
471
472 count = 0;
473 for (i = 0; i < ntokens; i++)
474 if (actrow[i] != 0)
475 count++;
476
477 if (count == 0)
478 return;
479
480 froms[state] = sp1 = sp = XCALLOC (short, count);
481 tos[state] = sp2 = XCALLOC (short, count);
482
483 for (i = 0; i < ntokens; i++)
484 if (actrow[i] != 0)
485 {
486 *sp1++ = i;
487 *sp2++ = actrow[i];
488 }
489
490 tally[state] = count;
491 width[state] = sp1[-1] - sp[0] + 1;
492 }
493
494
495 /*------------------------------------------------------------------.
496 | Figure out the actions for the specified state, indexed by |
497 | lookahead token type. |
498 | |
499 | The YYDEFACT table is output now. The detailed info is saved for |
500 | putting into YYTABLE later. |
501 `------------------------------------------------------------------*/
502
503 static void
504 token_actions (void)
505 {
506 int i;
507 short *yydefact = XCALLOC (short, nstates);
508
509 actrow = XCALLOC (short, ntokens);
510 for (i = 0; i < nstates; ++i)
511 {
512 yydefact[i] = action_row (i);
513 save_row (i);
514 }
515
516 output_table_data (&output_obstack, yydefact,
517 yydefact[0], 1, nstates);
518 muscle_insert ("defact", obstack_finish (&output_obstack));
519
520 XFREE (actrow);
521 XFREE (yydefact);
522 }
523
524
525 /*-----------------------------.
526 | Output the actions to OOUT. |
527 `-----------------------------*/
528
529 static void
530 actions_output (FILE *out, size_t *line)
531 {
532 int rule;
533 for (rule = 1; rule < nrules + 1; ++rule)
534 if (rule_table[rule].action)
535 {
536 fprintf (out, " case %d:\n", rule);
537
538 if (!no_lines_flag)
539 fprintf (out, muscle_find ("linef"),
540 rule_table[rule].action_line,
541 quotearg_style (c_quoting_style,
542 muscle_find ("filename")));
543 /* As a Bison extension, add the ending semicolon. Since some
544 Yacc don't do that, help people using bison as a Yacc
545 finding their missing semicolons. */
546 fprintf (out, "{ %s%s }\n break;\n\n",
547 rule_table[rule].action,
548 yacc_flag ? ";" : "");
549
550 /* We always output 4 '\n' per action. */
551 *line += 4;
552 /* Plus one if !no_lines_flag. */
553 if (!no_lines_flag)
554 ++*line;
555 /* Get the number of lines written by the user. */
556 *line += get_lines_number (rule_table[rule].action);
557 }
558 }
559
560
561 static void
562 save_column (int symbol, int default_state)
563 {
564 int i;
565 short *sp;
566 short *sp1;
567 short *sp2;
568 int count;
569 int symno;
570
571 short begin = goto_map[symbol];
572 short end = goto_map[symbol + 1];
573
574 count = 0;
575 for (i = begin; i < end; i++)
576 if (to_state[i] != default_state)
577 count++;
578
579 if (count == 0)
580 return;
581
582 symno = symbol - ntokens + nstates;
583
584 froms[symno] = sp1 = sp = XCALLOC (short, count);
585 tos[symno] = sp2 = XCALLOC (short, count);
586
587 for (i = begin; i < end; i++)
588 if (to_state[i] != default_state)
589 {
590 *sp1++ = from_state[i];
591 *sp2++ = to_state[i];
592 }
593
594 tally[symno] = count;
595 width[symno] = sp1[-1] - sp[0] + 1;
596 }
597
598 static int
599 default_goto (int symbol)
600 {
601 int i;
602 int m;
603 int n;
604 int default_state;
605 int max;
606
607 m = goto_map[symbol];
608 n = goto_map[symbol + 1];
609
610 if (m == n)
611 return -1;
612
613 for (i = 0; i < nstates; i++)
614 state_count[i] = 0;
615
616 for (i = m; i < n; i++)
617 state_count[to_state[i]]++;
618
619 max = 0;
620 default_state = -1;
621
622 for (i = 0; i < nstates; i++)
623 if (state_count[i] > max)
624 {
625 max = state_count[i];
626 default_state = i;
627 }
628
629 return default_state;
630 }
631
632
633 /*-------------------------------------------------------------------.
634 | Figure out what to do after reducing with each rule, depending on |
635 | the saved state from before the beginning of parsing the data that |
636 | matched this rule. |
637 | |
638 | The YYDEFGOTO table is output now. The detailed info is saved for |
639 | putting into YYTABLE later. |
640 `-------------------------------------------------------------------*/
641
642 static void
643 goto_actions (void)
644 {
645 int i;
646 short *yydefgoto = XMALLOC (short, nsyms - ntokens);
647
648 state_count = XCALLOC (short, nstates);
649 for (i = ntokens; i < nsyms; ++i)
650 {
651 int default_state = default_goto (i);
652 save_column (i, default_state);
653 yydefgoto[i - ntokens] = default_state;
654 }
655
656 output_table_data (&output_obstack, yydefgoto,
657 yydefgoto[0], 1, nsyms - ntokens);
658 muscle_insert ("defgoto", obstack_finish (&output_obstack));
659
660 XFREE (state_count);
661 XFREE (yydefgoto);
662 }
663
664
665 /* The next few functions decide how to pack the actions and gotos
666 information into yytable. */
667
668 static void
669 sort_actions (void)
670 {
671 int i;
672 int j;
673 int k;
674 int t;
675 int w;
676
677 order = XCALLOC (short, nvectors);
678 nentries = 0;
679
680 for (i = 0; i < nvectors; i++)
681 if (tally[i] > 0)
682 {
683 t = tally[i];
684 w = width[i];
685 j = nentries - 1;
686
687 while (j >= 0 && (width[order[j]] < w))
688 j--;
689
690 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
691 j--;
692
693 for (k = nentries - 1; k > j; k--)
694 order[k + 1] = order[k];
695
696 order[j + 1] = i;
697 nentries++;
698 }
699 }
700
701
702 static int
703 matching_state (int vector)
704 {
705 int i;
706 int j;
707 int k;
708 int t;
709 int w;
710 int match;
711 int prev;
712
713 i = order[vector];
714 if (i >= nstates)
715 return -1;
716
717 t = tally[i];
718 w = width[i];
719
720 for (prev = vector - 1; prev >= 0; prev--)
721 {
722 j = order[prev];
723 if (width[j] != w || tally[j] != t)
724 return -1;
725
726 match = 1;
727 for (k = 0; match && k < t; k++)
728 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
729 match = 0;
730
731 if (match)
732 return j;
733 }
734
735 return -1;
736 }
737
738
739 static int
740 pack_vector (int vector)
741 {
742 int i;
743 int j;
744 int k;
745 int t;
746 int loc = 0;
747 int ok;
748 short *from;
749 short *to;
750
751 i = order[vector];
752 t = tally[i];
753
754 assert (t);
755
756 from = froms[i];
757 to = tos[i];
758
759 for (j = lowzero - from[0]; j < MAXTABLE; j++)
760 {
761 ok = 1;
762
763 for (k = 0; ok && k < t; k++)
764 {
765 loc = j + from[k];
766 if (loc > MAXTABLE)
767 fatal (_("maximum table size (%d) exceeded"), MAXTABLE);
768
769 if (table[loc] != 0)
770 ok = 0;
771 }
772
773 for (k = 0; ok && k < vector; k++)
774 if (pos[k] == j)
775 ok = 0;
776
777 if (ok)
778 {
779 for (k = 0; k < t; k++)
780 {
781 loc = j + from[k];
782 table[loc] = to[k];
783 check[loc] = from[k];
784 }
785
786 while (table[lowzero] != 0)
787 lowzero++;
788
789 if (loc > high)
790 high = loc;
791
792 return j;
793 }
794 }
795
796 assert (!"pack_vector");
797 return 0;
798 }
799
800
801 static void
802 pack_table (void)
803 {
804 int i;
805 int place;
806 int state;
807
808 base = XCALLOC (short, nvectors);
809 pos = XCALLOC (short, nentries);
810 table = XCALLOC (short, MAXTABLE);
811 check = XCALLOC (short, MAXTABLE);
812
813 lowzero = 0;
814 high = 0;
815
816 for (i = 0; i < nvectors; i++)
817 base[i] = MINSHORT;
818
819 for (i = 0; i < MAXTABLE; i++)
820 check[i] = -1;
821
822 for (i = 0; i < nentries; i++)
823 {
824 state = matching_state (i);
825
826 if (state < 0)
827 place = pack_vector (i);
828 else
829 place = base[state];
830
831 pos[i] = place;
832 base[order[i]] = place;
833 }
834
835 for (i = 0; i < nvectors; i++)
836 {
837 XFREE (froms[i]);
838 XFREE (tos[i]);
839 }
840
841 XFREE (froms);
842 XFREE (tos);
843 XFREE (pos);
844 }
845
846 /* the following functions output yytable, yycheck
847 and the vectors whose elements index the portion starts */
848
849 static void
850 output_base (void)
851 {
852 /* Output pact. */
853 output_table_data (&output_obstack, base,
854 base[0], 1, nstates);
855 muscle_insert ("pact", obstack_finish (&output_obstack));
856
857 /* Output pgoto. */
858 output_table_data (&output_obstack, base,
859 base[nstates], nstates + 1, nvectors);
860 muscle_insert ("pgoto", obstack_finish (&output_obstack));
861
862 XFREE (base);
863 }
864
865
866 static void
867 output_table (void)
868 {
869 output_table_data (&output_obstack, table,
870 table[0], 1, high + 1);
871 muscle_insert ("table", obstack_finish (&output_obstack));
872 XFREE (table);
873 }
874
875
876 static void
877 output_check (void)
878 {
879 output_table_data (&output_obstack, check,
880 check[0], 1, high + 1);
881 muscle_insert ("check", obstack_finish (&output_obstack));
882 XFREE (check);
883 }
884
885 /* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
886 and yycheck. */
887
888 static void
889 output_actions (void)
890 {
891 int i;
892 nvectors = nstates + nvars;
893
894 froms = XCALLOC (short *, nvectors);
895 tos = XCALLOC (short *, nvectors);
896 tally = XCALLOC (short, nvectors);
897 width = XCALLOC (short, nvectors);
898
899 token_actions ();
900 XFREE (LA);
901 XFREE (LAruleno);
902
903 goto_actions ();
904 XFREE (goto_map + ntokens);
905 XFREE (from_state);
906 XFREE (to_state);
907
908 sort_actions ();
909 pack_table ();
910
911 output_base ();
912 output_table ();
913
914 output_check ();
915
916 for (i = 0; i < nstates; ++i)
917 {
918 XFREE (state_table[i]->shifts);
919 XFREE (state_table[i]->reductions);
920 XFREE (state_table[i]->errs);
921 free (state_table[i]);
922 }
923 XFREE (state_table);
924 }
925
926 \f
927 /*------------------------------------------------------------.
928 | Copy the parser code from SKEL_FILENAME into OOUT obstack. |
929 | and do the muscle substitution. |
930 `------------------------------------------------------------*/
931
932 static void
933 output_parser (const char *skel_filename, FILE *out)
934 {
935 int c;
936 FILE *fskel;
937 size_t line;
938
939 fskel = xfopen (skel_filename, "r");
940
941 /* New output code. */
942 line = 1;
943 c = getc (fskel);
944 while (c != EOF)
945 {
946 if (c != '%')
947 {
948 if (c == '\n')
949 ++line;
950 putc (c, out);
951 c = getc (fskel);
952 }
953 else if ((c = getc (fskel)) == '%')
954 {
955 /* Read the muscle. */
956 const char *muscle_key = 0;
957 const char *muscle_value = 0;
958
959 while (isalnum (c = getc (fskel)) || c == '-')
960 obstack_1grow (&muscle_obstack, c);
961 obstack_1grow (&muscle_obstack, 0);
962
963 /* Output the right value, or see if it's something special. */
964 muscle_key = obstack_finish (&muscle_obstack);
965 muscle_value = muscle_find (muscle_key);
966 if (!strcmp (muscle_key, "actions"))
967 actions_output (out, &line);
968 else if (!strcmp (muscle_key, "line"))
969 fprintf (out, "%d", line);
970 else if (muscle_value)
971 {
972 fputs (muscle_value, out);
973 line += get_lines_number (muscle_value);
974 }
975 else
976 {
977 fputs ("%%", out);
978 fputs (muscle_key, out);
979 }
980 }
981 else
982 putc ('%', out);
983 }
984
985 /* End. */
986 xfclose (fskel);
987 }
988
989 /*----------------------------------------.
990 | Prepare the master parser to be output |
991 `----------------------------------------*/
992
993 static void
994 output_master_parser (void)
995 {
996 FILE *parser = xfopen (parser_file_name, "w");
997 if (!skeleton)
998 {
999 if (semantic_parser)
1000 skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
1001 else
1002 skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
1003 }
1004 muscle_insert ("skeleton", skeleton);
1005 muscle_insert ("parser-file-name", parser_file_name);
1006
1007 output_parser (skeleton, parser);
1008 xfclose (parser);
1009 }
1010
1011
1012 /* FIXME. */
1013
1014 #define MUSCLE_INSERT_INT(Key, Value) \
1015 { \
1016 obstack_fgrow1 (&muscle_obstack, "%d", Value); \
1017 obstack_1grow (&muscle_obstack, 0); \
1018 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1019 }
1020
1021 #define MUSCLE_INSERT_STRING(Key, Value) \
1022 { \
1023 obstack_sgrow (&muscle_obstack, Value); \
1024 obstack_1grow (&muscle_obstack, 0); \
1025 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1026 }
1027
1028 #define MUSCLE_INSERT_PREFIX(Key, Value) \
1029 { \
1030 obstack_fgrow2 (&muscle_obstack, "%s%s", spec_name_prefix, Value); \
1031 obstack_1grow (&muscle_obstack, 0); \
1032 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1033 }
1034
1035 static void
1036 prepare (void)
1037 {
1038 MUSCLE_INSERT_INT ("last", high);
1039 MUSCLE_INSERT_INT ("flag", MINSHORT);
1040 MUSCLE_INSERT_INT ("pure", pure_parser);
1041 MUSCLE_INSERT_INT ("nsym", nsyms);
1042 MUSCLE_INSERT_INT ("debug", debug_flag);
1043 MUSCLE_INSERT_INT ("final", final_state);
1044 MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
1045 MUSCLE_INSERT_INT ("ntbase", ntokens);
1046 MUSCLE_INSERT_INT ("error-verbose", error_verbose);
1047 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
1048
1049 MUSCLE_INSERT_INT ("nnts", nvars);
1050 MUSCLE_INSERT_INT ("nrules", nrules);
1051 MUSCLE_INSERT_INT ("nstates", nstates);
1052 MUSCLE_INSERT_INT ("ntokens", ntokens);
1053
1054 MUSCLE_INSERT_INT ("locations-flag", locations_flag);
1055 }
1056
1057
1058 /*-------------------------.
1059 | Output the header file. |
1060 `-------------------------*/
1061
1062 static void
1063 header_output (void)
1064 {
1065 FILE *out = xfopen (spec_defines_file, "w");
1066 char *macro_name = compute_header_macro ();
1067
1068 fprintf (out, "#ifndef %s\n", macro_name);
1069 fprintf (out, "# define %s\n\n", macro_name);
1070
1071 fputs (muscle_find ("tokendef"), out);
1072 fprintf (out, "\
1073 #ifndef YYSTYPE\n\
1074 typedef %s
1075 yystype;\n\
1076 # define YYSTYPE yystype\n\
1077 #endif\n",
1078 muscle_find ("stype"));
1079
1080 if (!pure_parser)
1081 fprintf (out, "\nextern YYSTYPE %slval;\n",
1082 spec_name_prefix);
1083 if (semantic_parser)
1084 {
1085 int i;
1086
1087 for (i = ntokens; i < nsyms; i++)
1088 /* don't make these for dummy nonterminals made by gensym. */
1089 if (*tags[i] != '@')
1090 fprintf (out, "# define\tNT%s\t%d\n", tags[i], i);
1091 }
1092
1093 fprintf (out, "\n#endif /* not %s */\n", macro_name);
1094 free (macro_name);
1095 xfclose (out);
1096 }
1097
1098
1099 /*----------------------------------------------------------.
1100 | Output the parsing tables and the parser code to ftable. |
1101 `----------------------------------------------------------*/
1102
1103 void
1104 output (void)
1105 {
1106 obstack_init (&output_obstack);
1107
1108 output_token_translations ();
1109 output_gram ();
1110
1111 XFREE (ritem);
1112 if (semantic_parser)
1113 output_stos ();
1114 output_rule_data ();
1115 XFREE (user_toknums);
1116 output_actions ();
1117
1118 prepare ();
1119 /* Copy definitions in directive. */
1120 obstack_1grow (&attrs_obstack, 0);
1121 muscle_insert ("prologue", obstack_finish (&attrs_obstack));
1122
1123 /* Output the parser. */
1124 output_master_parser ();
1125 /* Output the header if needed. */
1126 if (defines_flag)
1127 header_output ();
1128
1129 free (rule_table + 1);
1130 obstack_free (&muscle_obstack, 0);
1131 obstack_free (&output_obstack, 0);
1132 obstack_free (&action_obstack, 0);
1133 }