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