xref: /dragonfly/contrib/byacc/output.c (revision abf903a5)
1 /* $Id: output.c,v 1.83 2017/07/09 18:13:42 tom Exp $ */
2 
3 #include "defs.h"
4 
5 #define StaticOrR	(rflag ? "" : "static ")
6 #define CountLine(fp)   (!rflag || ((fp) == code_file))
7 
8 #if defined(YYBTYACC)
9 #define PER_STATE 3
10 #else
11 #define PER_STATE 2
12 #endif
13 
14 static int nvectors;
15 static int nentries;
16 static Value_t **froms;
17 static Value_t **tos;
18 #if defined(YYBTYACC)
19 static Value_t *conflicts = NULL;
20 static Value_t nconflicts = 0;
21 #endif
22 static Value_t *tally;
23 static Value_t *width;
24 static Value_t *state_count;
25 static Value_t *order;
26 static Value_t *base;
27 static Value_t *pos;
28 static int maxtable;
29 static Value_t *table;
30 static Value_t *check;
31 static int lowzero;
32 static long high;
33 
34 static void
35 putc_code(FILE * fp, int c)
36 {
37     if ((c == '\n') && (fp == code_file))
38 	++outline;
39     putc(c, fp);
40 }
41 
42 static void
43 putl_code(FILE * fp, const char *s)
44 {
45     if (fp == code_file)
46 	++outline;
47     fputs(s, fp);
48 }
49 
50 static void
51 puts_code(FILE * fp, const char *s)
52 {
53     fputs(s, fp);
54 }
55 
56 static void
57 puts_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 
81 static void
82 puts_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 
93 static void
94 write_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 
103 static void
104 write_input_lineno(void)
105 {
106     if (!lflag)
107     {
108 	++outline;
109 	fprintf(code_file, line_format, lineno, input_file_name);
110     }
111 }
112 
113 static void
114 define_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 
134 static void
135 output_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 
188 static void
189 output_newline(void)
190 {
191     if (!rflag)
192 	++outline;
193     putc('\n', output_file);
194 }
195 
196 static void
197 output_line(const char *value)
198 {
199     fputs(value, output_file);
200     output_newline();
201 }
202 
203 static void
204 output_int(int value)
205 {
206     fprintf(output_file, "%5d,", value);
207 }
208 
209 static void
210 start_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 
221 static void
222 start_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 
230 static void
231 end_table(void)
232 {
233     output_newline();
234     output_line("};");
235 }
236 
237 static void
238 output_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)
254 static void
255 output_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 
274 static void
275 output_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 
283 static void
284 output_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 
326 static void
327 output_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)
351 static void
352 output_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 
395 static Value_t
396 find_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 
414 static void
415 token_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 
605 static int
606 default_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 
640 static void
641 save_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 
682 static void
683 goto_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 
713 static void
714 sort_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 
769 static int
770 matching_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 
807 static int
808 pack_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 
890 static void
891 pack_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 
938 static void
939 output_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 
1021 static void
1022 output_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 
1056 static void
1057 output_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)
1083 static void
1084 output_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 
1118 static void
1119 output_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 
1154 static int
1155 is_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 (!IS_NAME1(c))
1166 	    return (0);
1167 	while ((c = *++s) != '"')
1168 	{
1169 	    if (!IS_NAME2(c))
1170 		return (0);
1171 	}
1172 	return (1);
1173     }
1174 
1175     if (!IS_NAME1(c))
1176 	return (0);
1177     while ((c = *++s) != 0)
1178     {
1179 	if (!IS_NAME2(c))
1180 	    return (0);
1181     }
1182     return (1);
1183 }
1184 
1185 #if USE_HEADER_GUARDS
1186 static void
1187 start_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 
1193 static void
1194 end_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 
1203 static void
1204 output_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 
1271 static void
1272 output_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 
1291 static void
1292 output_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)
1556 static void
1557 output_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 
1576 static void
1577 output_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)
1588 static void
1589 output_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 
1600 static void
1601 output_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 
1645 static void
1646 output_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 
1670 static void
1671 output_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 
1692 static void
1693 output_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 
1798 static void
1799 output_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)
1827 static void
1828 output_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 
1871 static void
1872 output_initial_action(void)
1873 {
1874     if (initial_action)
1875 	fprintf(code_file, "%s\n", initial_action);
1876 }
1877 
1878 static void
1879 output_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 
1917 static void
1918 free_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 
1930 static void
1931 free_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 
1943 static void
1944 free_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 
1956 static void
1957 output_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 
1974 void
1975 output(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
2101 void
2102 output_leaks(void)
2103 {
2104     DO_FREE(tally);
2105     DO_FREE(width);
2106     DO_FREE(order);
2107 }
2108 #endif
2109