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