xref: /freebsd/contrib/byacc/output.c (revision 40a8ac8f62b535d30349faf28cf47106b7041b83)
1 /* $Id: output.c,v 1.67 2014/04/22 23:16:57 tom Exp $ */
2 
3 #include "defs.h"
4 
5 #define StaticOrR	(rflag ? "" : "static ")
6 #define CountLine(fp)   (!rflag || ((fp) == code_file))
7 
8 #if defined(YYBTYACC)
9 #define PER_STATE 3
10 #else
11 #define PER_STATE 2
12 #endif
13 
14 static int nvectors;
15 static int nentries;
16 static Value_t **froms;
17 static Value_t **tos;
18 #if defined(YYBTYACC)
19 static Value_t *conflicts = NULL;
20 static Value_t nconflicts = 0;
21 #endif
22 static Value_t *tally;
23 static Value_t *width;
24 static Value_t *state_count;
25 static Value_t *order;
26 static Value_t *base;
27 static Value_t *pos;
28 static int maxtable;
29 static Value_t *table;
30 static Value_t *check;
31 static int lowzero;
32 static long high;
33 
34 static void
35 putc_code(FILE * fp, int c)
36 {
37     if ((c == '\n') && (fp == code_file))
38 	++outline;
39     putc(c, fp);
40 }
41 
42 static void
43 putl_code(FILE * fp, const char *s)
44 {
45     if (fp == code_file)
46 	++outline;
47     fputs(s, fp);
48 }
49 
50 static void
51 puts_code(FILE * fp, const char *s)
52 {
53     fputs(s, fp);
54 }
55 
56 static void
57 write_code_lineno(FILE * fp)
58 {
59     if (!lflag && (fp == code_file))
60     {
61 	++outline;
62 	fprintf(fp, line_format, outline + 1, code_file_name);
63     }
64 }
65 
66 static void
67 write_input_lineno(void)
68 {
69     if (!lflag)
70     {
71 	++outline;
72 	fprintf(code_file, line_format, lineno, input_file_name);
73     }
74 }
75 
76 static void
77 define_prefixed(FILE * fp, const char *name)
78 {
79     int bump_line = CountLine(fp);
80     if (bump_line)
81 	++outline;
82     fprintf(fp, "\n");
83 
84     if (bump_line)
85 	++outline;
86     fprintf(fp, "#ifndef %s\n", name);
87 
88     if (bump_line)
89 	++outline;
90     fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2);
91 
92     if (bump_line)
93 	++outline;
94     fprintf(fp, "#endif /* %s */\n", name);
95 }
96 
97 static void
98 output_prefix(FILE * fp)
99 {
100     if (symbol_prefix == NULL)
101     {
102 	symbol_prefix = "yy";
103     }
104     else
105     {
106 	define_prefixed(fp, "yyparse");
107 	define_prefixed(fp, "yylex");
108 	define_prefixed(fp, "yyerror");
109 	define_prefixed(fp, "yychar");
110 	define_prefixed(fp, "yyval");
111 	define_prefixed(fp, "yylval");
112 	define_prefixed(fp, "yydebug");
113 	define_prefixed(fp, "yynerrs");
114 	define_prefixed(fp, "yyerrflag");
115 	define_prefixed(fp, "yylhs");
116 	define_prefixed(fp, "yylen");
117 	define_prefixed(fp, "yydefred");
118 #if defined(YYBTYACC)
119 	define_prefixed(fp, "yystos");
120 #endif
121 	define_prefixed(fp, "yydgoto");
122 	define_prefixed(fp, "yysindex");
123 	define_prefixed(fp, "yyrindex");
124 	define_prefixed(fp, "yygindex");
125 	define_prefixed(fp, "yytable");
126 	define_prefixed(fp, "yycheck");
127 	define_prefixed(fp, "yyname");
128 	define_prefixed(fp, "yyrule");
129 #if defined(YYBTYACC)
130 	if (locations)
131 	{
132 	    define_prefixed(fp, "yyloc");
133 	    define_prefixed(fp, "yylloc");
134 	}
135 	putc_code(fp, '\n');
136 	putl_code(fp, "#if YYBTYACC\n");
137 
138 	define_prefixed(fp, "yycindex");
139 	define_prefixed(fp, "yyctable");
140 
141 	putc_code(fp, '\n');
142 	putl_code(fp, "#endif /* YYBTYACC */\n");
143 	putc_code(fp, '\n');
144 #endif
145     }
146     if (CountLine(fp))
147 	++outline;
148     fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix);
149 }
150 
151 static void
152 output_newline(void)
153 {
154     if (!rflag)
155 	++outline;
156     putc('\n', output_file);
157 }
158 
159 static void
160 output_line(const char *value)
161 {
162     fputs(value, output_file);
163     output_newline();
164 }
165 
166 static void
167 output_int(int value)
168 {
169     fprintf(output_file, "%5d,", value);
170 }
171 
172 static void
173 start_int_table(const char *name, int value)
174 {
175     int need = 34 - (int)(strlen(symbol_prefix) + strlen(name));
176 
177     if (need < 6)
178 	need = 6;
179     fprintf(output_file,
180 	    "%sconst YYINT %s%s[] = {%*d,",
181 	    StaticOrR, symbol_prefix, name, need, value);
182 }
183 
184 static void
185 start_str_table(const char *name)
186 {
187     fprintf(output_file,
188 	    "%sconst char *const %s%s[] = {",
189 	    StaticOrR, symbol_prefix, name);
190     output_newline();
191 }
192 
193 static void
194 end_table(void)
195 {
196     output_newline();
197     output_line("};");
198 }
199 
200 static void
201 output_YYINT_typedef(FILE * fp)
202 {
203     /* generate the type used to index the various parser tables */
204     if (CountLine(fp))
205 	++outline;
206     fprintf(fp, "typedef %s YYINT;\n", CONCAT1("", YYINT));
207 }
208 
209 static void
210 output_rule_data(void)
211 {
212     int i;
213     int j;
214 
215     output_YYINT_typedef(output_file);
216 
217     start_int_table("lhs", symbol_value[start_symbol]);
218 
219     j = 10;
220     for (i = 3; i < nrules; i++)
221     {
222 	if (j >= 10)
223 	{
224 	    output_newline();
225 	    j = 1;
226 	}
227 	else
228 	    ++j;
229 
230 	output_int(symbol_value[rlhs[i]]);
231     }
232     end_table();
233 
234     start_int_table("len", 2);
235 
236     j = 10;
237     for (i = 3; i < nrules; i++)
238     {
239 	if (j >= 10)
240 	{
241 	    output_newline();
242 	    j = 1;
243 	}
244 	else
245 	    j++;
246 
247 	output_int(rrhs[i + 1] - rrhs[i] - 1);
248     }
249     end_table();
250 }
251 
252 static void
253 output_yydefred(void)
254 {
255     int i, j;
256 
257     start_int_table("defred", (defred[0] ? defred[0] - 2 : 0));
258 
259     j = 10;
260     for (i = 1; i < nstates; i++)
261     {
262 	if (j < 10)
263 	    ++j;
264 	else
265 	{
266 	    output_newline();
267 	    j = 1;
268 	}
269 
270 	output_int((defred[i] ? defred[i] - 2 : 0));
271     }
272 
273     end_table();
274 }
275 
276 #if defined(YYBTYACC)
277 static void
278 output_accessing_symbols(void)
279 {
280     int i, j;
281     int *translate;
282 
283     if (nstates != 0)
284     {
285 	translate = TMALLOC(int, nstates);
286 	NO_SPACE(translate);
287 
288 	for (i = 0; i < nstates; ++i)
289 	{
290 	    int gsymb = accessing_symbol[i];
291 
292 	    translate[i] = symbol_pval[gsymb];
293 	}
294 
295 	/* yystos[] may be unused, depending on compile-time defines */
296 	start_int_table("stos", translate[0]);
297 
298 	j = 10;
299 	for (i = 1; i < nstates; ++i)
300 	{
301 	    if (j < 10)
302 		++j;
303 	    else
304 	    {
305 		output_newline();
306 		j = 1;
307 	    }
308 
309 	    output_int(translate[i]);
310 	}
311 
312 	end_table();
313 	FREE(translate);
314     }
315 }
316 
317 static Value_t
318 find_conflict_base(int cbase)
319 {
320     int i, j;
321 
322     for (i = 0; i < cbase; i++)
323     {
324 	for (j = 0; j + cbase < nconflicts; j++)
325 	{
326 	    if (conflicts[i + j] != conflicts[cbase + j])
327 		break;
328 	}
329 	if (j + cbase >= nconflicts)
330 	    break;
331     }
332     return (Value_t) i;
333 }
334 #endif
335 
336 static void
337 token_actions(void)
338 {
339     int i, j;
340     Value_t shiftcount, reducecount;
341 #if defined(YYBTYACC)
342     Value_t conflictcount = 0;
343     Value_t csym = -1;
344     Value_t cbase = 0;
345 #endif
346     int max, min;
347     Value_t *actionrow, *r, *s;
348     action *p;
349 
350     actionrow = NEW2(PER_STATE * ntokens, Value_t);
351     for (i = 0; i < nstates; ++i)
352     {
353 	if (parser[i])
354 	{
355 	    for (j = 0; j < PER_STATE * ntokens; ++j)
356 		actionrow[j] = 0;
357 
358 	    shiftcount = 0;
359 	    reducecount = 0;
360 #if defined(YYBTYACC)
361 	    if (backtrack)
362 	    {
363 		conflictcount = 0;
364 		csym = -1;
365 		cbase = nconflicts;
366 	    }
367 #endif
368 	    for (p = parser[i]; p; p = p->next)
369 	    {
370 #if defined(YYBTYACC)
371 		if (backtrack)
372 		{
373 		    if (csym != -1 && csym != p->symbol)
374 		    {
375 			conflictcount++;
376 			conflicts[nconflicts++] = -1;
377 			j = find_conflict_base(cbase);
378 			actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
379 			if (j == cbase)
380 			{
381 			    cbase = nconflicts;
382 			}
383 			else
384 			{
385 			    if (conflicts[cbase] == -1)
386 				cbase++;
387 			    nconflicts = cbase;
388 			}
389 			csym = -1;
390 		    }
391 		}
392 #endif
393 		if (p->suppressed == 0)
394 		{
395 		    if (p->action_code == SHIFT)
396 		    {
397 			++shiftcount;
398 			actionrow[p->symbol] = p->number;
399 		    }
400 		    else if (p->action_code == REDUCE && p->number != defred[i])
401 		    {
402 			++reducecount;
403 			actionrow[p->symbol + ntokens] = p->number;
404 		    }
405 		}
406 #if defined(YYBTYACC)
407 		else if (backtrack && p->suppressed == 1)
408 		{
409 		    csym = p->symbol;
410 		    if (p->action_code == SHIFT)
411 		    {
412 			conflicts[nconflicts++] = p->number;
413 		    }
414 		    else if (p->action_code == REDUCE && p->number != defred[i])
415 		    {
416 			if (cbase == nconflicts)
417 			{
418 			    if (cbase)
419 				cbase--;
420 			    else
421 				conflicts[nconflicts++] = -1;
422 			}
423 			conflicts[nconflicts++] = (Value_t) (p->number - 2);
424 		    }
425 		}
426 #endif
427 	    }
428 #if defined(YYBTYACC)
429 	    if (backtrack && csym != -1)
430 	    {
431 		conflictcount++;
432 		conflicts[nconflicts++] = -1;
433 		j = find_conflict_base(cbase);
434 		actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
435 		if (j == cbase)
436 		{
437 		    cbase = nconflicts;
438 		}
439 		else
440 		{
441 		    if (conflicts[cbase] == -1)
442 			cbase++;
443 		    nconflicts = cbase;
444 		}
445 	    }
446 #endif
447 
448 	    tally[i] = shiftcount;
449 	    tally[nstates + i] = reducecount;
450 #if defined(YYBTYACC)
451 	    if (backtrack)
452 		tally[2 * nstates + i] = conflictcount;
453 #endif
454 	    width[i] = 0;
455 	    width[nstates + i] = 0;
456 #if defined(YYBTYACC)
457 	    if (backtrack)
458 		width[2 * nstates + i] = 0;
459 #endif
460 	    if (shiftcount > 0)
461 	    {
462 		froms[i] = r = NEW2(shiftcount, Value_t);
463 		tos[i] = s = NEW2(shiftcount, Value_t);
464 		min = MAXYYINT;
465 		max = 0;
466 		for (j = 0; j < ntokens; ++j)
467 		{
468 		    if (actionrow[j])
469 		    {
470 			if (min > symbol_value[j])
471 			    min = symbol_value[j];
472 			if (max < symbol_value[j])
473 			    max = symbol_value[j];
474 			*r++ = symbol_value[j];
475 			*s++ = actionrow[j];
476 		    }
477 		}
478 		width[i] = (Value_t) (max - min + 1);
479 	    }
480 	    if (reducecount > 0)
481 	    {
482 		froms[nstates + i] = r = NEW2(reducecount, Value_t);
483 		tos[nstates + i] = s = NEW2(reducecount, Value_t);
484 		min = MAXYYINT;
485 		max = 0;
486 		for (j = 0; j < ntokens; ++j)
487 		{
488 		    if (actionrow[ntokens + j])
489 		    {
490 			if (min > symbol_value[j])
491 			    min = symbol_value[j];
492 			if (max < symbol_value[j])
493 			    max = symbol_value[j];
494 			*r++ = symbol_value[j];
495 			*s++ = (Value_t) (actionrow[ntokens + j] - 2);
496 		    }
497 		}
498 		width[nstates + i] = (Value_t) (max - min + 1);
499 	    }
500 #if defined(YYBTYACC)
501 	    if (backtrack && conflictcount > 0)
502 	    {
503 		froms[2 * nstates + i] = r = NEW2(conflictcount, Value_t);
504 		tos[2 * nstates + i] = s = NEW2(conflictcount, Value_t);
505 		min = MAXYYINT;
506 		max = 0;
507 		for (j = 0; j < ntokens; ++j)
508 		{
509 		    if (actionrow[2 * ntokens + j])
510 		    {
511 			if (min > symbol_value[j])
512 			    min = symbol_value[j];
513 			if (max < symbol_value[j])
514 			    max = symbol_value[j];
515 			*r++ = symbol_value[j];
516 			*s++ = (Value_t) (actionrow[2 * ntokens + j] - 1);
517 		    }
518 		}
519 		width[2 * nstates + i] = (Value_t) (max - min + 1);
520 	    }
521 #endif
522 	}
523     }
524     FREE(actionrow);
525 }
526 
527 static int
528 default_goto(int symbol)
529 {
530     int i;
531     int m;
532     int n;
533     int default_state;
534     int max;
535 
536     m = goto_map[symbol];
537     n = goto_map[symbol + 1];
538 
539     if (m == n)
540 	return (0);
541 
542     for (i = 0; i < nstates; i++)
543 	state_count[i] = 0;
544 
545     for (i = m; i < n; i++)
546 	state_count[to_state[i]]++;
547 
548     max = 0;
549     default_state = 0;
550     for (i = 0; i < nstates; i++)
551     {
552 	if (state_count[i] > max)
553 	{
554 	    max = state_count[i];
555 	    default_state = i;
556 	}
557     }
558 
559     return (default_state);
560 }
561 
562 static void
563 save_column(int symbol, int default_state)
564 {
565     int i;
566     int m;
567     int n;
568     Value_t *sp;
569     Value_t *sp1;
570     Value_t *sp2;
571     Value_t count;
572     int symno;
573 
574     m = goto_map[symbol];
575     n = goto_map[symbol + 1];
576 
577     count = 0;
578     for (i = m; i < n; i++)
579     {
580 	if (to_state[i] != default_state)
581 	    ++count;
582     }
583     if (count == 0)
584 	return;
585 
586     symno = symbol_value[symbol] + PER_STATE * nstates;
587 
588     froms[symno] = sp1 = sp = NEW2(count, Value_t);
589     tos[symno] = sp2 = NEW2(count, Value_t);
590 
591     for (i = m; i < n; i++)
592     {
593 	if (to_state[i] != default_state)
594 	{
595 	    *sp1++ = from_state[i];
596 	    *sp2++ = to_state[i];
597 	}
598     }
599 
600     tally[symno] = count;
601     width[symno] = (Value_t) (sp1[-1] - sp[0] + 1);
602 }
603 
604 static void
605 goto_actions(void)
606 {
607     int i, j, k;
608 
609     state_count = NEW2(nstates, Value_t);
610 
611     k = default_goto(start_symbol + 1);
612     start_int_table("dgoto", k);
613     save_column(start_symbol + 1, k);
614 
615     j = 10;
616     for (i = start_symbol + 2; i < nsyms; i++)
617     {
618 	if (j >= 10)
619 	{
620 	    output_newline();
621 	    j = 1;
622 	}
623 	else
624 	    ++j;
625 
626 	k = default_goto(i);
627 	output_int(k);
628 	save_column(i, k);
629     }
630 
631     end_table();
632     FREE(state_count);
633 }
634 
635 static void
636 sort_actions(void)
637 {
638     Value_t i;
639     int j;
640     int k;
641     int t;
642     int w;
643 
644     order = NEW2(nvectors, Value_t);
645     nentries = 0;
646 
647     for (i = 0; i < nvectors; i++)
648     {
649 	if (tally[i] > 0)
650 	{
651 	    t = tally[i];
652 	    w = width[i];
653 	    j = nentries - 1;
654 
655 	    while (j >= 0 && (width[order[j]] < w))
656 		j--;
657 
658 	    while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
659 		j--;
660 
661 	    for (k = nentries - 1; k > j; k--)
662 		order[k + 1] = order[k];
663 
664 	    order[j + 1] = i;
665 	    nentries++;
666 	}
667     }
668 }
669 
670 /*  The function matching_vector determines if the vector specified by	*/
671 /*  the input parameter matches a previously considered	vector.  The	*/
672 /*  test at the start of the function checks if the vector represents	*/
673 /*  a row of shifts over terminal symbols or a row of reductions, or a	*/
674 /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not	*/
675 /*  check if a column of shifts over a nonterminal symbols matches a	*/
676 /*  previously considered vector.  Because of the nature of LR parsing	*/
677 /*  tables, no two columns can match.  Therefore, the only possible	*/
678 /*  match would be between a row and a column.  Such matches are	*/
679 /*  unlikely.  Therefore, to save time, no attempt is made to see if a	*/
680 /*  column matches a previously considered vector.			*/
681 /*									*/
682 /*  Matching_vector is poorly designed.  The test could easily be made	*/
683 /*  faster.  Also, it depends on the vectors being in a specific	*/
684 /*  order.								*/
685 #if defined(YYBTYACC)
686 /*									*/
687 /*  Not really any point in checking for matching conflicts -- it is    */
688 /*  extremely unlikely to occur, and conflicts are (hopefully) rare.    */
689 #endif
690 
691 static int
692 matching_vector(int vector)
693 {
694     int i;
695     int j;
696     int k;
697     int t;
698     int w;
699     int match;
700     int prev;
701 
702     i = order[vector];
703     if (i >= 2 * nstates)
704 	return (-1);
705 
706     t = tally[i];
707     w = width[i];
708 
709     for (prev = vector - 1; prev >= 0; prev--)
710     {
711 	j = order[prev];
712 	if (width[j] != w || tally[j] != t)
713 	    return (-1);
714 
715 	match = 1;
716 	for (k = 0; match && k < t; k++)
717 	{
718 	    if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
719 		match = 0;
720 	}
721 
722 	if (match)
723 	    return (j);
724     }
725 
726     return (-1);
727 }
728 
729 static int
730 pack_vector(int vector)
731 {
732     int i, j, k, l;
733     int t;
734     int loc;
735     int ok;
736     Value_t *from;
737     Value_t *to;
738     int newmax;
739 
740     i = order[vector];
741     t = tally[i];
742     assert(t);
743 
744     from = froms[i];
745     to = tos[i];
746 
747     j = lowzero - from[0];
748     for (k = 1; k < t; ++k)
749 	if (lowzero - from[k] > j)
750 	    j = lowzero - from[k];
751     for (;; ++j)
752     {
753 	if (j == 0)
754 	    continue;
755 	ok = 1;
756 	for (k = 0; ok && k < t; k++)
757 	{
758 	    loc = j + from[k];
759 	    if (loc >= maxtable - 1)
760 	    {
761 		if (loc >= MAXTABLE - 1)
762 		    fatal("maximum table size exceeded");
763 
764 		newmax = maxtable;
765 		do
766 		{
767 		    newmax += 200;
768 		}
769 		while (newmax <= loc);
770 
771 		table = TREALLOC(Value_t, table, newmax);
772 		NO_SPACE(table);
773 
774 		check = TREALLOC(Value_t, check, newmax);
775 		NO_SPACE(check);
776 
777 		for (l = maxtable; l < newmax; ++l)
778 		{
779 		    table[l] = 0;
780 		    check[l] = -1;
781 		}
782 		maxtable = newmax;
783 	    }
784 
785 	    if (check[loc] != -1)
786 		ok = 0;
787 	}
788 	for (k = 0; ok && k < vector; k++)
789 	{
790 	    if (pos[k] == j)
791 		ok = 0;
792 	}
793 	if (ok)
794 	{
795 	    for (k = 0; k < t; k++)
796 	    {
797 		loc = j + from[k];
798 		table[loc] = to[k];
799 		check[loc] = from[k];
800 		if (loc > high)
801 		    high = loc;
802 	    }
803 
804 	    while (check[lowzero] != -1)
805 		++lowzero;
806 
807 	    return (j);
808 	}
809     }
810 }
811 
812 static void
813 pack_table(void)
814 {
815     int i;
816     Value_t place;
817     int state;
818 
819     base = NEW2(nvectors, Value_t);
820     pos = NEW2(nentries, Value_t);
821 
822     maxtable = 1000;
823     table = NEW2(maxtable, Value_t);
824     check = NEW2(maxtable, Value_t);
825 
826     lowzero = 0;
827     high = 0;
828 
829     for (i = 0; i < maxtable; i++)
830 	check[i] = -1;
831 
832     for (i = 0; i < nentries; i++)
833     {
834 	state = matching_vector(i);
835 
836 	if (state < 0)
837 	    place = (Value_t) pack_vector(i);
838 	else
839 	    place = base[state];
840 
841 	pos[i] = place;
842 	base[order[i]] = place;
843     }
844 
845     for (i = 0; i < nvectors; i++)
846     {
847 	if (froms[i])
848 	    FREE(froms[i]);
849 	if (tos[i])
850 	    FREE(tos[i]);
851     }
852 
853     DO_FREE(froms);
854     DO_FREE(tos);
855     DO_FREE(tally);
856     DO_FREE(width);
857     DO_FREE(pos);
858 }
859 
860 static void
861 output_base(void)
862 {
863     int i, j;
864 
865     start_int_table("sindex", base[0]);
866 
867     j = 10;
868     for (i = 1; i < nstates; i++)
869     {
870 	if (j >= 10)
871 	{
872 	    output_newline();
873 	    j = 1;
874 	}
875 	else
876 	    ++j;
877 
878 	output_int(base[i]);
879     }
880 
881     end_table();
882 
883     start_int_table("rindex", base[nstates]);
884 
885     j = 10;
886     for (i = nstates + 1; i < 2 * nstates; i++)
887     {
888 	if (j >= 10)
889 	{
890 	    output_newline();
891 	    j = 1;
892 	}
893 	else
894 	    ++j;
895 
896 	output_int(base[i]);
897     }
898 
899     end_table();
900 
901 #if defined(YYBTYACC)
902     output_line("#if YYBTYACC");
903     start_int_table("cindex", base[2 * nstates]);
904 
905     j = 10;
906     for (i = 2 * nstates + 1; i < 3 * nstates; i++)
907     {
908 	if (j >= 10)
909 	{
910 	    output_newline();
911 	    j = 1;
912 	}
913 	else
914 	    ++j;
915 
916 	output_int(base[i]);
917     }
918 
919     end_table();
920     output_line("#endif");
921 #endif
922 
923     start_int_table("gindex", base[PER_STATE * nstates]);
924 
925     j = 10;
926     for (i = PER_STATE * nstates + 1; i < nvectors - 1; i++)
927     {
928 	if (j >= 10)
929 	{
930 	    output_newline();
931 	    j = 1;
932 	}
933 	else
934 	    ++j;
935 
936 	output_int(base[i]);
937     }
938 
939     end_table();
940     FREE(base);
941 }
942 
943 static void
944 output_table(void)
945 {
946     int i;
947     int j;
948 
949     if (high >= MAXYYINT)
950     {
951 	fprintf(stderr, "YYTABLESIZE: %ld\n", high);
952 	fprintf(stderr, "Table is longer than %d elements.\n", MAXYYINT);
953 	done(1);
954     }
955 
956     ++outline;
957     fprintf(code_file, "#define YYTABLESIZE %ld\n", high);
958     start_int_table("table", table[0]);
959 
960     j = 10;
961     for (i = 1; i <= high; i++)
962     {
963 	if (j >= 10)
964 	{
965 	    output_newline();
966 	    j = 1;
967 	}
968 	else
969 	    ++j;
970 
971 	output_int(table[i]);
972     }
973 
974     end_table();
975     FREE(table);
976 }
977 
978 static void
979 output_check(void)
980 {
981     int i;
982     int j;
983 
984     start_int_table("check", check[0]);
985 
986     j = 10;
987     for (i = 1; i <= high; i++)
988     {
989 	if (j >= 10)
990 	{
991 	    output_newline();
992 	    j = 1;
993 	}
994 	else
995 	    ++j;
996 
997 	output_int(check[i]);
998     }
999 
1000     end_table();
1001     FREE(check);
1002 }
1003 
1004 #if defined(YYBTYACC)
1005 static void
1006 output_ctable(void)
1007 {
1008     int i;
1009     int j;
1010 
1011     if (conflicts)
1012     {
1013 	output_line("#if YYBTYACC");
1014 	start_int_table("ctable", conflicts[0]);
1015 
1016 	j = 10;
1017 	for (i = 1; i < nconflicts; i++)
1018 	{
1019 	    if (j >= 10)
1020 	    {
1021 		output_newline();
1022 		j = 1;
1023 	    }
1024 	    else
1025 		++j;
1026 
1027 	    output_int(conflicts[i]);
1028 	}
1029 
1030 	end_table();
1031 	output_line("#endif");
1032 	FREE(conflicts);
1033     }
1034 }
1035 #endif
1036 
1037 static void
1038 output_actions(void)
1039 {
1040     nvectors = PER_STATE * nstates + nvars;
1041 
1042     froms = NEW2(nvectors, Value_t *);
1043     tos = NEW2(nvectors, Value_t *);
1044     tally = NEW2(nvectors, Value_t);
1045     width = NEW2(nvectors, Value_t);
1046 
1047 #if defined(YYBTYACC)
1048     if (backtrack && (SRtotal + RRtotal) != 0)
1049 	conflicts = NEW2(4 * (SRtotal + RRtotal), Value_t);
1050 #endif
1051 
1052     token_actions();
1053     FREE(lookaheads);
1054     FREE(LA);
1055     FREE(LAruleno);
1056     FREE(accessing_symbol);
1057 
1058     goto_actions();
1059     FREE(goto_map + ntokens);
1060     FREE(from_state);
1061     FREE(to_state);
1062 
1063     sort_actions();
1064     pack_table();
1065     output_base();
1066     output_table();
1067     output_check();
1068 #if defined(YYBTYACC)
1069     output_ctable();
1070 #endif
1071 }
1072 
1073 static int
1074 is_C_identifier(char *name)
1075 {
1076     char *s;
1077     int c;
1078 
1079     s = name;
1080     c = *s;
1081     if (c == '"')
1082     {
1083 	c = *++s;
1084 	if (!isalpha(c) && c != '_' && c != '$')
1085 	    return (0);
1086 	while ((c = *++s) != '"')
1087 	{
1088 	    if (!isalnum(c) && c != '_' && c != '$')
1089 		return (0);
1090 	}
1091 	return (1);
1092     }
1093 
1094     if (!isalpha(c) && c != '_' && c != '$')
1095 	return (0);
1096     while ((c = *++s) != 0)
1097     {
1098 	if (!isalnum(c) && c != '_' && c != '$')
1099 	    return (0);
1100     }
1101     return (1);
1102 }
1103 
1104 #if USE_HEADER_GUARDS
1105 static void
1106 start_defines_file(void)
1107 {
1108     fprintf(defines_file, "#ifndef _%s_defines_h_\n", symbol_prefix);
1109     fprintf(defines_file, "#define _%s_defines_h_\n\n", symbol_prefix);
1110 }
1111 
1112 static void
1113 end_defines_file(void)
1114 {
1115     fprintf(defines_file, "\n#endif /* _%s_defines_h_ */\n", symbol_prefix);
1116 }
1117 #else
1118 #define start_defines_file()	/* nothing */
1119 #define end_defines_file()	/* nothing */
1120 #endif
1121 
1122 static void
1123 output_defines(FILE * fp)
1124 {
1125     int c, i;
1126     char *s;
1127 
1128     for (i = 2; i < ntokens; ++i)
1129     {
1130 	s = symbol_name[i];
1131 	if (is_C_identifier(s) && (!sflag || *s != '"'))
1132 	{
1133 	    fprintf(fp, "#define ");
1134 	    c = *s;
1135 	    if (c == '"')
1136 	    {
1137 		while ((c = *++s) != '"')
1138 		{
1139 		    putc(c, fp);
1140 		}
1141 	    }
1142 	    else
1143 	    {
1144 		do
1145 		{
1146 		    putc(c, fp);
1147 		}
1148 		while ((c = *++s) != 0);
1149 	    }
1150 	    if (fp == code_file)
1151 		++outline;
1152 	    fprintf(fp, " %d\n", symbol_value[i]);
1153 	}
1154     }
1155 
1156     if (fp == code_file)
1157 	++outline;
1158     if (fp != defines_file || iflag)
1159 	fprintf(fp, "#define YYERRCODE %d\n", symbol_value[1]);
1160 
1161     if (fp == defines_file || (iflag && !dflag))
1162     {
1163 	if (unionized)
1164 	{
1165 	    if (union_file != 0)
1166 	    {
1167 		rewind(union_file);
1168 		while ((c = getc(union_file)) != EOF)
1169 		    putc_code(fp, c);
1170 	    }
1171 	    fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix);
1172 	}
1173     }
1174 }
1175 
1176 static void
1177 output_stored_text(FILE * fp)
1178 {
1179     int c;
1180     FILE *in;
1181 
1182     rewind(text_file);
1183     if (text_file == NULL)
1184 	open_error("text_file");
1185     in = text_file;
1186     if ((c = getc(in)) == EOF)
1187 	return;
1188     putc_code(fp, c);
1189     while ((c = getc(in)) != EOF)
1190     {
1191 	putc_code(fp, c);
1192     }
1193     write_code_lineno(fp);
1194 }
1195 
1196 static void
1197 output_debug(void)
1198 {
1199     int i, j, k, max, maxtok;
1200     const char **symnam;
1201     const char *s;
1202 
1203     ++outline;
1204     fprintf(code_file, "#define YYFINAL %d\n", final_state);
1205 
1206     putl_code(code_file, "#ifndef YYDEBUG\n");
1207     ++outline;
1208     fprintf(code_file, "#define YYDEBUG %d\n", tflag);
1209     putl_code(code_file, "#endif\n");
1210 
1211     if (rflag)
1212     {
1213 	fprintf(output_file, "#ifndef YYDEBUG\n");
1214 	fprintf(output_file, "#define YYDEBUG %d\n", tflag);
1215 	fprintf(output_file, "#endif\n");
1216     }
1217 
1218     maxtok = 0;
1219     for (i = 0; i < ntokens; ++i)
1220 	if (symbol_value[i] > maxtok)
1221 	    maxtok = symbol_value[i];
1222 
1223     /* symbol_value[$accept] = -1         */
1224     /* symbol_value[<goal>]  = 0          */
1225     /* remaining non-terminals start at 1 */
1226     max = maxtok;
1227     for (i = ntokens; i < nsyms; ++i)
1228 	if (((maxtok + 1) + (symbol_value[i] + 1)) > max)
1229 	    max = (maxtok + 1) + (symbol_value[i] + 1);
1230 
1231     ++outline;
1232     fprintf(code_file, "#define YYMAXTOKEN %d\n", maxtok);
1233 
1234     ++outline;
1235     fprintf(code_file, "#define YYUNDFTOKEN %d\n", max + 1);
1236 
1237     ++outline;
1238     fprintf(code_file, "#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? "
1239 	    "YYUNDFTOKEN : (a))\n");
1240 
1241     symnam = TMALLOC(const char *, max + 2);
1242     NO_SPACE(symnam);
1243 
1244     /* Note that it is not necessary to initialize the element          */
1245     /* symnam[max].                                                     */
1246 #if defined(YYBTYACC)
1247     for (i = 0; i < max; ++i)
1248 	symnam[i] = 0;
1249     for (i = nsyms - 1; i >= 0; --i)
1250 	symnam[symbol_pval[i]] = symbol_name[i];
1251     symnam[max + 1] = "illegal-symbol";
1252 #else
1253     for (i = 0; i <= max; ++i)
1254 	symnam[i] = 0;
1255     for (i = ntokens - 1; i >= 2; --i)
1256 	symnam[symbol_value[i]] = symbol_name[i];
1257     symnam[0] = "end-of-file";
1258     symnam[max + 1] = "illegal-symbol";
1259 #endif
1260 
1261     /*
1262      * bison's yytname[] array is roughly the same as byacc's yyname[] array.
1263      * The difference is that byacc does not predefine "$undefined".
1264      *
1265      * If the grammar declares "%token-table", define symbol "yytname" so
1266      * an application such as ntpd can build.
1267      */
1268     if (token_table)
1269     {
1270 	output_line("#undef yytname");
1271 	output_line("#define yytname yyname");
1272     }
1273     else
1274     {
1275 	output_line("#if YYDEBUG");
1276     }
1277 
1278     start_str_table("name");
1279     j = 80;
1280     for (i = 0; i <= max + 1; ++i)
1281     {
1282 	if ((s = symnam[i]) != 0)
1283 	{
1284 	    if (s[0] == '"')
1285 	    {
1286 		k = 7;
1287 		while (*++s != '"')
1288 		{
1289 		    ++k;
1290 		    if (*s == '\\')
1291 		    {
1292 			k += 2;
1293 			if (*++s == '\\')
1294 			    ++k;
1295 		    }
1296 		}
1297 		j += k;
1298 		if (j > 80)
1299 		{
1300 		    output_newline();
1301 		    j = k;
1302 		}
1303 		fprintf(output_file, "\"\\\"");
1304 		s = symnam[i];
1305 		while (*++s != '"')
1306 		{
1307 		    if (*s == '\\')
1308 		    {
1309 			fprintf(output_file, "\\\\");
1310 			if (*++s == '\\')
1311 			    fprintf(output_file, "\\\\");
1312 			else
1313 			    putc(*s, output_file);
1314 		    }
1315 		    else
1316 			putc(*s, output_file);
1317 		}
1318 		fprintf(output_file, "\\\"\",");
1319 	    }
1320 	    else if (s[0] == '\'')
1321 	    {
1322 		if (s[1] == '"')
1323 		{
1324 		    j += 7;
1325 		    if (j > 80)
1326 		    {
1327 			output_newline();
1328 			j = 7;
1329 		    }
1330 		    fprintf(output_file, "\"'\\\"'\",");
1331 		}
1332 		else
1333 		{
1334 		    k = 5;
1335 		    while (*++s != '\'')
1336 		    {
1337 			++k;
1338 			if (*s == '\\')
1339 			{
1340 			    k += 2;
1341 			    if (*++s == '\\')
1342 				++k;
1343 			}
1344 		    }
1345 		    j += k;
1346 		    if (j > 80)
1347 		    {
1348 			output_newline();
1349 			j = k;
1350 		    }
1351 		    fprintf(output_file, "\"'");
1352 		    s = symnam[i];
1353 		    while (*++s != '\'')
1354 		    {
1355 			if (*s == '\\')
1356 			{
1357 			    fprintf(output_file, "\\\\");
1358 			    if (*++s == '\\')
1359 				fprintf(output_file, "\\\\");
1360 			    else
1361 				putc(*s, output_file);
1362 			}
1363 			else
1364 			    putc(*s, output_file);
1365 		    }
1366 		    fprintf(output_file, "'\",");
1367 		}
1368 	    }
1369 	    else
1370 	    {
1371 		k = (int)strlen(s) + 3;
1372 		j += k;
1373 		if (j > 80)
1374 		{
1375 		    output_newline();
1376 		    j = k;
1377 		}
1378 		putc('"', output_file);
1379 		do
1380 		{
1381 		    putc(*s, output_file);
1382 		}
1383 		while (*++s);
1384 		fprintf(output_file, "\",");
1385 	    }
1386 	}
1387 	else
1388 	{
1389 	    j += 2;
1390 	    if (j > 80)
1391 	    {
1392 		output_newline();
1393 		j = 2;
1394 	    }
1395 	    fprintf(output_file, "0,");
1396 	}
1397     }
1398     end_table();
1399     FREE(symnam);
1400 
1401     if (token_table)
1402 	output_line("#if YYDEBUG");
1403     start_str_table("rule");
1404     for (i = 2; i < nrules; ++i)
1405     {
1406 	fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1407 	for (j = rrhs[i]; ritem[j] > 0; ++j)
1408 	{
1409 	    s = symbol_name[ritem[j]];
1410 	    if (s[0] == '"')
1411 	    {
1412 		fprintf(output_file, " \\\"");
1413 		while (*++s != '"')
1414 		{
1415 		    if (*s == '\\')
1416 		    {
1417 			if (s[1] == '\\')
1418 			    fprintf(output_file, "\\\\\\\\");
1419 			else
1420 			    fprintf(output_file, "\\\\%c", s[1]);
1421 			++s;
1422 		    }
1423 		    else
1424 			putc(*s, output_file);
1425 		}
1426 		fprintf(output_file, "\\\"");
1427 	    }
1428 	    else if (s[0] == '\'')
1429 	    {
1430 		if (s[1] == '"')
1431 		    fprintf(output_file, " '\\\"'");
1432 		else if (s[1] == '\\')
1433 		{
1434 		    if (s[2] == '\\')
1435 			fprintf(output_file, " '\\\\\\\\");
1436 		    else
1437 			fprintf(output_file, " '\\\\%c", s[2]);
1438 		    s += 2;
1439 		    while (*++s != '\'')
1440 			putc(*s, output_file);
1441 		    putc('\'', output_file);
1442 		}
1443 		else
1444 		    fprintf(output_file, " '%c'", s[1]);
1445 	    }
1446 	    else
1447 		fprintf(output_file, " %s", s);
1448 	}
1449 	fprintf(output_file, "\",");
1450 	output_newline();
1451     }
1452 
1453     end_table();
1454     output_line("#endif");
1455 }
1456 
1457 #if defined(YYBTYACC)
1458 static void
1459 output_backtracking_parser(FILE * fp)
1460 {
1461     putl_code(fp, "#undef YYBTYACC\n");
1462 #if defined(YYBTYACC)
1463     if (backtrack)
1464     {
1465 	putl_code(fp, "#define YYBTYACC 1\n");
1466 	putl_code(fp,
1467 		  "#define YYDEBUGSTR (yytrial ? YYPREFIX \"debug(trial)\" : YYPREFIX \"debug\")\n");
1468     }
1469     else
1470 #endif
1471     {
1472 	putl_code(fp, "#define YYBTYACC 0\n");
1473 	putl_code(fp, "#define YYDEBUGSTR YYPREFIX \"debug\"\n");
1474     }
1475 }
1476 #endif
1477 
1478 static void
1479 output_pure_parser(FILE * fp)
1480 {
1481     putc_code(fp, '\n');
1482 
1483     if (fp == code_file)
1484 	++outline;
1485     fprintf(fp, "#define YYPURE %d\n", pure_parser);
1486     putc_code(fp, '\n');
1487 }
1488 
1489 static void
1490 output_stype(FILE * fp)
1491 {
1492     if (!unionized && ntags == 0)
1493     {
1494 	putc_code(fp, '\n');
1495 	putl_code(fp, "#if "
1496 		  "! defined(YYSTYPE) && "
1497 		  "! defined(YYSTYPE_IS_DECLARED)\n");
1498 	putl_code(fp, "/* Default: YYSTYPE is the semantic value type. */\n");
1499 	putl_code(fp, "typedef int YYSTYPE;\n");
1500 	putl_code(fp, "# define YYSTYPE_IS_DECLARED 1\n");
1501 	putl_code(fp, "#endif\n");
1502     }
1503 }
1504 
1505 #if defined(YYBTYACC)
1506 static void
1507 output_ltype(FILE * fp)
1508 {
1509     putc_code(fp, '\n');
1510     putl_code(fp, "#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED\n");
1511     putl_code(fp, "/* Default: YYLTYPE is the text position type. */\n");
1512     putl_code(fp, "typedef struct YYLTYPE\n");
1513     putl_code(fp, "{\n");
1514     putl_code(fp, "    int first_line;\n");
1515     putl_code(fp, "    int first_column;\n");
1516     putl_code(fp, "    int last_line;\n");
1517     putl_code(fp, "    int last_column;\n");
1518     putl_code(fp, "} YYLTYPE;\n");
1519     putl_code(fp, "#define YYLTYPE_IS_DECLARED 1\n");
1520     putl_code(fp, "#endif\n");
1521 }
1522 #endif
1523 
1524 static void
1525 output_trailing_text(void)
1526 {
1527     int c, last;
1528     FILE *in;
1529 
1530     if (line == 0)
1531 	return;
1532 
1533     in = input_file;
1534     c = *cptr;
1535     if (c == '\n')
1536     {
1537 	++lineno;
1538 	if ((c = getc(in)) == EOF)
1539 	    return;
1540 	write_input_lineno();
1541 	putc_code(code_file, c);
1542 	last = c;
1543     }
1544     else
1545     {
1546 	write_input_lineno();
1547 	do
1548 	{
1549 	    putc_code(code_file, c);
1550 	}
1551 	while ((c = *++cptr) != '\n');
1552 	putc_code(code_file, c);
1553 	last = '\n';
1554     }
1555 
1556     while ((c = getc(in)) != EOF)
1557     {
1558 	putc_code(code_file, c);
1559 	last = c;
1560     }
1561 
1562     if (last != '\n')
1563     {
1564 	putc_code(code_file, '\n');
1565     }
1566     write_code_lineno(code_file);
1567 }
1568 
1569 static void
1570 output_semantic_actions(void)
1571 {
1572     int c, last;
1573 
1574     rewind(action_file);
1575     if ((c = getc(action_file)) == EOF)
1576 	return;
1577 
1578     last = c;
1579     putc_code(code_file, c);
1580     while ((c = getc(action_file)) != EOF)
1581     {
1582 	putc_code(code_file, c);
1583 	last = c;
1584     }
1585 
1586     if (last != '\n')
1587     {
1588 	putc_code(code_file, '\n');
1589     }
1590 
1591     write_code_lineno(code_file);
1592 }
1593 
1594 static void
1595 output_parse_decl(FILE * fp)
1596 {
1597     putc_code(fp, '\n');
1598     putl_code(fp, "/* compatibility with bison */\n");
1599     putl_code(fp, "#ifdef YYPARSE_PARAM\n");
1600     putl_code(fp, "/* compatibility with FreeBSD */\n");
1601     putl_code(fp, "# ifdef YYPARSE_PARAM_TYPE\n");
1602     putl_code(fp,
1603 	      "#  define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n");
1604     putl_code(fp, "# else\n");
1605     putl_code(fp, "#  define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n");
1606     putl_code(fp, "# endif\n");
1607     putl_code(fp, "#else\n");
1608 
1609     puts_code(fp, "# define YYPARSE_DECL() yyparse(");
1610     if (!parse_param)
1611 	puts_code(fp, "void");
1612     else
1613     {
1614 	param *p;
1615 	for (p = parse_param; p; p = p->next)
1616 	    fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1617 		    p->next ? ", " : "");
1618     }
1619     putl_code(fp, ")\n");
1620 
1621     putl_code(fp, "#endif\n");
1622 }
1623 
1624 static void
1625 output_lex_decl(FILE * fp)
1626 {
1627     putc_code(fp, '\n');
1628     putl_code(fp, "/* Parameters sent to lex. */\n");
1629     putl_code(fp, "#ifdef YYLEX_PARAM\n");
1630     if (pure_parser)
1631     {
1632 	putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n");
1633 #if defined(YYBTYACC)
1634 	if (locations)
1635 	{
1636 	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc,"
1637 		      " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1638 	}
1639 	else
1640 #endif
1641 	{
1642 	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1643 		      " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
1644 	}
1645 	putl_code(fp, "# else\n");
1646 #if defined(YYBTYACC)
1647 	if (locations)
1648 	{
1649 	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc,"
1650 		      " void * YYLEX_PARAM)\n");
1651 	}
1652 	else
1653 #endif
1654 	{
1655 	    putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
1656 		      " void * YYLEX_PARAM)\n");
1657 	}
1658 	putl_code(fp, "# endif\n");
1659 #if defined(YYBTYACC)
1660 	if (locations)
1661 	    putl_code(fp,
1662 		      "# define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)\n");
1663 	else
1664 #endif
1665 	    putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
1666     }
1667     else
1668     {
1669 	putl_code(fp, "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n");
1670 	putl_code(fp, "# define YYLEX yylex(YYLEX_PARAM)\n");
1671     }
1672     putl_code(fp, "#else\n");
1673     if (pure_parser && lex_param)
1674     {
1675 	param *p;
1676 
1677 #if defined(YYBTYACC)
1678 	if (locations)
1679 	    puts_code(fp,
1680 		      "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc, ");
1681 	else
1682 #endif
1683 	    puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
1684 	for (p = lex_param; p; p = p->next)
1685 	    fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1686 		    p->next ? ", " : "");
1687 	putl_code(fp, ")\n");
1688 
1689 #if defined(YYBTYACC)
1690 	if (locations)
1691 	    puts_code(fp, "# define YYLEX yylex(&yylval, &yylloc, ");
1692 	else
1693 #endif
1694 	    puts_code(fp, "# define YYLEX yylex(&yylval, ");
1695 	for (p = lex_param; p; p = p->next)
1696 	    fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
1697 	putl_code(fp, ")\n");
1698     }
1699     else if (pure_parser)
1700     {
1701 #if defined(YYBTYACC)
1702 	if (locations)
1703 	{
1704 	    putl_code(fp,
1705 		      "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc)\n");
1706 	    putl_code(fp, "# define YYLEX yylex(&yylval, &yylloc)\n");
1707 	}
1708 	else
1709 #endif
1710 	{
1711 	    putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
1712 	    putl_code(fp, "# define YYLEX yylex(&yylval)\n");
1713 	}
1714     }
1715     else if (lex_param)
1716     {
1717 	param *p;
1718 
1719 	puts_code(fp, "# define YYLEX_DECL() yylex(");
1720 	for (p = lex_param; p; p = p->next)
1721 	    fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
1722 		    p->next ? ", " : "");
1723 	putl_code(fp, ")\n");
1724 
1725 	puts_code(fp, "# define YYLEX yylex(");
1726 	for (p = lex_param; p; p = p->next)
1727 	    fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
1728 	putl_code(fp, ")\n");
1729     }
1730     else
1731     {
1732 	putl_code(fp, "# define YYLEX_DECL() yylex(void)\n");
1733 	putl_code(fp, "# define YYLEX yylex()\n");
1734     }
1735     putl_code(fp, "#endif\n");
1736 }
1737 
1738 static void
1739 output_error_decl(FILE * fp)
1740 {
1741     param *p;
1742 
1743     putc_code(fp, '\n');
1744     putl_code(fp, "/* Parameters sent to yyerror. */\n");
1745     putl_code(fp, "#ifndef YYERROR_DECL\n");
1746     puts_code(fp, "#define YYERROR_DECL() yyerror(");
1747 #if defined(YYBTYACC)
1748     if (locations)
1749 	puts_code(fp, "YYLTYPE loc, ");
1750 #endif
1751     for (p = parse_param; p; p = p->next)
1752 	fprintf(fp, "%s %s%s, ", p->type, p->name, p->type2);
1753     putl_code(fp, "const char *s)\n");
1754     putl_code(fp, "#endif\n");
1755 
1756     putl_code(fp, "#ifndef YYERROR_CALL\n");
1757     puts_code(fp, "#define YYERROR_CALL(msg) yyerror(");
1758 
1759 #if defined(YYBTYACC)
1760     if (locations)
1761 	puts_code(fp, "yylloc, ");
1762 #endif
1763     for (p = parse_param; p; p = p->next)
1764 	fprintf(fp, "%s, ", p->name);
1765 
1766     putl_code(fp, "msg)\n");
1767     putl_code(fp, "#endif\n");
1768 }
1769 
1770 #if defined(YYBTYACC)
1771 static void
1772 output_yydestruct_decl(FILE * fp)
1773 {
1774     putc_code(fp, '\n');
1775     putl_code(fp, "#ifndef YYDESTRUCT_DECL\n");
1776 #if defined(YYBTYACC)
1777     if (locations)
1778 	putl_code(fp,
1779 		  "#define YYDESTRUCT_DECL() yydestruct(const char *msg, int psymb, YYSTYPE *val, YYLTYPE *loc)\n");
1780     else
1781 #endif
1782 	putl_code(fp,
1783 		  "#define YYDESTRUCT_DECL() yydestruct(const char *msg, int psymb, YYSTYPE *val)\n");
1784     putl_code(fp, "#endif\n");
1785     putl_code(fp, "#ifndef YYDESTRUCT_CALL\n");
1786 #if defined(YYBTYACC)
1787     if (locations)
1788 	putl_code(fp,
1789 		  "#define YYDESTRUCT_CALL(msg, psymb, val, loc) yydestruct(msg, psymb, val, loc)\n");
1790     else
1791 #endif
1792 	putl_code(fp,
1793 		  "#define YYDESTRUCT_CALL(msg, psymb, val) yydestruct(msg, psymb, val)\n");
1794     putl_code(fp, "#endif\n");
1795 }
1796 
1797 static void
1798 output_yydestruct_impl(void)
1799 {
1800     int i;
1801     char *s, *destructor_code;
1802 
1803     putc_code(code_file, '\n');
1804     putl_code(code_file, "/* Release memory associated with symbol. */\n");
1805     putl_code(code_file, "#if ! defined YYDESTRUCT_IS_DECLARED\n");
1806     putl_code(code_file, "static void\n");
1807     putl_code(code_file, "YYDESTRUCT_DECL()\n");
1808     putl_code(code_file, "{\n");
1809     putl_code(code_file, "    switch (psymb)\n");
1810     putl_code(code_file, "    {\n");
1811     for (i = 2; i < nsyms; ++i)
1812     {
1813 	if ((destructor_code = symbol_destructor[i]) != NULL)
1814 	{
1815 	    ++outline;
1816 	    fprintf(code_file, "\tcase %d:\n", symbol_pval[i]);
1817 	    /* comprehend the number of lines in the destructor code */
1818 	    for (s = destructor_code; (s = strchr(s, '\n')) != NULL; s++)
1819 		++outline;
1820 	    puts_code(code_file, destructor_code);
1821 	    putc_code(code_file, '\n');
1822 	    putl_code(code_file, "\tbreak;\n");
1823 	    write_code_lineno(code_file);
1824 	    FREE(destructor_code);
1825 	}
1826     }
1827     putl_code(code_file, "    }\n");
1828     putl_code(code_file, "}\n");
1829     putl_code(code_file, "#define YYDESTRUCT_IS_DECLARED 1\n");
1830     putl_code(code_file, "#endif\n");
1831 
1832     DO_FREE(symbol_destructor);
1833 }
1834 #endif
1835 
1836 static void
1837 free_itemsets(void)
1838 {
1839     core *cp, *next;
1840 
1841     FREE(state_table);
1842     for (cp = first_state; cp; cp = next)
1843     {
1844 	next = cp->next;
1845 	FREE(cp);
1846     }
1847 }
1848 
1849 static void
1850 free_shifts(void)
1851 {
1852     shifts *sp, *next;
1853 
1854     FREE(shift_table);
1855     for (sp = first_shift; sp; sp = next)
1856     {
1857 	next = sp->next;
1858 	FREE(sp);
1859     }
1860 }
1861 
1862 static void
1863 free_reductions(void)
1864 {
1865     reductions *rp, *next;
1866 
1867     FREE(reduction_table);
1868     for (rp = first_reduction; rp; rp = next)
1869     {
1870 	next = rp->next;
1871 	FREE(rp);
1872     }
1873 }
1874 
1875 static void
1876 output_externs(FILE * fp, const char *const section[])
1877 {
1878     int i;
1879     const char *s;
1880 
1881     for (i = 0; (s = section[i]) != 0; ++i)
1882     {
1883 	/* prefix non-blank lines that don't start with
1884 	   C pre-processor directives with 'extern ' */
1885 	if (*s && (*s != '#'))
1886 	    fputs("extern\t", fp);
1887 	if (fp == code_file)
1888 	    ++outline;
1889 	fprintf(fp, "%s\n", s);
1890     }
1891 }
1892 
1893 void
1894 output(void)
1895 {
1896     FILE *fp;
1897 
1898     free_itemsets();
1899     free_shifts();
1900     free_reductions();
1901 
1902 #if defined(YYBTYACC)
1903     output_backtracking_parser(output_file);
1904     if (rflag)
1905 	output_backtracking_parser(code_file);
1906 #endif
1907 
1908     if (iflag)
1909     {
1910 	write_code_lineno(code_file);
1911 	++outline;
1912 	fprintf(code_file, "#include \"%s\"\n", externs_file_name);
1913 	fp = externs_file;
1914     }
1915     else
1916 	fp = code_file;
1917 
1918     output_prefix(fp);
1919     output_pure_parser(fp);
1920     output_stored_text(fp);
1921     output_stype(fp);
1922 #if defined(YYBTYACC)
1923     if (locations)
1924 	output_ltype(fp);
1925 #endif
1926     output_parse_decl(fp);
1927     output_lex_decl(fp);
1928     output_error_decl(fp);
1929 #if defined(YYBTYACC)
1930     if (destructor)
1931 	output_yydestruct_decl(fp);
1932 #endif
1933     if (iflag || !rflag)
1934     {
1935 	write_section(fp, xdecls);
1936     }
1937 
1938     if (iflag)
1939     {
1940 	output_externs(externs_file, global_vars);
1941 	if (!pure_parser)
1942 	    output_externs(externs_file, impure_vars);
1943     }
1944 
1945     if (iflag)
1946     {
1947 	if (dflag)
1948 	{
1949 	    ++outline;
1950 	    fprintf(code_file, "#include \"%s\"\n", defines_file_name);
1951 	}
1952 	else
1953 	    output_defines(externs_file);
1954     }
1955     else
1956     {
1957 	putc_code(code_file, '\n');
1958 	output_defines(code_file);
1959     }
1960 
1961     if (dflag)
1962     {
1963 	start_defines_file();
1964 	output_defines(defines_file);
1965 	end_defines_file();
1966     }
1967 
1968     output_rule_data();
1969     output_yydefred();
1970 #if defined(YYBTYACC)
1971     output_accessing_symbols();
1972 #endif
1973     output_actions();
1974     free_parser();
1975     output_debug();
1976     if (rflag)
1977     {
1978 	write_section(code_file, xdecls);
1979 	output_YYINT_typedef(code_file);
1980 	write_section(code_file, tables);
1981     }
1982     write_section(code_file, global_vars);
1983     if (!pure_parser)
1984     {
1985 	write_section(code_file, impure_vars);
1986     }
1987     write_section(code_file, hdr_defs);
1988     if (!pure_parser)
1989     {
1990 	write_section(code_file, hdr_vars);
1991     }
1992     output_trailing_text();
1993 #if defined(YYBTYACC)
1994     if (destructor)
1995 	output_yydestruct_impl();
1996 #endif
1997     write_section(code_file, body_1);
1998     if (pure_parser)
1999     {
2000 	write_section(code_file, body_vars);
2001     }
2002     write_section(code_file, body_2);
2003     output_semantic_actions();
2004     write_section(code_file, trailer);
2005 }
2006 
2007 #ifdef NO_LEAKS
2008 void
2009 output_leaks(void)
2010 {
2011     DO_FREE(tally);
2012     DO_FREE(width);
2013     DO_FREE(order);
2014 }
2015 #endif
2016