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