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