xref: /netbsd-src/external/bsd/byacc/dist/output.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: output.c,v 1.10 2013/12/30 19:08:55 christos Exp $	*/
2 
3 /* Id: output.c,v 1.45 2013/03/05 00:29:17 tom Exp  */
4 
5 #include "defs.h"
6 
7 #include <sys/cdefs.h>
8 __RCSID("$NetBSD: output.c,v 1.10 2013/12/30 19:08:55 christos Exp $");
9 
10 #define StaticOrR	(rflag ? "" : "static ")
11 #define CountLine(fp)   (!rflag || ((fp) == code_file))
12 
13 static int nvectors;
14 static int nentries;
15 static Value_t **froms;
16 static Value_t **tos;
17 static Value_t *tally;
18 static Value_t *width;
19 static Value_t *state_count;
20 static Value_t *order;
21 static Value_t *base;
22 static Value_t *pos;
23 static int maxtable;
24 static Value_t *table;
25 static Value_t *check;
26 static int lowzero;
27 static int high;
28 
29 static void
30 putc_code(FILE * fp, int c)
31 {
32     if ((c == '\n') && (fp == code_file))
33 	++outline;
34     putc(c, fp);
35 }
36 
37 static void
38 putl_code(FILE * fp, const char *s)
39 {
40     if (fp == code_file)
41 	++outline;
42     fputs(s, fp);
43 }
44 
45 static void
46 puts_code(FILE * fp, const char *s)
47 {
48     fputs(s, fp);
49 }
50 
51 static void
52 write_code_lineno(FILE * fp)
53 {
54     if (!lflag && (fp == code_file))
55     {
56 	++outline;
57 	fprintf(fp, line_format, outline, code_file_name);
58     }
59 }
60 
61 static void
62 write_input_lineno(void)
63 {
64     if (!lflag)
65     {
66 	++outline;
67 	fprintf(code_file, line_format, lineno, input_file_name);
68     }
69 }
70 
71 static void
72 define_prefixed(FILE * fp, const char *name)
73 {
74     int bump_line = CountLine(fp);
75     if (bump_line)
76 	++outline;
77     fprintf(fp, "\n");
78 
79     if (bump_line)
80 	++outline;
81     fprintf(fp, "#ifndef %s\n", name);
82 
83     if (bump_line)
84 	++outline;
85     fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2);
86 
87     if (bump_line)
88 	++outline;
89     fprintf(fp, "#endif /* %s */\n", name);
90 }
91 
92 static void
93 output_prefix(FILE * fp)
94 {
95     if (symbol_prefix == NULL)
96     {
97 	symbol_prefix = "yy";
98     }
99     else
100     {
101 	define_prefixed(fp, "yyparse");
102 	define_prefixed(fp, "yylex");
103 	define_prefixed(fp, "yyerror");
104 	define_prefixed(fp, "yychar");
105 	define_prefixed(fp, "yyval");
106 	define_prefixed(fp, "yylval");
107 	define_prefixed(fp, "yydebug");
108 	define_prefixed(fp, "yynerrs");
109 	define_prefixed(fp, "yyerrflag");
110 	define_prefixed(fp, "yylhs");
111 	define_prefixed(fp, "yylen");
112 	define_prefixed(fp, "yydefred");
113 	define_prefixed(fp, "yydgoto");
114 	define_prefixed(fp, "yysindex");
115 	define_prefixed(fp, "yyrindex");
116 	define_prefixed(fp, "yygindex");
117 	define_prefixed(fp, "yytable");
118 	define_prefixed(fp, "yycheck");
119 	define_prefixed(fp, "yytname");
120 	define_prefixed(fp, "yyrule");
121     }
122     if (CountLine(fp))
123 	++outline;
124     fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix);
125 }
126 
127 static void
128 output_newline(void)
129 {
130     if (!rflag)
131 	++outline;
132     putc('\n', output_file);
133 }
134 
135 static void
136 output_line(const char *value)
137 {
138     fputs(value, output_file);
139     output_newline();
140 }
141 
142 static void
143 output_int(int value)
144 {
145     fprintf(output_file, "%5d,", value);
146 }
147 
148 static void
149 start_int_table(const char *name, int value)
150 {
151     int need = 34 - (int)(strlen(symbol_prefix) + strlen(name));
152 
153     if (need < 6)
154 	need = 6;
155     fprintf(output_file,
156 	    "%sconst short %s%s[] = {%*d,",
157 	    StaticOrR, symbol_prefix, name, need, value);
158 }
159 
160 static void
161 start_str_table(const char *name)
162 {
163     fprintf(output_file,
164 	    "%sconst char *%s%s[] = {",
165 	    StaticOrR, "yy", name);
166     output_newline();
167 }
168 
169 static void
170 end_table(void)
171 {
172     output_newline();
173     output_line("};");
174 }
175 
176 static void
177 output_rule_data(void)
178 {
179     int i;
180     int j;
181 
182     start_int_table("lhs", symbol_value[start_symbol]);
183 
184     j = 10;
185     for (i = 3; i < nrules; i++)
186     {
187 	if (j >= 10)
188 	{
189 	    output_newline();
190 	    j = 1;
191 	}
192 	else
193 	    ++j;
194 
195 	output_int(symbol_value[rlhs[i]]);
196     }
197     end_table();
198 
199     start_int_table("len", 2);
200 
201     j = 10;
202     for (i = 3; i < nrules; i++)
203     {
204 	if (j >= 10)
205 	{
206 	    output_newline();
207 	    j = 1;
208 	}
209 	else
210 	    j++;
211 
212 	output_int(rrhs[i + 1] - rrhs[i] - 1);
213     }
214     end_table();
215 }
216 
217 static void
218 output_yydefred(void)
219 {
220     int i, j;
221 
222     start_int_table("defred", (defred[0] ? defred[0] - 2 : 0));
223 
224     j = 10;
225     for (i = 1; i < nstates; i++)
226     {
227 	if (j < 10)
228 	    ++j;
229 	else
230 	{
231 	    output_newline();
232 	    j = 1;
233 	}
234 
235 	output_int((defred[i] ? defred[i] - 2 : 0));
236     }
237 
238     end_table();
239 }
240 
241 static void
242 token_actions(void)
243 {
244     int i, j;
245     Value_t shiftcount, reducecount;
246     int max, min;
247     Value_t *actionrow, *r, *s;
248     action *p;
249 
250     actionrow = NEW2(2 * ntokens, Value_t);
251     for (i = 0; i < nstates; ++i)
252     {
253 	if (parser[i])
254 	{
255 	    for (j = 0; j < 2 * ntokens; ++j)
256 		actionrow[j] = 0;
257 
258 	    shiftcount = 0;
259 	    reducecount = 0;
260 	    for (p = parser[i]; p; p = p->next)
261 	    {
262 		if (p->suppressed == 0)
263 		{
264 		    if (p->action_code == SHIFT)
265 		    {
266 			++shiftcount;
267 			actionrow[p->symbol] = p->number;
268 		    }
269 		    else if (p->action_code == REDUCE && p->number != defred[i])
270 		    {
271 			++reducecount;
272 			actionrow[p->symbol + ntokens] = p->number;
273 		    }
274 		}
275 	    }
276 
277 	    tally[i] = shiftcount;
278 	    tally[nstates + i] = reducecount;
279 	    width[i] = 0;
280 	    width[nstates + i] = 0;
281 	    if (shiftcount > 0)
282 	    {
283 		froms[i] = r = NEW2(shiftcount, Value_t);
284 		tos[i] = s = NEW2(shiftcount, Value_t);
285 		min = MAXSHORT;
286 		max = 0;
287 		for (j = 0; j < ntokens; ++j)
288 		{
289 		    if (actionrow[j])
290 		    {
291 			if (min > symbol_value[j])
292 			    min = symbol_value[j];
293 			if (max < symbol_value[j])
294 			    max = symbol_value[j];
295 			*r++ = symbol_value[j];
296 			*s++ = actionrow[j];
297 		    }
298 		}
299 		width[i] = (Value_t) (max - min + 1);
300 	    }
301 	    if (reducecount > 0)
302 	    {
303 		froms[nstates + i] = r = NEW2(reducecount, Value_t);
304 		tos[nstates + i] = s = NEW2(reducecount, Value_t);
305 		min = MAXSHORT;
306 		max = 0;
307 		for (j = 0; j < ntokens; ++j)
308 		{
309 		    if (actionrow[ntokens + j])
310 		    {
311 			if (min > symbol_value[j])
312 			    min = symbol_value[j];
313 			if (max < symbol_value[j])
314 			    max = symbol_value[j];
315 			*r++ = symbol_value[j];
316 			*s++ = (Value_t) (actionrow[ntokens + j] - 2);
317 		    }
318 		}
319 		width[nstates + i] = (Value_t) (max - min + 1);
320 	    }
321 	}
322     }
323     FREE(actionrow);
324 }
325 
326 static int
327 default_goto(int symbol)
328 {
329     int i;
330     int m;
331     int n;
332     int default_state;
333     int max;
334 
335     m = goto_map[symbol];
336     n = goto_map[symbol + 1];
337 
338     if (m == n)
339 	return (0);
340 
341     for (i = 0; i < nstates; i++)
342 	state_count[i] = 0;
343 
344     for (i = m; i < n; i++)
345 	state_count[to_state[i]]++;
346 
347     max = 0;
348     default_state = 0;
349     for (i = 0; i < nstates; i++)
350     {
351 	if (state_count[i] > max)
352 	{
353 	    max = state_count[i];
354 	    default_state = i;
355 	}
356     }
357 
358     return (default_state);
359 }
360 
361 static void
362 save_column(int symbol, int default_state)
363 {
364     int i;
365     int m;
366     int n;
367     Value_t *sp;
368     Value_t *sp1;
369     Value_t *sp2;
370     Value_t count;
371     int symno;
372 
373     m = goto_map[symbol];
374     n = goto_map[symbol + 1];
375 
376     count = 0;
377     for (i = m; i < n; i++)
378     {
379 	if (to_state[i] != default_state)
380 	    ++count;
381     }
382     if (count == 0)
383 	return;
384 
385     symno = symbol_value[symbol] + 2 * nstates;
386 
387     froms[symno] = sp1 = sp = NEW2(count, Value_t);
388     tos[symno] = sp2 = NEW2(count, Value_t);
389 
390     for (i = m; i < n; i++)
391     {
392 	if (to_state[i] != default_state)
393 	{
394 	    *sp1++ = from_state[i];
395 	    *sp2++ = to_state[i];
396 	}
397     }
398 
399     tally[symno] = count;
400     width[symno] = (Value_t) (sp1[-1] - sp[0] + 1);
401 }
402 
403 static void
404 goto_actions(void)
405 {
406     int i, j, k;
407 
408     state_count = NEW2(nstates, Value_t);
409 
410     k = default_goto(start_symbol + 1);
411     start_int_table("dgoto", k);
412     save_column(start_symbol + 1, k);
413 
414     j = 10;
415     for (i = start_symbol + 2; i < nsyms; i++)
416     {
417 	if (j >= 10)
418 	{
419 	    output_newline();
420 	    j = 1;
421 	}
422 	else
423 	    ++j;
424 
425 	k = default_goto(i);
426 	output_int(k);
427 	save_column(i, k);
428     }
429 
430     end_table();
431     FREE(state_count);
432 }
433 
434 static void
435 sort_actions(void)
436 {
437     Value_t i;
438     int j;
439     int k;
440     int t;
441     int w;
442 
443     order = NEW2(nvectors, Value_t);
444     nentries = 0;
445 
446     for (i = 0; i < nvectors; i++)
447     {
448 	if (tally[i] > 0)
449 	{
450 	    t = tally[i];
451 	    w = width[i];
452 	    j = nentries - 1;
453 
454 	    while (j >= 0 && (width[order[j]] < w))
455 		j--;
456 
457 	    while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
458 		j--;
459 
460 	    for (k = nentries - 1; k > j; k--)
461 		order[k + 1] = order[k];
462 
463 	    order[j + 1] = i;
464 	    nentries++;
465 	}
466     }
467 }
468 
469 /*  The function matching_vector determines if the vector specified by	*/
470 /*  the input parameter matches a previously considered	vector.  The	*/
471 /*  test at the start of the function checks if the vector represents	*/
472 /*  a row of shifts over terminal symbols or a row of reductions, or a	*/
473 /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not	*/
474 /*  check if a column of shifts over a nonterminal symbols matches a	*/
475 /*  previously considered vector.  Because of the nature of LR parsing	*/
476 /*  tables, no two columns can match.  Therefore, the only possible	*/
477 /*  match would be between a row and a column.  Such matches are	*/
478 /*  unlikely.  Therefore, to save time, no attempt is made to see if a	*/
479 /*  column matches a previously considered vector.			*/
480 /*									*/
481 /*  Matching_vector is poorly designed.  The test could easily be made	*/
482 /*  faster.  Also, it depends on the vectors being in a specific	*/
483 /*  order.								*/
484 
485 static int
486 matching_vector(int vector)
487 {
488     int i;
489     int j;
490     int k;
491     int t;
492     int w;
493     int match;
494     int prev;
495 
496     i = order[vector];
497     if (i >= 2 * nstates)
498 	return (-1);
499 
500     t = tally[i];
501     w = width[i];
502 
503     for (prev = vector - 1; prev >= 0; prev--)
504     {
505 	j = order[prev];
506 	if (width[j] != w || tally[j] != t)
507 	    return (-1);
508 
509 	match = 1;
510 	for (k = 0; match && k < t; k++)
511 	{
512 	    if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
513 		match = 0;
514 	}
515 
516 	if (match)
517 	    return (j);
518     }
519 
520     return (-1);
521 }
522 
523 static int
524 pack_vector(int vector)
525 {
526     int i, j, k, l;
527     int t;
528     int loc;
529     int ok;
530     Value_t *from;
531     Value_t *to;
532     int newmax;
533 
534     i = order[vector];
535     t = tally[i];
536     assert(t);
537 
538     from = froms[i];
539     to = tos[i];
540 
541     j = lowzero - from[0];
542     for (k = 1; k < t; ++k)
543 	if (lowzero - from[k] > j)
544 	    j = lowzero - from[k];
545     for (;; ++j)
546     {
547 	if (j == 0)
548 	    continue;
549 	ok = 1;
550 	for (k = 0; ok && k < t; k++)
551 	{
552 	    loc = j + from[k];
553 	    if (loc >= maxtable - 1)
554 	    {
555 		if (loc >= MAXTABLE - 1)
556 		    fatal("maximum table size exceeded");
557 
558 		newmax = maxtable;
559 		do
560 		{
561 		    newmax += 200;
562 		}
563 		while (newmax <= loc);
564 
565 		table = TREALLOC(Value_t, table, newmax);
566 		NO_SPACE(table);
567 
568 		check = TREALLOC(Value_t, check, newmax);
569 		NO_SPACE(check);
570 
571 		for (l = maxtable; l < newmax; ++l)
572 		{
573 		    table[l] = 0;
574 		    check[l] = -1;
575 		}
576 		maxtable = newmax;
577 	    }
578 
579 	    if (check[loc] != -1)
580 		ok = 0;
581 	}
582 	for (k = 0; ok && k < vector; k++)
583 	{
584 	    if (pos[k] == j)
585 		ok = 0;
586 	}
587 	if (ok)
588 	{
589 	    for (k = 0; k < t; k++)
590 	    {
591 		loc = j + from[k];
592 		table[loc] = to[k];
593 		check[loc] = from[k];
594 		if (loc > high)
595 		    high = loc;
596 	    }
597 
598 	    while (check[lowzero] != -1)
599 		++lowzero;
600 
601 	    return (j);
602 	}
603     }
604 }
605 
606 static void
607 pack_table(void)
608 {
609     int i;
610     Value_t place;
611     int state;
612 
613     base = NEW2(nvectors, Value_t);
614     pos = NEW2(nentries, Value_t);
615 
616     maxtable = 1000;
617     table = NEW2(maxtable, Value_t);
618     check = NEW2(maxtable, Value_t);
619 
620     lowzero = 0;
621     high = 0;
622 
623     for (i = 0; i < maxtable; i++)
624 	check[i] = -1;
625 
626     for (i = 0; i < nentries; i++)
627     {
628 	state = matching_vector(i);
629 
630 	if (state < 0)
631 	    place = (Value_t) pack_vector(i);
632 	else
633 	    place = base[state];
634 
635 	pos[i] = place;
636 	base[order[i]] = place;
637     }
638 
639     for (i = 0; i < nvectors; i++)
640     {
641 	if (froms[i])
642 	    FREE(froms[i]);
643 	if (tos[i])
644 	    FREE(tos[i]);
645     }
646 
647     FREE(froms);
648     FREE(tos);
649     FREE(pos);
650 }
651 
652 static void
653 output_base(void)
654 {
655     int i, j;
656 
657     start_int_table("sindex", base[0]);
658 
659     j = 10;
660     for (i = 1; i < nstates; i++)
661     {
662 	if (j >= 10)
663 	{
664 	    output_newline();
665 	    j = 1;
666 	}
667 	else
668 	    ++j;
669 
670 	output_int(base[i]);
671     }
672 
673     end_table();
674 
675     start_int_table("rindex", base[nstates]);
676 
677     j = 10;
678     for (i = nstates + 1; i < 2 * nstates; i++)
679     {
680 	if (j >= 10)
681 	{
682 	    output_newline();
683 	    j = 1;
684 	}
685 	else
686 	    ++j;
687 
688 	output_int(base[i]);
689     }
690 
691     end_table();
692 
693     start_int_table("gindex", base[2 * nstates]);
694 
695     j = 10;
696     for (i = 2 * nstates + 1; i < nvectors - 1; i++)
697     {
698 	if (j >= 10)
699 	{
700 	    output_newline();
701 	    j = 1;
702 	}
703 	else
704 	    ++j;
705 
706 	output_int(base[i]);
707     }
708 
709     end_table();
710     FREE(base);
711 }
712 
713 static void
714 output_table(void)
715 {
716     int i;
717     int j;
718 
719     ++outline;
720     fprintf(code_file, "#define YYTABLESIZE %d\n", high);
721     start_int_table("table", table[0]);
722 
723     j = 10;
724     for (i = 1; i <= high; i++)
725     {
726 	if (j >= 10)
727 	{
728 	    output_newline();
729 	    j = 1;
730 	}
731 	else
732 	    ++j;
733 
734 	output_int(table[i]);
735     }
736 
737     end_table();
738     FREE(table);
739 }
740 
741 static void
742 output_check(void)
743 {
744     int i;
745     int j;
746 
747     start_int_table("check", check[0]);
748 
749     j = 10;
750     for (i = 1; i <= high; i++)
751     {
752 	if (j >= 10)
753 	{
754 	    output_newline();
755 	    j = 1;
756 	}
757 	else
758 	    ++j;
759 
760 	output_int(check[i]);
761     }
762 
763     end_table();
764     FREE(check);
765 }
766 
767 static void
768 output_actions(void)
769 {
770     nvectors = 2 * nstates + nvars;
771 
772     froms = NEW2(nvectors, Value_t *);
773     tos = NEW2(nvectors, Value_t *);
774     tally = NEW2(nvectors, Value_t);
775     width = NEW2(nvectors, Value_t);
776 
777     token_actions();
778     FREE(lookaheads);
779     FREE(LA);
780     FREE(LAruleno);
781     FREE(accessing_symbol);
782 
783     goto_actions();
784     FREE(goto_map + ntokens);
785     FREE(from_state);
786     FREE(to_state);
787 
788     sort_actions();
789     pack_table();
790     output_base();
791     output_table();
792     output_check();
793 }
794 
795 static int
796 is_C_identifier(char *name)
797 {
798     char *s;
799     int c;
800 
801     s = name;
802     c = *s;
803     if (c == '"')
804     {
805 	c = *++s;
806 	if (!isalpha(c) && c != '_' && c != '$')
807 	    return (0);
808 	while ((c = *++s) != '"')
809 	{
810 	    if (!isalnum(c) && c != '_' && c != '$')
811 		return (0);
812 	}
813 	return (1);
814     }
815 
816     if (!isalpha(c) && c != '_' && c != '$')
817 	return (0);
818     while ((c = *++s) != 0)
819     {
820 	if (!isalnum(c) && c != '_' && c != '$')
821 	    return (0);
822     }
823     return (1);
824 }
825 
826 static void
827 output_defines(FILE * fp)
828 {
829     int c, i;
830     char *s;
831 
832     for (i = 2; i < ntokens; ++i)
833     {
834 	s = symbol_name[i];
835 	if (is_C_identifier(s) && (!sflag || *s != '"'))
836 	{
837 	    fprintf(fp, "#define ");
838 	    c = *s;
839 	    if (c == '"')
840 	    {
841 		while ((c = *++s) != '"')
842 		{
843 		    putc(c, fp);
844 		}
845 	    }
846 	    else
847 	    {
848 		do
849 		{
850 		    putc(c, fp);
851 		}
852 		while ((c = *++s) != 0);
853 	    }
854 	    if (fp == code_file)
855 		++outline;
856 	    fprintf(fp, " %d\n", symbol_value[i]);
857 	}
858     }
859 
860     if (fp == code_file)
861 	++outline;
862     if (fp != defines_file || iflag)
863 	fprintf(fp, "#define YYERRCODE %d\n", symbol_value[1]);
864 
865     if (fp == defines_file || (iflag && !dflag))
866     {
867 	if (unionized)
868 	{
869 	    if (union_file != 0)
870 	    {
871 		rewind(union_file);
872 		while ((c = getc(union_file)) != EOF)
873 		    putc(c, fp);
874 	    }
875 	    fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix);
876 	}
877     }
878 }
879 
880 static void
881 output_stored_text(FILE * fp)
882 {
883     int c;
884     FILE *in;
885 
886     rewind(text_file);
887     if (text_file == NULL)
888 	open_error("text_file");
889     in = text_file;
890     if ((c = getc(in)) == EOF)
891 	return;
892     putc_code(fp, c);
893     while ((c = getc(in)) != EOF)
894     {
895 	putc_code(fp, c);
896     }
897     write_code_lineno(fp);
898 }
899 
900 static void
901 output_debug(void)
902 {
903     int i, j, k, max;
904     const char **symnam;
905     const char *s;
906 
907     ++outline;
908     fprintf(code_file, "#define YYFINAL %d\n", final_state);
909 
910     putl_code(code_file, "#ifndef YYDEBUG\n");
911     ++outline;
912     fprintf(code_file, "#define YYDEBUG %d\n", tflag);
913     putl_code(code_file, "#endif\n");
914 
915     if (rflag)
916     {
917 	fprintf(output_file, "#ifndef YYDEBUG\n");
918 	fprintf(output_file, "#define YYDEBUG %d\n", tflag);
919 	fprintf(output_file, "#endif\n");
920     }
921 
922     max = 0;
923     for (i = 2; i < ntokens; ++i)
924 	if (symbol_value[i] > max)
925 	    max = symbol_value[i];
926 
927     ++outline;
928     fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
929     fprintf(code_file, "#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? "
930 	"(YYMAXTOKEN + 1) : (a))\n");
931 
932     symnam = TMALLOC(const char *, max + 2);
933     NO_SPACE(symnam);
934 
935     /* Note that it is  not necessary to initialize the element         */
936     /* symnam[max].                                                     */
937     for (i = 0; i <= max; ++i)
938 	symnam[i] = 0;
939     for (i = ntokens - 1; i >= 2; --i)
940 	symnam[symbol_value[i]] = symbol_name[i];
941     symnam[0] = "end-of-file";
942     symnam[max + 1] = "illegal-token";
943 
944     if (!token_table)
945 	output_line("#if YYDEBUG");
946 
947     start_str_table("tname");
948     j = 80;
949     for (i = 0; i <= max + 1; ++i)
950     {
951 	if ((s = symnam[i]) != 0)
952 	{
953 	    if (s[0] == '"')
954 	    {
955 		k = 7;
956 		while (*++s != '"')
957 		{
958 		    ++k;
959 		    if (*s == '\\')
960 		    {
961 			k += 2;
962 			if (*++s == '\\')
963 			    ++k;
964 		    }
965 		}
966 		j += k;
967 		if (j > 80)
968 		{
969 		    output_newline();
970 		    j = k;
971 		}
972 		fprintf(output_file, "\"\\\"");
973 		s = symnam[i];
974 		while (*++s != '"')
975 		{
976 		    if (*s == '\\')
977 		    {
978 			fprintf(output_file, "\\\\");
979 			if (*++s == '\\')
980 			    fprintf(output_file, "\\\\");
981 			else
982 			    putc(*s, output_file);
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 		{
993 		    j += 7;
994 		    if (j > 80)
995 		    {
996 			output_newline();
997 			j = 7;
998 		    }
999 		    fprintf(output_file, "\"'\\\"'\",");
1000 		}
1001 		else
1002 		{
1003 		    k = 5;
1004 		    while (*++s != '\'')
1005 		    {
1006 			++k;
1007 			if (*s == '\\')
1008 			{
1009 			    k += 2;
1010 			    if (*++s == '\\')
1011 				++k;
1012 			}
1013 		    }
1014 		    j += k;
1015 		    if (j > 80)
1016 		    {
1017 			output_newline();
1018 			j = k;
1019 		    }
1020 		    fprintf(output_file, "\"'");
1021 		    s = symnam[i];
1022 		    while (*++s != '\'')
1023 		    {
1024 			if (*s == '\\')
1025 			{
1026 			    fprintf(output_file, "\\\\");
1027 			    if (*++s == '\\')
1028 				fprintf(output_file, "\\\\");
1029 			    else
1030 				putc(*s, output_file);
1031 			}
1032 			else
1033 			    putc(*s, output_file);
1034 		    }
1035 		    fprintf(output_file, "'\",");
1036 		}
1037 	    }
1038 	    else
1039 	    {
1040 		k = (int)strlen(s) + 3;
1041 		j += k;
1042 		if (j > 80)
1043 		{
1044 		    output_newline();
1045 		    j = k;
1046 		}
1047 		putc('"', output_file);
1048 		do
1049 		{
1050 		    putc(*s, output_file);
1051 		}
1052 		while (*++s);
1053 		fprintf(output_file, "\",");
1054 	    }
1055 	}
1056 	else
1057 	{
1058 	    j += 2;
1059 	    if (j > 80)
1060 	    {
1061 		output_newline();
1062 		j = 2;
1063 	    }
1064 	    fprintf(output_file, "0,");
1065 	}
1066     }
1067     end_table();
1068     FREE(symnam);
1069 
1070     if (token_table)
1071 	output_line("#if YYDEBUG");
1072     start_str_table("rule");
1073     for (i = 2; i < nrules; ++i)
1074     {
1075 	fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1076 	for (j = rrhs[i]; ritem[j] > 0; ++j)
1077 	{
1078 	    s = symbol_name[ritem[j]];
1079 	    if (s[0] == '"')
1080 	    {
1081 		fprintf(output_file, " \\\"");
1082 		while (*++s != '"')
1083 		{
1084 		    if (*s == '\\')
1085 		    {
1086 			if (s[1] == '\\')
1087 			    fprintf(output_file, "\\\\\\\\");
1088 			else
1089 			    fprintf(output_file, "\\\\%c", s[1]);
1090 			++s;
1091 		    }
1092 		    else
1093 			putc(*s, output_file);
1094 		}
1095 		fprintf(output_file, "\\\"");
1096 	    }
1097 	    else if (s[0] == '\'')
1098 	    {
1099 		if (s[1] == '"')
1100 		    fprintf(output_file, " '\\\"'");
1101 		else if (s[1] == '\\')
1102 		{
1103 		    if (s[2] == '\\')
1104 			fprintf(output_file, " '\\\\\\\\");
1105 		    else
1106 			fprintf(output_file, " '\\\\%c", s[2]);
1107 		    s += 2;
1108 		    while (*++s != '\'')
1109 			putc(*s, output_file);
1110 		    putc('\'', output_file);
1111 		}
1112 		else
1113 		    fprintf(output_file, " '%c'", s[1]);
1114 	    }
1115 	    else
1116 		fprintf(output_file, " %s", s);
1117 	}
1118 	fprintf(output_file, "\",");
1119 	output_newline();
1120     }
1121 
1122     end_table();
1123     output_line("#endif");
1124 }
1125 
1126 static void
1127 output_pure_parser(FILE * fp)
1128 {
1129     putc_code(fp, '\n');
1130 
1131     if (fp == code_file)
1132 	outline += 1;
1133     fprintf(fp, "#define YYPURE %d\n", pure_parser);
1134     putc_code(fp, '\n');
1135 }
1136 
1137 static void
1138 output_stype(FILE * fp)
1139 {
1140     if (!unionized && ntags == 0)
1141     {
1142 	putc_code(fp, '\n');
1143 	putl_code(fp, "#ifndef YYSTYPE\n");
1144 	putl_code(fp, "typedef int YYSTYPE;\n");
1145 	putl_code(fp, "#endif\n");
1146     }
1147 }
1148 
1149 static void
1150 output_trailing_text(void)
1151 {
1152     int c, last;
1153     FILE *in;
1154 
1155     if (line == 0)
1156 	return;
1157 
1158     in = input_file;
1159     c = *cptr;
1160     if (c == '\n')
1161     {
1162 	++lineno;
1163 	if ((c = getc(in)) == EOF)
1164 	    return;
1165 	write_input_lineno();
1166 	putc_code(code_file, c);
1167 	last = c;
1168     }
1169     else
1170     {
1171 	write_input_lineno();
1172 	do
1173 	{
1174 	    putc_code(code_file, c);
1175 	}
1176 	while ((c = *++cptr) != '\n');
1177 	putc_code(code_file, c);
1178 	last = '\n';
1179     }
1180 
1181     while ((c = getc(in)) != EOF)
1182     {
1183 	putc_code(code_file, c);
1184 	last = c;
1185     }
1186 
1187     if (last != '\n')
1188     {
1189 	putc_code(code_file, '\n');
1190     }
1191     write_code_lineno(code_file);
1192 }
1193 
1194 static void
1195 output_semantic_actions(void)
1196 {
1197     int c, last;
1198 
1199     rewind(action_file);
1200     if ((c = getc(action_file)) == EOF)
1201 	return;
1202 
1203     last = c;
1204     putc_code(code_file, c);
1205     while ((c = getc(action_file)) != EOF)
1206     {
1207 	putc_code(code_file, c);
1208 	last = c;
1209     }
1210 
1211     if (last != '\n')
1212     {
1213 	putc_code(code_file, '\n');
1214     }
1215 
1216     write_code_lineno(code_file);
1217 }
1218 
1219 static void
1220 output_parse_decl(FILE * fp)
1221 {
1222     putl_code(fp, "\n");
1223     putl_code(fp, "/* compatibility with bison */\n");
1224     putl_code(fp, "#ifdef YYPARSE_PARAM\n");
1225     putl_code(fp, "/* compatibility with FreeBSD */\n");
1226     putl_code(fp, "# ifdef YYPARSE_PARAM_TYPE\n");
1227     putl_code(fp,
1228 	      "#  define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n");
1229     putl_code(fp, "# else\n");
1230     putl_code(fp, "#  define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n");
1231     putl_code(fp, "# endif\n");
1232     putl_code(fp, "#else\n");
1233 
1234     puts_code(fp, "# define YYPARSE_DECL() yyparse(");
1235     if (!parse_param)
1236 	puts_code(fp, "void");
1237     else
1238     {
1239 	param *p;
1240 	for (p = parse_param; p; p = p->next)
1241 	    fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1242 		    p->next ? ", " : "");
1243     }
1244     putl_code(fp, ")\n");
1245 
1246     putl_code(fp, "#endif\n");
1247 }
1248 
1249 static void
1250 output_lex_decl(FILE * fp)
1251 {
1252     putl_code(fp, "\n");
1253     putl_code(fp, "/* Parameters sent to lex. */\n");
1254     putl_code(fp, "#ifdef YYLEX_PARAM\n");
1255     if (pure_parser)
1256     {
1257 	putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n");
1258 	putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1259 		  " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1260 	putl_code(fp, "# else\n");
1261 	putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1262 		  " void * YYLEX_PARAM)\n");
1263 	putl_code(fp, "# endif\n");
1264 	putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
1265     }
1266     else
1267     {
1268 	putl_code(fp, "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n");
1269 	putl_code(fp, "# define YYLEX yylex(YYLEX_PARAM)\n");
1270     }
1271     putl_code(fp, "#else\n");
1272     if (pure_parser && lex_param)
1273     {
1274 	param *p;
1275 	puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
1276 	for (p = lex_param; p; p = p->next)
1277 	    fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1278 		    p->next ? ", " : "");
1279 	putl_code(fp, ")\n");
1280 
1281 	puts_code(fp, "# define YYLEX yylex(&yylval, ");
1282 	for (p = lex_param; p; p = p->next)
1283 	    fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
1284 	putl_code(fp, ")\n");
1285     }
1286     else if (pure_parser)
1287     {
1288 	putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
1289 	putl_code(fp, "# define YYLEX yylex(&yylval)\n");
1290     }
1291     else if (lex_param)
1292     {
1293 	param *p;
1294 	puts_code(fp, "# define YYLEX_DECL() yylex(");
1295 	for (p = lex_param; p; p = p->next)
1296 	    fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1297 		    p->next ? ", " : "");
1298 	putl_code(fp, ")\n");
1299 
1300 	puts_code(fp, "# define YYLEX yylex(");
1301 	for (p = lex_param; p; p = p->next)
1302 	    fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
1303 	putl_code(fp, ")\n");
1304     }
1305     else
1306     {
1307 	putl_code(fp, "# define YYLEX_DECL() yylex(void)\n");
1308 	putl_code(fp, "# define YYLEX yylex()\n");
1309     }
1310     putl_code(fp, "#endif\n");
1311 }
1312 
1313 static void
1314 output_error_decl(FILE * fp)
1315 {
1316     putl_code(fp, "\n");
1317     putl_code(fp, "/* Parameters sent to yyerror. */\n");
1318     if (parse_param)
1319     {
1320 	param *p;
1321 
1322 	putl_code(fp, "#ifndef YYERROR_DECL\n");
1323 	fprintf(fp, "#define YYERROR_DECL() yyerror(");
1324 	for (p = parse_param; p; p = p->next)
1325 	    fprintf(fp, "%s %s%s, ", p->type, p->name, p->type2);
1326 	putl_code(fp, "const char *s)\n");
1327 	putl_code(fp, "#endif\n");
1328 
1329 	putl_code(fp, "#ifndef YYERROR_CALL\n");
1330 	puts_code(fp, "#define YYERROR_CALL(msg) yyerror(");
1331 
1332 	for (p = parse_param; p; p = p->next)
1333 	    fprintf(fp, "%s, ", p->name);
1334 
1335 	putl_code(fp, "msg)\n");
1336 	putl_code(fp, "#endif\n");
1337     }
1338     else
1339     {
1340 	putl_code(fp, "#ifndef YYERROR_DECL\n");
1341 	putl_code(fp, "#define YYERROR_DECL() yyerror(const char *s)\n");
1342 	putl_code(fp, "#endif\n");
1343 	putl_code(fp, "#ifndef YYERROR_CALL\n");
1344 	putl_code(fp, "#define YYERROR_CALL(msg) yyerror(msg)\n");
1345 	putl_code(fp, "#endif\n");
1346     }
1347 }
1348 
1349 static void
1350 free_itemsets(void)
1351 {
1352     core *cp, *next;
1353 
1354     FREE(state_table);
1355     for (cp = first_state; cp; cp = next)
1356     {
1357 	next = cp->next;
1358 	FREE(cp);
1359     }
1360 }
1361 
1362 static void
1363 free_shifts(void)
1364 {
1365     shifts *sp, *next;
1366 
1367     FREE(shift_table);
1368     for (sp = first_shift; sp; sp = next)
1369     {
1370 	next = sp->next;
1371 	FREE(sp);
1372     }
1373 }
1374 
1375 static void
1376 free_reductions(void)
1377 {
1378     reductions *rp, *next;
1379 
1380     FREE(reduction_table);
1381     for (rp = first_reduction; rp; rp = next)
1382     {
1383 	next = rp->next;
1384 	FREE(rp);
1385     }
1386 }
1387 
1388 static void
1389 output_yyerror_call(const char *msg)
1390 {
1391     FILE *fp = code_file;
1392 
1393     puts_code(fp, "    yyerror(");
1394     if (parse_param)
1395     {
1396 	param *p;
1397 	for (p = parse_param; p; p = p->next)
1398 	    fprintf(fp, "%s, ", p->name);
1399     }
1400     puts_code(fp, "\"");
1401     puts_code(fp, msg);
1402     putl_code(fp, "\");\n");
1403 }
1404 
1405 static void
1406 output_externs(FILE * fp, const char *const section[])
1407 {
1408     int c;
1409     int i;
1410     const char *s;
1411 
1412     for (i = 0; (s = section[i]) != 0; ++i)
1413     {
1414 	if (*s && *s != '#')
1415 	    fputs("extern\t", fp);
1416 	while ((c = *s) != 0)
1417 	{
1418 	    putc(c, fp);
1419 	    ++s;
1420 	}
1421 	if (fp == code_file)
1422 	    ++outline;
1423 	putc('\n', fp);
1424     }
1425 }
1426 
1427 void
1428 output(void)
1429 {
1430     FILE *fp;
1431 
1432     free_itemsets();
1433     free_shifts();
1434     free_reductions();
1435 
1436     if (iflag)
1437     {
1438 	++outline;
1439 	fprintf(code_file, "#include \"%s\"\n", externs_file_name);
1440 	fp = externs_file;
1441     }
1442     else
1443 	fp = code_file;
1444 
1445     output_prefix(iflag ? externs_file : output_file);
1446     output_pure_parser(fp);
1447     output_stored_text(fp);
1448     output_stype(fp);
1449     output_parse_decl(fp);
1450     output_lex_decl(fp);
1451     output_error_decl(fp);
1452     write_section(fp, xdecls);
1453 
1454     if (iflag)
1455     {
1456 	output_externs(externs_file, global_vars);
1457 	if (!pure_parser)
1458 	    output_externs(externs_file, impure_vars);
1459     }
1460 
1461     if (iflag)
1462     {
1463 	if (dflag)
1464 	{
1465 	    ++outline;
1466 	    fprintf(code_file, "#include \"%s\"\n", defines_file_name);
1467 	}
1468 	else
1469 	    output_defines(externs_file);
1470     }
1471     else
1472     {
1473 	putc_code(code_file, '\n');
1474 	output_defines(code_file);
1475     }
1476 
1477     if (dflag)
1478 	output_defines(defines_file);
1479 
1480     output_rule_data();
1481     output_yydefred();
1482     output_actions();
1483     free_parser();
1484     output_debug();
1485     if (rflag)
1486     {
1487 	output_prefix(code_file);
1488 	write_section(code_file, xdecls);
1489 	write_section(code_file, tables);
1490     }
1491     write_section(code_file, global_vars);
1492     if (!pure_parser)
1493     {
1494 	write_section(code_file, impure_vars);
1495     }
1496     write_section(code_file, hdr_defs);
1497     if (!pure_parser)
1498     {
1499 	write_section(code_file, hdr_vars);
1500     }
1501     output_trailing_text();
1502     write_section(code_file, body_1);
1503     if (pure_parser)
1504     {
1505 	write_section(code_file, body_vars);
1506     }
1507     write_section(code_file, body_2);
1508     output_yyerror_call("syntax error");
1509     write_section(code_file, body_3);
1510     output_semantic_actions();
1511     write_section(code_file, trailer);
1512     output_yyerror_call("yacc stack overflow");
1513     write_section(code_file, trailer_2);
1514 }
1515 
1516 #ifdef NO_LEAKS
1517 void
1518 output_leaks(void)
1519 {
1520     DO_FREE(tally);
1521     DO_FREE(width);
1522     DO_FREE(order);
1523 }
1524 #endif
1525