]> git.saurik.com Git - bison.git/blob - src/output.c
dabcba1592f563bdc8196e48c57b30732d30c778
[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 "obstack.h"
95 #include "quotearg.h"
96 #include "getargs.h"
97 #include "files.h"
98 #include "gram.h"
99 #include "LR0.h"
100 #include "complain.h"
101 #include "output.h"
102 #include "lalr.h"
103 #include "reader.h"
104 #include "conflicts.h"
105 #include "muscle_tab.h"
106
107 extern void berror PARAMS((const char *));
108
109 static int nvectors;
110 static int nentries;
111 static short **froms = NULL;
112 static short **tos = NULL;
113 static short *tally = NULL;
114 static short *width = NULL;
115 static short *actrow = NULL;
116 static short *state_count = NULL;
117 static short *order = NULL;
118 static short *base = NULL;
119 static short *pos = NULL;
120 static short *table = NULL;
121 static short *check = NULL;
122 static int lowzero;
123 static int high;
124
125 struct obstack muscle_obstack;
126 struct obstack output_obstack;
127
128 /* FIXME. */
129
130 static inline void
131 output_table_data (struct obstack *oout,
132 short *table_data,
133 short first,
134 short begin,
135 short end)
136 {
137 int i;
138 int j = 1;
139
140 obstack_fgrow1 (oout, "%6d", first);
141 for (i = begin; i < end; ++i)
142 {
143 obstack_1grow (oout, ',');
144 if (j >= 10)
145 {
146 obstack_sgrow (oout, "\n ");
147 j = 1;
148 }
149 else
150 ++j;
151 obstack_fgrow1 (oout, "%6d", table_data[i]);
152 }
153 obstack_1grow (oout, 0);
154 }
155
156
157 static void
158 output_token_translations (void)
159 {
160 output_table_data (&output_obstack, token_translations,
161 0, 1, max_user_token_number + 1);
162 muscle_insert ("translate", obstack_finish (&output_obstack));
163 XFREE (token_translations);
164 }
165
166
167 static void
168 output_gram (void)
169 {
170 {
171 int i;
172 short *values = XCALLOC (short, nrules + 1);
173 for (i = 0; i < nrules + 1; ++i)
174 values[i] = rule_table[i].rhs;
175 output_table_data (&output_obstack, values,
176 0, 1, nrules + 1);
177 XFREE (values);
178 }
179
180 muscle_insert ("prhs", obstack_finish (&output_obstack));
181
182 {
183 size_t yyrhs_size = 1;
184 short *yyrhs, *sp;
185 int i;
186
187 for (sp = ritem + 1; *sp; sp++)
188 ++yyrhs_size;
189 yyrhs = XMALLOC (short, yyrhs_size);
190
191 for (sp = ritem + 1, i = 1; *sp; ++sp, ++i)
192 yyrhs[i] = *sp > 0 ? *sp : 0;
193
194 output_table_data (&output_obstack, yyrhs,
195 ritem[0], 1, yyrhs_size);
196 muscle_insert ("rhs", obstack_finish (&output_obstack));
197
198 XFREE (yyrhs);
199 }
200
201 #if 0
202 if (!semantic_parser && !no_parser_flag)
203 obstack_sgrow (&table_obstack, "\n#endif\n");
204 #endif
205 }
206
207
208 static void
209 output_stos (void)
210 {
211 int i;
212 short *values = (short *) alloca (sizeof (short) * nstates);
213 for (i = 0; i < nstates; ++i)
214 values[i] = state_table[i].accessing_symbol;
215 output_table_data (&output_obstack, values,
216 0, 1, nstates);
217 muscle_insert ("stos", obstack_finish (&output_obstack));
218 }
219
220
221 static void
222 output_rule_data (void)
223 {
224 int i;
225 int j;
226 short *short_tab = NULL;
227
228 output_table_data (&output_obstack, rline,
229 0, 1, nrules + 1);
230 muscle_insert ("rline", obstack_finish (&output_obstack));
231
232 j = 0;
233 for (i = 0; i < nsyms; i++)
234 /* this used to be i<=nsyms, but that output a final "" symbol
235 almost by accident */
236 {
237 /* Width of the next token, including the two quotes, the coma
238 and the space. */
239 int strsize = 4;
240 char *p;
241
242 for (p = tags[i]; p && *p; p++)
243 if (*p == '"' || *p == '\\' || *p == '\n' || *p == '\t'
244 || *p == '\b')
245 strsize += 2;
246 else if (*p < 040 || *p >= 0177)
247 strsize += 4;
248 else
249 strsize++;
250
251 if (j + strsize > 75)
252 {
253 obstack_sgrow (&output_obstack, "\n ");
254 j = 2;
255 }
256
257 obstack_1grow (&output_obstack, '\"');
258 for (p = tags[i]; p && *p; p++)
259 {
260 if (*p == '"' || *p == '\\')
261 obstack_fgrow1 (&output_obstack, "\\%c", *p);
262 else if (*p == '\n')
263 obstack_sgrow (&output_obstack, "\\n");
264 else if (*p == '\t')
265 obstack_sgrow (&output_obstack, "\\t");
266 else if (*p == '\b')
267 obstack_sgrow (&output_obstack, "\\b");
268 else if (*p < 040 || *p >= 0177)
269 obstack_fgrow1 (&output_obstack, "\\%03o", *p);
270 else
271 obstack_1grow (&output_obstack, *p);
272 }
273
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 XFREE (rule_table + 1);
311 }
312
313 /*------------------------------------------------------------------.
314 | Decide what to do for each type of token if seen as the lookahead |
315 | token in specified state. The value returned is used as the |
316 | default action (yydefact) for the state. In addition, actrow is |
317 | filled with what to do for each kind of token, index by symbol |
318 | number, with zero meaning do the default action. The value |
319 | MINSHORT, a very negative number, means this situation is an |
320 | error. The parser recognizes this value specially. |
321 | |
322 | This is where conflicts are resolved. The loop over lookahead |
323 | rules considered lower-numbered rules last, and the last rule |
324 | considered that likes a token gets to handle it. |
325 `------------------------------------------------------------------*/
326
327 static int
328 action_row (int state)
329 {
330 int i;
331 int j;
332 int k;
333 int m = 0;
334 int n = 0;
335 int count;
336 int default_rule;
337 int nreds;
338 int max;
339 int rule;
340 int shift_state;
341 int symbol;
342 unsigned mask;
343 unsigned *wordp;
344 reductions *redp;
345 shifts *shiftp;
346 errs *errp;
347 int nodefault = 0; /* set nonzero to inhibit having any default reduction */
348
349 for (i = 0; i < ntokens; i++)
350 actrow[i] = 0;
351
352 default_rule = 0;
353 nreds = 0;
354 redp = state_table[state].reduction_table;
355
356 if (redp)
357 {
358 nreds = redp->nreds;
359
360 if (nreds >= 1)
361 {
362 /* loop over all the rules available here which require
363 lookahead */
364 m = state_table[state].lookaheads;
365 n = state_table[state + 1].lookaheads;
366
367 for (i = n - 1; i >= m; i--)
368 {
369 rule = -LAruleno[i];
370 wordp = LA (i);
371 mask = 1;
372
373 /* and find each token which the rule finds acceptable
374 to come next */
375 for (j = 0; j < ntokens; j++)
376 {
377 /* and record this rule as the rule to use if that
378 token follows. */
379 if (mask & *wordp)
380 actrow[j] = rule;
381
382 mask <<= 1;
383 if (mask == 0)
384 {
385 mask = 1;
386 wordp++;
387 }
388 }
389 }
390 }
391 }
392
393 shiftp = state_table[state].shift_table;
394
395 /* Now see which tokens are allowed for shifts in this state. For
396 them, record the shift as the thing to do. So shift is preferred
397 to reduce. */
398
399 if (shiftp)
400 {
401 k = shiftp->nshifts;
402
403 for (i = 0; i < k; i++)
404 {
405 shift_state = shiftp->shifts[i];
406 if (!shift_state)
407 continue;
408
409 symbol = state_table[shift_state].accessing_symbol;
410
411 if (ISVAR (symbol))
412 break;
413
414 actrow[symbol] = shift_state;
415
416 /* Do not use any default reduction if there is a shift for
417 error */
418 if (symbol == error_token_number)
419 nodefault = 1;
420 }
421 }
422
423 errp = err_table[state];
424
425 /* See which tokens are an explicit error in this state (due to
426 %nonassoc). For them, record MINSHORT as the action. */
427
428 if (errp)
429 {
430 k = errp->nerrs;
431
432 for (i = 0; i < k; i++)
433 {
434 symbol = errp->errs[i];
435 actrow[symbol] = MINSHORT;
436 }
437 }
438
439 /* Now find the most common reduction and make it the default action
440 for this state. */
441
442 if (nreds >= 1 && !nodefault)
443 {
444 if (state_table[state].consistent)
445 default_rule = redp->rules[0];
446 else
447 {
448 max = 0;
449 for (i = m; i < n; i++)
450 {
451 count = 0;
452 rule = -LAruleno[i];
453
454 for (j = 0; j < ntokens; j++)
455 {
456 if (actrow[j] == rule)
457 count++;
458 }
459
460 if (count > max)
461 {
462 max = count;
463 default_rule = rule;
464 }
465 }
466
467 /* actions which match the default are replaced with zero,
468 which means "use the default" */
469
470 if (max > 0)
471 {
472 for (j = 0; j < ntokens; j++)
473 {
474 if (actrow[j] == default_rule)
475 actrow[j] = 0;
476 }
477
478 default_rule = -default_rule;
479 }
480 }
481 }
482
483 /* If have no default rule, the default is an error.
484 So replace any action which says "error" with "use default". */
485
486 if (default_rule == 0)
487 for (j = 0; j < ntokens; j++)
488 {
489 if (actrow[j] == MINSHORT)
490 actrow[j] = 0;
491 }
492
493 return default_rule;
494 }
495
496
497 static void
498 save_row (int state)
499 {
500 int i;
501 int count;
502 short *sp;
503 short *sp1;
504 short *sp2;
505
506 count = 0;
507 for (i = 0; i < ntokens; i++)
508 {
509 if (actrow[i] != 0)
510 count++;
511 }
512
513 if (count == 0)
514 return;
515
516 froms[state] = sp1 = sp = XCALLOC (short, count);
517 tos[state] = sp2 = XCALLOC (short, count);
518
519 for (i = 0; i < ntokens; i++)
520 {
521 if (actrow[i] != 0)
522 {
523 *sp1++ = i;
524 *sp2++ = actrow[i];
525 }
526 }
527
528 tally[state] = count;
529 width[state] = sp1[-1] - sp[0] + 1;
530 }
531
532
533 /*------------------------------------------------------------------.
534 | Figure out the actions for the specified state, indexed by |
535 | lookahead token type. |
536 | |
537 | The YYDEFACT table is output now. The detailed info is saved for |
538 | putting into YYTABLE later. |
539 `------------------------------------------------------------------*/
540
541 static void
542 token_actions (void)
543 {
544 int i;
545 short *yydefact = XCALLOC (short, nstates);
546
547 actrow = XCALLOC (short, ntokens);
548 for (i = 0; i < nstates; ++i)
549 {
550 yydefact[i] = action_row (i);
551 save_row (i);
552 }
553
554 output_table_data (&output_obstack, yydefact,
555 yydefact[0], 1, nstates);
556 muscle_insert ("defact", obstack_finish (&output_obstack));
557
558 XFREE (actrow);
559 XFREE (yydefact);
560 }
561
562
563 static void
564 free_shifts (void)
565 {
566 shifts *sp, *sptmp; /* JF derefrenced freed ptr */
567
568 for (sp = first_shift; sp; sp = sptmp)
569 {
570 sptmp = sp->next;
571 XFREE (sp);
572 }
573 }
574
575
576 static void
577 free_reductions (void)
578 {
579 reductions *rp, *rptmp; /* JF fixed freed ptr */
580
581 for (rp = first_reduction; rp; rp = rptmp)
582 {
583 rptmp = rp->next;
584 XFREE (rp);
585 }
586 }
587
588
589
590 static void
591 save_column (int symbol, int default_state)
592 {
593 int i;
594 short *sp;
595 short *sp1;
596 short *sp2;
597 int count;
598 int symno;
599
600 short begin = goto_map[symbol];
601 short end = goto_map[symbol + 1];
602
603 count = 0;
604 for (i = begin; i < end; i++)
605 {
606 if (to_state[i] != default_state)
607 count++;
608 }
609
610 if (count == 0)
611 return;
612
613 symno = symbol - ntokens + nstates;
614
615 froms[symno] = sp1 = sp = XCALLOC (short, count);
616 tos[symno] = sp2 = XCALLOC (short, count);
617
618 for (i = begin; i < end; i++)
619 {
620 if (to_state[i] != default_state)
621 {
622 *sp1++ = from_state[i];
623 *sp2++ = to_state[i];
624 }
625 }
626
627 tally[symno] = count;
628 width[symno] = sp1[-1] - sp[0] + 1;
629 }
630
631 static int
632 default_goto (int symbol)
633 {
634 int i;
635 int m;
636 int n;
637 int default_state;
638 int max;
639
640 m = goto_map[symbol];
641 n = goto_map[symbol + 1];
642
643 if (m == n)
644 return -1;
645
646 for (i = 0; i < nstates; i++)
647 state_count[i] = 0;
648
649 for (i = m; i < n; i++)
650 state_count[to_state[i]]++;
651
652 max = 0;
653 default_state = -1;
654
655 for (i = 0; i < nstates; i++)
656 {
657 if (state_count[i] > max)
658 {
659 max = state_count[i];
660 default_state = i;
661 }
662 }
663
664 return default_state;
665 }
666
667
668 /*-------------------------------------------------------------------.
669 | Figure out what to do after reducing with each rule, depending on |
670 | the saved state from before the beginning of parsing the data that |
671 | matched this rule. |
672 | |
673 | The YYDEFGOTO table is output now. The detailed info is saved for |
674 | putting into YYTABLE later. |
675 `-------------------------------------------------------------------*/
676
677 static void
678 goto_actions (void)
679 {
680 int i;
681 short *yydefgoto = XMALLOC (short, nsyms - ntokens);
682
683 state_count = XCALLOC (short, nstates);
684 for (i = ntokens; i < nsyms; ++i)
685 {
686 int default_state = default_goto (i);
687 save_column (i, default_state);
688 yydefgoto[i - ntokens] = default_state;
689 }
690
691 output_table_data (&output_obstack, yydefgoto,
692 yydefgoto[0], 1, nsyms - ntokens);
693 muscle_insert ("defgoto", obstack_finish (&output_obstack));
694
695 XFREE (state_count);
696 XFREE (yydefgoto);
697 }
698
699
700 /* The next few functions decide how to pack the actions and gotos
701 information into yytable. */
702
703 static void
704 sort_actions (void)
705 {
706 int i;
707 int j;
708 int k;
709 int t;
710 int w;
711
712 order = XCALLOC (short, nvectors);
713 nentries = 0;
714
715 for (i = 0; i < nvectors; i++)
716 {
717 if (tally[i] > 0)
718 {
719 t = tally[i];
720 w = width[i];
721 j = nentries - 1;
722
723 while (j >= 0 && (width[order[j]] < w))
724 j--;
725
726 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
727 j--;
728
729 for (k = nentries - 1; k > j; k--)
730 order[k + 1] = order[k];
731
732 order[j + 1] = i;
733 nentries++;
734 }
735 }
736 }
737
738
739 static int
740 matching_state (int vector)
741 {
742 int i;
743 int j;
744 int k;
745 int t;
746 int w;
747 int match;
748 int prev;
749
750 i = order[vector];
751 if (i >= nstates)
752 return -1;
753
754 t = tally[i];
755 w = width[i];
756
757 for (prev = vector - 1; prev >= 0; prev--)
758 {
759 j = order[prev];
760 if (width[j] != w || tally[j] != t)
761 return -1;
762
763 match = 1;
764 for (k = 0; match && k < t; k++)
765 {
766 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
767 match = 0;
768 }
769
770 if (match)
771 return j;
772 }
773
774 return -1;
775 }
776
777
778 static int
779 pack_vector (int vector)
780 {
781 int i;
782 int j;
783 int k;
784 int t;
785 int loc = 0;
786 int ok;
787 short *from;
788 short *to;
789
790 i = order[vector];
791 t = tally[i];
792
793 assert (t);
794
795 from = froms[i];
796 to = tos[i];
797
798 for (j = lowzero - from[0]; j < MAXTABLE; j++)
799 {
800 ok = 1;
801
802 for (k = 0; ok && k < t; k++)
803 {
804 loc = j + from[k];
805 if (loc > MAXTABLE)
806 fatal (_("maximum table size (%d) exceeded"), MAXTABLE);
807
808 if (table[loc] != 0)
809 ok = 0;
810 }
811
812 for (k = 0; ok && k < vector; k++)
813 {
814 if (pos[k] == j)
815 ok = 0;
816 }
817
818 if (ok)
819 {
820 for (k = 0; k < t; k++)
821 {
822 loc = j + from[k];
823 table[loc] = to[k];
824 check[loc] = from[k];
825 }
826
827 while (table[lowzero] != 0)
828 lowzero++;
829
830 if (loc > high)
831 high = loc;
832
833 return j;
834 }
835 }
836
837 berror ("pack_vector");
838 return 0; /* JF keep lint happy */
839 }
840
841
842 static void
843 pack_table (void)
844 {
845 int i;
846 int place;
847 int state;
848
849 base = XCALLOC (short, nvectors);
850 pos = XCALLOC (short, nentries);
851 table = XCALLOC (short, MAXTABLE);
852 check = XCALLOC (short, MAXTABLE);
853
854 lowzero = 0;
855 high = 0;
856
857 for (i = 0; i < nvectors; i++)
858 base[i] = MINSHORT;
859
860 for (i = 0; i < MAXTABLE; i++)
861 check[i] = -1;
862
863 for (i = 0; i < nentries; i++)
864 {
865 state = matching_state (i);
866
867 if (state < 0)
868 place = pack_vector (i);
869 else
870 place = base[state];
871
872 pos[i] = place;
873 base[order[i]] = place;
874 }
875
876 for (i = 0; i < nvectors; i++)
877 {
878 if (froms[i])
879 XFREE (froms[i]);
880 if (tos[i])
881 XFREE (tos[i]);
882 }
883
884 XFREE (froms);
885 XFREE (tos);
886 XFREE (pos);
887 }
888
889 /* the following functions output yytable, yycheck
890 and the vectors whose elements index the portion starts */
891
892 static void
893 output_base (void)
894 {
895 /* Output pact. */
896 output_table_data (&output_obstack, base,
897 base[0], 1, nstates);
898 muscle_insert ("pact", obstack_finish (&output_obstack));
899
900 /* Output pgoto. */
901 output_table_data (&output_obstack, base,
902 base[nstates], nstates + 1, nvectors);
903 muscle_insert ("pgoto", obstack_finish (&output_obstack));
904
905 XFREE (base);
906 }
907
908
909 static void
910 output_table (void)
911 {
912 output_table_data (&output_obstack, table,
913 table[0], 1, high + 1);
914 muscle_insert ("table", obstack_finish (&output_obstack));
915 XFREE (table);
916 }
917
918
919 static void
920 output_check (void)
921 {
922 output_table_data (&output_obstack, check,
923 check[0], 1, high + 1);
924 muscle_insert ("check", obstack_finish (&output_obstack));
925 XFREE (check);
926 }
927
928 /* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
929 and yycheck. */
930
931 static void
932 output_actions (void)
933 {
934 nvectors = nstates + nvars;
935
936 froms = XCALLOC (short *, nvectors);
937 tos = XCALLOC (short *, nvectors);
938 tally = XCALLOC (short, nvectors);
939 width = XCALLOC (short, nvectors);
940
941 token_actions ();
942 free_shifts ();
943 free_reductions ();
944 XFREE (LA);
945 XFREE (LAruleno);
946
947 goto_actions ();
948 XFREE (goto_map + ntokens);
949 XFREE (from_state);
950 XFREE (to_state);
951
952 sort_actions ();
953 pack_table ();
954
955 output_base ();
956 output_table ();
957
958 output_check ();
959 XFREE (state_table);
960 }
961
962 \f
963 /*------------------------------------------------------------.
964 | Copy the parser code from SKEL_FILENAME into OOUT obstack. |
965 | and do the muscle substitution. |
966 `------------------------------------------------------------*/
967
968 static void
969 output_parser (const char *skel_filename, struct obstack *oout)
970 {
971 int c;
972 FILE *fskel;
973 size_t line;
974
975 fskel = xfopen (skel_filename, "r");
976
977 /* New output code. */
978 line = 1;
979 c = getc (fskel);
980 while (c != EOF)
981 {
982 if (c != '%')
983 {
984 if (c == '\n')
985 ++line;
986 obstack_1grow (oout, c);
987 c = getc (fskel);
988 }
989 else if ((c = getc (fskel)) == '%')
990 {
991 /* Read the muscle. */
992 const char *muscle_key = 0;
993 const char *muscle_value = 0;
994
995 while (isalnum (c = getc (fskel)) || c == '_')
996 obstack_1grow (&muscle_obstack, c);
997 obstack_1grow (&muscle_obstack, 0);
998
999 /* Output the right value, or see if it's something special. */
1000 muscle_key = obstack_finish (&muscle_obstack);
1001 muscle_value = muscle_find (muscle_key);
1002 if (muscle_value)
1003 obstack_sgrow (oout, muscle_value);
1004 else if (!strcmp (muscle_key, "line"))
1005 obstack_fgrow1 (oout, "%d", line + 1);
1006 else if (!strcmp (muscle_key, "input_line"))
1007 obstack_fgrow1 (oout, "%d", lineno);
1008 /* FIXME: Insert the code to recognize %%sub-skeleton for exemple. */
1009 else
1010 {
1011 obstack_sgrow (oout, "%%");
1012 obstack_sgrow (oout, muscle_key);
1013 }
1014 }
1015 else
1016 obstack_1grow (oout, '%');
1017 }
1018
1019 /* End. */
1020 xfclose (fskel);
1021 }
1022
1023 /*----------------------------------------.
1024 | Prepare the master parser to be output |
1025 `----------------------------------------*/
1026
1027 static void
1028 output_master_parser (void)
1029 {
1030 if (!skeleton)
1031 {
1032 if (semantic_parser)
1033 skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
1034 else
1035 skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
1036 }
1037 output_parser (skeleton, &table_obstack);
1038 }
1039
1040
1041 static void
1042 free_itemsets (void)
1043 {
1044 core *cp, *cptmp;
1045 for (cp = first_state; cp; cp = cptmp)
1046 {
1047 cptmp = cp->next;
1048 XFREE (cp);
1049 }
1050 }
1051
1052 /* FIXME. */
1053
1054 #define MUSCLE_INSERT_INT(Key, Value) \
1055 { \
1056 obstack_fgrow1 (&muscle_obstack, "%d", Value); \
1057 obstack_1grow (&muscle_obstack, 0); \
1058 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1059 }
1060
1061 #define MUSCLE_INSERT_STRING(Key, Value) \
1062 { \
1063 obstack_sgrow (&muscle_obstack, Value); \
1064 obstack_1grow (&muscle_obstack, 0); \
1065 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1066 }
1067
1068 #define MUSCLE_INSERT_PREFIX(Key, Value) \
1069 { \
1070 obstack_fgrow2 (&muscle_obstack, "%s%s", spec_name_prefix, Value); \
1071 obstack_1grow (&muscle_obstack, 0); \
1072 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
1073 }
1074
1075 static void
1076 prepare (void)
1077 {
1078 MUSCLE_INSERT_INT ("last", high);
1079 MUSCLE_INSERT_INT ("flag", MINSHORT);
1080 MUSCLE_INSERT_INT ("pure", pure_parser);
1081 MUSCLE_INSERT_INT ("nsym", nsyms);
1082 MUSCLE_INSERT_INT ("debug", debug_flag);
1083 MUSCLE_INSERT_INT ("final", final_state);
1084 MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
1085 MUSCLE_INSERT_INT ("ntbase", ntokens);
1086 MUSCLE_INSERT_INT ("verbose", 0);
1087
1088 MUSCLE_INSERT_INT ("nnts", nvars);
1089 MUSCLE_INSERT_INT ("nrules", nrules);
1090 MUSCLE_INSERT_INT ("nstates", nstates);
1091 MUSCLE_INSERT_INT ("ntokens", ntokens);
1092
1093 MUSCLE_INSERT_INT ("locations_flag", locations_flag);
1094
1095 /* We need to save the actions in the muscle %%action. */
1096 muscle_insert ("action", obstack_finish (&action_obstack));
1097
1098 if (spec_name_prefix)
1099 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
1100 }
1101
1102 /*----------------------------------------------------------.
1103 | Output the parsing tables and the parser code to ftable. |
1104 `----------------------------------------------------------*/
1105
1106 void
1107 output (void)
1108 {
1109 obstack_init (&output_obstack);
1110
1111 free_itemsets ();
1112
1113 output_token_translations ();
1114 output_gram ();
1115
1116 XFREE (ritem);
1117 if (semantic_parser)
1118 output_stos ();
1119 output_rule_data ();
1120 XFREE (user_toknums);
1121 output_actions ();
1122
1123 #if 0
1124 if (!no_parser_flag) */
1125 #endif
1126 prepare ();
1127 /* Copy definitions in directive. */
1128 muscle_insert ("prologue", obstack_finish (&attrs_obstack));
1129
1130 output_master_parser ();
1131
1132 obstack_free (&muscle_obstack, 0);
1133 obstack_free (&output_obstack, 0);
1134 obstack_free (&action_obstack, 0);
1135 }