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