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