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