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