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