386BSD 0.1 development
[unix-history] / usr / src / usr.bin / yacc / output.c
CommitLineData
30885fad
WJ
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Robert Paul Corbett.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38static char sccsid[] = "@(#)output.c 5.6 (Berkeley) 1/20/91";
39#endif /* not lint */
40
41#include "defs.h"
42
43static int nvectors;
44static int nentries;
45static short **froms;
46static short **tos;
47static short *tally;
48static short *width;
49static short *state_count;
50static short *order;
51static short *base;
52static short *pos;
53static int maxtable;
54static short *table;
55static short *check;
56static int lowzero;
57static int high;
58
59
60output()
61{
62 free_itemsets();
63 free_shifts();
64 free_reductions();
65 output_stored_text();
66 output_defines();
67 output_rule_data();
68 output_yydefred();
69 output_actions();
70 free_parser();
71 output_debug();
72 output_stype();
73 if (rflag) write_section(tables);
74 write_section(header);
75 output_trailing_text();
76 write_section(body);
77 output_semantic_actions();
78 write_section(trailer);
79}
80
81
82output_rule_data()
83{
84 register int i;
85 register int j;
86
87
88 fprintf(output_file, "short yylhs[] = {%42d,",
89 symbol_value[start_symbol]);
90
91 j = 10;
92 for (i = 3; i < nrules; i++)
93 {
94 if (j >= 10)
95 {
96 if (!rflag) ++outline;
97 putc('\n', output_file);
98 j = 1;
99 }
100 else
101 ++j;
102
103 fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
104 }
105 if (!rflag) outline += 2;
106 fprintf(output_file, "\n};\n");
107
108 fprintf(output_file, "short yylen[] = {%42d,", 2);
109
110 j = 10;
111 for (i = 3; i < nrules; i++)
112 {
113 if (j >= 10)
114 {
115 if (!rflag) ++outline;
116 putc('\n', output_file);
117 j = 1;
118 }
119 else
120 j++;
121
122 fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
123 }
124 if (!rflag) outline += 2;
125 fprintf(output_file, "\n};\n");
126}
127
128
129output_yydefred()
130{
131 register int i, j;
132
133 fprintf(output_file, "short yydefred[] = {%39d,",
134 (defred[0] ? defred[0] - 2 : 0));
135
136 j = 10;
137 for (i = 1; i < nstates; i++)
138 {
139 if (j < 10)
140 ++j;
141 else
142 {
143 if (!rflag) ++outline;
144 putc('\n', output_file);
145 j = 1;
146 }
147
148 fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
149 }
150
151 if (!rflag) outline += 2;
152 fprintf(output_file, "\n};\n");
153}
154
155
156output_actions()
157{
158 nvectors = 2*nstates + nvars;
159
160 froms = NEW2(nvectors, short *);
161 tos = NEW2(nvectors, short *);
162 tally = NEW2(nvectors, short);
163 width = NEW2(nvectors, short);
164
165 token_actions();
166 FREE(lookaheads);
167 FREE(LA);
168 FREE(LAruleno);
169 FREE(accessing_symbol);
170
171 goto_actions();
172 FREE(goto_map + ntokens);
173 FREE(from_state);
174 FREE(to_state);
175
176 sort_actions();
177 pack_table();
178 output_base();
179 output_table();
180 output_check();
181}
182
183
184token_actions()
185{
186 register int i, j;
187 register int shiftcount, reducecount;
188 register int max, min;
189 register short *actionrow, *r, *s;
190 register action *p;
191
192 actionrow = NEW2(2*ntokens, short);
193 for (i = 0; i < nstates; ++i)
194 {
195 if (parser[i])
196 {
197 for (j = 0; j < 2*ntokens; ++j)
198 actionrow[j] = 0;
199
200 shiftcount = 0;
201 reducecount = 0;
202 for (p = parser[i]; p; p = p->next)
203 {
204 if (p->suppressed == 0)
205 {
206 if (p->action_code == SHIFT)
207 {
208 ++shiftcount;
209 actionrow[p->symbol] = p->number;
210 }
211 else if (p->action_code == REDUCE && p->number != defred[i])
212 {
213 ++reducecount;
214 actionrow[p->symbol + ntokens] = p->number;
215 }
216 }
217 }
218
219 tally[i] = shiftcount;
220 tally[nstates+i] = reducecount;
221 width[i] = 0;
222 width[nstates+i] = 0;
223 if (shiftcount > 0)
224 {
225 froms[i] = r = NEW2(shiftcount, short);
226 tos[i] = s = NEW2(shiftcount, short);
227 min = MAXSHORT;
228 max = 0;
229 for (j = 0; j < ntokens; ++j)
230 {
231 if (actionrow[j])
232 {
233 if (min > symbol_value[j])
234 min = symbol_value[j];
235 if (max < symbol_value[j])
236 max = symbol_value[j];
237 *r++ = symbol_value[j];
238 *s++ = actionrow[j];
239 }
240 }
241 width[i] = max - min + 1;
242 }
243 if (reducecount > 0)
244 {
245 froms[nstates+i] = r = NEW2(reducecount, short);
246 tos[nstates+i] = s = NEW2(reducecount, short);
247 min = MAXSHORT;
248 max = 0;
249 for (j = 0; j < ntokens; ++j)
250 {
251 if (actionrow[ntokens+j])
252 {
253 if (min > symbol_value[j])
254 min = symbol_value[j];
255 if (max < symbol_value[j])
256 max = symbol_value[j];
257 *r++ = symbol_value[j];
258 *s++ = actionrow[ntokens+j] - 2;
259 }
260 }
261 width[nstates+i] = max - min + 1;
262 }
263 }
264 }
265 FREE(actionrow);
266}
267
268goto_actions()
269{
270 register int i, j, k;
271
272 state_count = NEW2(nstates, short);
273
274 k = default_goto(start_symbol + 1);
275 fprintf(output_file, "short yydgoto[] = {%40d,", k);
276 save_column(start_symbol + 1, k);
277
278 j = 10;
279 for (i = start_symbol + 2; i < nsyms; i++)
280 {
281 if (j >= 10)
282 {
283 if (!rflag) ++outline;
284 putc('\n', output_file);
285 j = 1;
286 }
287 else
288 ++j;
289
290 k = default_goto(i);
291 fprintf(output_file, "%5d,", k);
292 save_column(i, k);
293 }
294
295 if (!rflag) outline += 2;
296 fprintf(output_file, "\n};\n");
297 FREE(state_count);
298}
299
300int
301default_goto(symbol)
302int symbol;
303{
304 register int i;
305 register int m;
306 register int n;
307 register int default_state;
308 register int max;
309
310 m = goto_map[symbol];
311 n = goto_map[symbol + 1];
312
313 if (m == n) return (0);
314
315 for (i = 0; i < nstates; i++)
316 state_count[i] = 0;
317
318 for (i = m; i < n; i++)
319 state_count[to_state[i]]++;
320
321 max = 0;
322 default_state = 0;
323 for (i = 0; i < nstates; i++)
324 {
325 if (state_count[i] > max)
326 {
327 max = state_count[i];
328 default_state = i;
329 }
330 }
331
332 return (default_state);
333}
334
335
336
337save_column(symbol, default_state)
338int symbol;
339int default_state;
340{
341 register int i;
342 register int m;
343 register int n;
344 register short *sp;
345 register short *sp1;
346 register short *sp2;
347 register int count;
348 register int symno;
349
350 m = goto_map[symbol];
351 n = goto_map[symbol + 1];
352
353 count = 0;
354 for (i = m; i < n; i++)
355 {
356 if (to_state[i] != default_state)
357 ++count;
358 }
359 if (count == 0) return;
360
361 symno = symbol_value[symbol] + 2*nstates;
362
363 froms[symno] = sp1 = sp = NEW2(count, short);
364 tos[symno] = sp2 = NEW2(count, short);
365
366 for (i = m; i < n; i++)
367 {
368 if (to_state[i] != default_state)
369 {
370 *sp1++ = from_state[i];
371 *sp2++ = to_state[i];
372 }
373 }
374
375 tally[symno] = count;
376 width[symno] = sp1[-1] - sp[0] + 1;
377}
378
379sort_actions()
380{
381 register int i;
382 register int j;
383 register int k;
384 register int t;
385 register int w;
386
387 order = NEW2(nvectors, short);
388 nentries = 0;
389
390 for (i = 0; i < nvectors; i++)
391 {
392 if (tally[i] > 0)
393 {
394 t = tally[i];
395 w = width[i];
396 j = nentries - 1;
397
398 while (j >= 0 && (width[order[j]] < w))
399 j--;
400
401 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
402 j--;
403
404 for (k = nentries - 1; k > j; k--)
405 order[k + 1] = order[k];
406
407 order[j + 1] = i;
408 nentries++;
409 }
410 }
411}
412
413
414pack_table()
415{
416 register int i;
417 register int place;
418 register int state;
419
420 base = NEW2(nvectors, short);
421 pos = NEW2(nentries, short);
422
423 maxtable = 1000;
424 table = NEW2(maxtable, short);
425 check = NEW2(maxtable, short);
426
427 lowzero = 0;
428 high = 0;
429
430 for (i = 0; i < maxtable; i++)
431 check[i] = -1;
432
433 for (i = 0; i < nentries; i++)
434 {
435 state = matching_vector(i);
436
437 if (state < 0)
438 place = pack_vector(i);
439 else
440 place = base[state];
441
442 pos[i] = place;
443 base[order[i]] = place;
444 }
445
446 for (i = 0; i < nvectors; i++)
447 {
448 if (froms[i])
449 FREE(froms[i]);
450 if (tos[i])
451 FREE(tos[i]);
452 }
453
454 FREE(froms);
455 FREE(tos);
456 FREE(pos);
457}
458
459
460/* The function matching_vector determines if the vector specified by */
461/* the input parameter matches a previously considered vector. The */
462/* test at the start of the function checks if the vector represents */
463/* a row of shifts over terminal symbols or a row of reductions, or a */
464/* column of shifts over a nonterminal symbol. Berkeley Yacc does not */
465/* check if a column of shifts over a nonterminal symbols matches a */
466/* previously considered vector. Because of the nature of LR parsing */
467/* tables, no two columns can match. Therefore, the only possible */
468/* match would be between a row and a column. Such matches are */
469/* unlikely. Therefore, to save time, no attempt is made to see if a */
470/* column matches a previously considered vector. */
471/* */
472/* Matching_vector is poorly designed. The test could easily be made */
473/* faster. Also, it depends on the vectors being in a specific */
474/* order. */
475
476int
477matching_vector(vector)
478int vector;
479{
480 register int i;
481 register int j;
482 register int k;
483 register int t;
484 register int w;
485 register int match;
486 register int prev;
487
488 i = order[vector];
489 if (i >= 2*nstates)
490 return (-1);
491
492 t = tally[i];
493 w = width[i];
494
495 for (prev = vector - 1; prev >= 0; prev--)
496 {
497 j = order[prev];
498 if (width[j] != w || tally[j] != t)
499 return (-1);
500
501 match = 1;
502 for (k = 0; match && k < t; k++)
503 {
504 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
505 match = 0;
506 }
507
508 if (match)
509 return (j);
510 }
511
512 return (-1);
513}
514
515
516
517int
518pack_vector(vector)
519int vector;
520{
521 register int i, j, k, l;
522 register int t;
523 register int loc;
524 register int ok;
525 register short *from;
526 register short *to;
527 int newmax;
528
529 i = order[vector];
530 t = tally[i];
531 assert(t);
532
533 from = froms[i];
534 to = tos[i];
535
536 j = lowzero - from[0];
537 for (k = 1; k < t; ++k)
538 if (lowzero - from[k] > j)
539 j = lowzero - from[k];
540 for (;; ++j)
541 {
542 if (j == 0)
543 continue;
544 ok = 1;
545 for (k = 0; ok && k < t; k++)
546 {
547 loc = j + from[k];
548 if (loc >= maxtable)
549 {
550 if (loc >= MAXTABLE)
551 fatal("maximum table size exceeded");
552
553 newmax = maxtable;
554 do { newmax += 200; } while (newmax <= loc);
555 table = (short *) REALLOC(table, newmax*sizeof(short));
556 if (table == 0) no_space();
557 check = (short *) REALLOC(check, newmax*sizeof(short));
558 if (check == 0) no_space();
559 for (l = maxtable; l < newmax; ++l)
560 {
561 table[l] = 0;
562 check[l] = -1;
563 }
564 maxtable = newmax;
565 }
566
567 if (check[loc] != -1)
568 ok = 0;
569 }
570 for (k = 0; ok && k < vector; k++)
571 {
572 if (pos[k] == j)
573 ok = 0;
574 }
575 if (ok)
576 {
577 for (k = 0; k < t; k++)
578 {
579 loc = j + from[k];
580 table[loc] = to[k];
581 check[loc] = from[k];
582 if (loc > high) high = loc;
583 }
584
585 while (check[lowzero] != -1)
586 ++lowzero;
587
588 return (j);
589 }
590 }
591}
592
593
594
595output_base()
596{
597 register int i, j;
598
599 fprintf(output_file, "short yysindex[] = {%39d,", base[0]);
600
601 j = 10;
602 for (i = 1; i < nstates; i++)
603 {
604 if (j >= 10)
605 {
606 if (!rflag) ++outline;
607 putc('\n', output_file);
608 j = 1;
609 }
610 else
611 ++j;
612
613 fprintf(output_file, "%5d,", base[i]);
614 }
615
616 if (!rflag) outline += 2;
617 fprintf(output_file, "\n};\nshort yyrindex[] = {%39d,",
618 base[nstates]);
619
620 j = 10;
621 for (i = nstates + 1; i < 2*nstates; i++)
622 {
623 if (j >= 10)
624 {
625 if (!rflag) ++outline;
626 putc('\n', output_file);
627 j = 1;
628 }
629 else
630 ++j;
631
632 fprintf(output_file, "%5d,", base[i]);
633 }
634
635 if (!rflag) outline += 2;
636 fprintf(output_file, "\n};\nshort yygindex[] = {%39d,",
637 base[2*nstates]);
638
639 j = 10;
640 for (i = 2*nstates + 1; i < nvectors - 1; i++)
641 {
642 if (j >= 10)
643 {
644 if (!rflag) ++outline;
645 putc('\n', output_file);
646 j = 1;
647 }
648 else
649 ++j;
650
651 fprintf(output_file, "%5d,", base[i]);
652 }
653
654 if (!rflag) outline += 2;
655 fprintf(output_file, "\n};\n");
656 FREE(base);
657}
658
659
660
661output_table()
662{
663 register int i;
664 register int j;
665
666 ++outline;
667 fprintf(code_file, "#define YYTABLESIZE %d\n", high);
668 fprintf(output_file, "short yytable[] = {%40d,", table[0]);
669
670 j = 10;
671 for (i = 1; i <= high; i++)
672 {
673 if (j >= 10)
674 {
675 if (!rflag) ++outline;
676 putc('\n', output_file);
677 j = 1;
678 }
679 else
680 ++j;
681
682 fprintf(output_file, "%5d,", table[i]);
683 }
684
685 if (!rflag) outline += 2;
686 fprintf(output_file, "\n};\n");
687 FREE(table);
688}
689
690
691
692output_check()
693{
694 register int i;
695 register int j;
696
697 fprintf(output_file, "short yycheck[] = {%40d,", check[0]);
698
699 j = 10;
700 for (i = 1; i <= high; i++)
701 {
702 if (j >= 10)
703 {
704 if (!rflag) ++outline;
705 putc('\n', output_file);
706 j = 1;
707 }
708 else
709 ++j;
710
711 fprintf(output_file, "%5d,", check[i]);
712 }
713
714 if (!rflag) outline += 2;
715 fprintf(output_file, "\n};\n");
716 FREE(check);
717}
718
719
720int
721is_C_identifier(name)
722char *name;
723{
724 register char *s;
725 register int c;
726
727 s = name;
728 c = *s;
729 if (c == '"')
730 {
731 c = *++s;
732 if (!isalpha(c) && c != '_' && c != '$')
733 return (0);
734 while ((c = *++s) != '"')
735 {
736 if (!isalnum(c) && c != '_' && c != '$')
737 return (0);
738 }
739 return (1);
740 }
741
742 if (!isalpha(c) && c != '_' && c != '$')
743 return (0);
744 while (c = *++s)
745 {
746 if (!isalnum(c) && c != '_' && c != '$')
747 return (0);
748 }
749 return (1);
750}
751
752
753output_defines()
754{
755 register int c, i;
756 register char *s;
757
758 for (i = 2; i < ntokens; ++i)
759 {
760 s = symbol_name[i];
761 if (is_C_identifier(s))
762 {
763 fprintf(code_file, "#define ");
764 if (dflag) fprintf(defines_file, "#define ");
765 c = *s;
766 if (c == '"')
767 {
768 while ((c = *++s) != '"')
769 {
770 putc(c, code_file);
771 if (dflag) putc(c, defines_file);
772 }
773 }
774 else
775 {
776 do
777 {
778 putc(c, code_file);
779 if (dflag) putc(c, defines_file);
780 }
781 while (c = *++s);
782 }
783 ++outline;
784 fprintf(code_file, " %d\n", symbol_value[i]);
785 if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]);
786 }
787 }
788
789 ++outline;
790 fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
791
792 if (dflag && unionized)
793 {
794 fclose(union_file);
795 union_file = fopen(union_file_name, "r");
796 if (union_file == NULL) open_error(union_file_name);
797 while ((c = getc(union_file)) != EOF)
798 putc(c, defines_file);
799 fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE yylval;\n");
800 }
801}
802
803
804output_stored_text()
805{
806 register int c;
807 register FILE *in, *out;
808
809 fclose(text_file);
810 text_file = fopen(text_file_name, "r");
811 if (text_file == NULL)
812 open_error(text_file_name);
813 in = text_file;
814 if ((c = getc(in)) == EOF)
815 return;
816 out = code_file;
817 if (c == '\n')
818 ++outline;
819 putc(c, out);
820 while ((c = getc(in)) != EOF)
821 {
822 if (c == '\n')
823 ++outline;
824 putc(c, out);
825 }
826 if (!lflag)
827 fprintf(out, line_format, ++outline + 1, code_file_name);
828}
829
830
831output_debug()
832{
833 register int i, j, k, max;
834 char **symnam, *s;
835
836 ++outline;
837 fprintf(code_file, "#define YYFINAL %d\n", final_state);
838 outline += 3;
839 fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
840 tflag);
841 if (rflag)
842 fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
843 tflag);
844
845 max = 0;
846 for (i = 2; i < ntokens; ++i)
847 if (symbol_value[i] > max)
848 max = symbol_value[i];
849 ++outline;
850 fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
851
852 symnam = (char **) MALLOC((max+1)*sizeof(char *));
853 if (symnam == 0) no_space();
854
855 /* Note that it is not necessary to initialize the element */
856 /* symnam[max]. */
857 for (i = 0; i < max; ++i)
858 symnam[i] = 0;
859 for (i = ntokens - 1; i >= 2; --i)
860 symnam[symbol_value[i]] = symbol_name[i];
861 symnam[0] = "end-of-file";
862
863 if (!rflag) ++outline;
864 fprintf(output_file, "#if YYDEBUG\nchar *yyname[] = {");
865 j = 80;
866 for (i = 0; i <= max; ++i)
867 {
868 if (s = symnam[i])
869 {
870 if (s[0] == '"')
871 {
872 k = 7;
873 while (*++s != '"')
874 {
875 ++k;
876 if (*s == '\\')
877 {
878 k += 2;
879 if (*++s == '\\')
880 ++k;
881 }
882 }
883 j += k;
884 if (j > 80)
885 {
886 if (!rflag) ++outline;
887 putc('\n', output_file);
888 j = k;
889 }
890 fprintf(output_file, "\"\\\"");
891 s = symnam[i];
892 while (*++s != '"')
893 {
894 if (*s == '\\')
895 {
896 fprintf(output_file, "\\\\");
897 if (*++s == '\\')
898 fprintf(output_file, "\\\\");
899 else
900 putc(*s, output_file);
901 }
902 else
903 putc(*s, output_file);
904 }
905 fprintf(output_file, "\\\"\",");
906 }
907 else if (s[0] == '\'')
908 {
909 if (s[1] == '"')
910 {
911 j += 7;
912 if (j > 80)
913 {
914 if (!rflag) ++outline;
915 putc('\n', output_file);
916 j = 7;
917 }
918 fprintf(output_file, "\"'\\\"'\",");
919 }
920 else
921 {
922 k = 5;
923 while (*++s != '\'')
924 {
925 ++k;
926 if (*s == '\\')
927 {
928 k += 2;
929 if (*++s == '\\')
930 ++k;
931 }
932 }
933 j += k;
934 if (j > 80)
935 {
936 if (!rflag) ++outline;
937 putc('\n', output_file);
938 j = k;
939 }
940 fprintf(output_file, "\"'");
941 s = symnam[i];
942 while (*++s != '\'')
943 {
944 if (*s == '\\')
945 {
946 fprintf(output_file, "\\\\");
947 if (*++s == '\\')
948 fprintf(output_file, "\\\\");
949 else
950 putc(*s, output_file);
951 }
952 else
953 putc(*s, output_file);
954 }
955 fprintf(output_file, "'\",");
956 }
957 }
958 else
959 {
960 k = strlen(s) + 3;
961 j += k;
962 if (j > 80)
963 {
964 if (!rflag) ++outline;
965 putc('\n', output_file);
966 j = k;
967 }
968 putc('"', output_file);
969 do { putc(*s, output_file); } while (*++s);
970 fprintf(output_file, "\",");
971 }
972 }
973 else
974 {
975 j += 2;
976 if (j > 80)
977 {
978 if (!rflag) ++outline;
979 putc('\n', output_file);
980 j = 2;
981 }
982 fprintf(output_file, "0,");
983 }
984 }
985 if (!rflag) outline += 2;
986 fprintf(output_file, "\n};\n");
987 FREE(symnam);
988
989 if (!rflag) ++outline;
990 fprintf(output_file, "char *yyrule[] = {\n");
991 for (i = 2; i < nrules; ++i)
992 {
993 fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
994 for (j = rrhs[i]; ritem[j] > 0; ++j)
995 {
996 s = symbol_name[ritem[j]];
997 if (s[0] == '"')
998 {
999 fprintf(output_file, " \\\"");
1000 while (*++s != '"')
1001 {
1002 if (*s == '\\')
1003 {
1004 if (s[1] == '\\')
1005 fprintf(output_file, "\\\\\\\\");
1006 else
1007 fprintf(output_file, "\\\\%c", s[1]);
1008 ++s;
1009 }
1010 else
1011 putc(*s, output_file);
1012 }
1013 fprintf(output_file, "\\\"");
1014 }
1015 else if (s[0] == '\'')
1016 {
1017 if (s[1] == '"')
1018 fprintf(output_file, " '\\\"'");
1019 else if (s[1] == '\\')
1020 {
1021 if (s[2] == '\\')
1022 fprintf(output_file, " '\\\\\\\\");
1023 else
1024 fprintf(output_file, " '\\\\%c", s[2]);
1025 s += 2;
1026 while (*++s != '\'')
1027 putc(*s, output_file);
1028 putc('\'', output_file);
1029 }
1030 else
1031 fprintf(output_file, " '%c'", s[1]);
1032 }
1033 else
1034 fprintf(output_file, " %s", s);
1035 }
1036 if (!rflag) ++outline;
1037 fprintf(output_file, "\",\n");
1038 }
1039
1040 if (!rflag) outline += 2;
1041 fprintf(output_file, "};\n#endif\n");
1042}
1043
1044
1045output_stype()
1046{
1047 if (!unionized && ntags == 0)
1048 {
1049 outline += 3;
1050 fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
1051 }
1052}
1053
1054
1055output_trailing_text()
1056{
1057 register int c, last;
1058 register FILE *in, *out;
1059
1060 if (line == 0)
1061 return;
1062
1063 in = input_file;
1064 out = code_file;
1065 c = *cptr;
1066 if (c == '\n')
1067 {
1068 ++lineno;
1069 if ((c = getc(in)) == EOF)
1070 return;
1071 if (!lflag)
1072 {
1073 ++outline;
1074 fprintf(out, line_format, lineno, input_file_name);
1075 }
1076 if (c == '\n')
1077 ++outline;
1078 putc(c, out);
1079 last = c;
1080 }
1081 else
1082 {
1083 if (!lflag)
1084 {
1085 ++outline;
1086 fprintf(out, line_format, lineno, input_file_name);
1087 }
1088 do { putc(c, out); } while ((c = *++cptr) != '\n');
1089 ++outline;
1090 putc('\n', out);
1091 last = '\n';
1092 }
1093
1094 while ((c = getc(in)) != EOF)
1095 {
1096 if (c == '\n')
1097 ++outline;
1098 putc(c, out);
1099 last = c;
1100 }
1101
1102 if (last != '\n')
1103 {
1104 ++outline;
1105 putc('\n', out);
1106 }
1107 if (!lflag)
1108 fprintf(out, line_format, ++outline + 1, code_file_name);
1109}
1110
1111
1112output_semantic_actions()
1113{
1114 register int c, last;
1115 register FILE *out;
1116
1117 fclose(action_file);
1118 action_file = fopen(action_file_name, "r");
1119 if (action_file == NULL)
1120 open_error(action_file_name);
1121
1122 if ((c = getc(action_file)) == EOF)
1123 return;
1124
1125 out = code_file;
1126 last = c;
1127 if (c == '\n')
1128 ++outline;
1129 putc(c, out);
1130 while ((c = getc(action_file)) != EOF)
1131 {
1132 if (c == '\n')
1133 ++outline;
1134 putc(c, out);
1135 last = c;
1136 }
1137
1138 if (last != '\n')
1139 {
1140 ++outline;
1141 putc('\n', out);
1142 }
1143
1144 if (!lflag)
1145 fprintf(out, line_format, ++outline + 1, code_file_name);
1146}
1147
1148
1149free_itemsets()
1150{
1151 register core *cp, *next;
1152
1153 FREE(state_table);
1154 for (cp = first_state; cp; cp = next)
1155 {
1156 next = cp->next;
1157 FREE(cp);
1158 }
1159}
1160
1161
1162free_shifts()
1163{
1164 register shifts *sp, *next;
1165
1166 FREE(shift_table);
1167 for (sp = first_shift; sp; sp = next)
1168 {
1169 next = sp->next;
1170 FREE(sp);
1171 }
1172}
1173
1174
1175
1176free_reductions()
1177{
1178 register reductions *rp, *next;
1179
1180 FREE(reduction_table);
1181 for (rp = first_reduction; rp; rp = next)
1182 {
1183 next = rp->next;
1184 FREE(rp);
1185 }
1186}