1 #include <stdio.h>
2 #include <string.h>
3 
4 #include "defs.h"
5 
6 static int nvectors;
7 static int nentries;
8 static short **froms;
9 static short **tos;
10 static short *tally;
11 static short *width;
12 static short *state_count;
13 static short *order;
14 static short *base;
15 static short *pos;
16 static int maxtable;
17 static short *table;
18 static short *check;
19 static int lowzero;
20 static int high;
21 
22 
output(void)23 void output(void)
24 {
25     free_itemsets();
26     free_shifts();
27     free_reductions();
28     output_stored_text();
29     if (jflag)    /*rwj*/
30       {
31       write_section(jheader);
32       output_stype();
33       }
34     output_defines();
35     output_rule_data();
36     output_yydefred();
37     output_actions();
38     free_parser();
39     output_debug();
40     if (!jflag)    /*rwj*/
41       output_stype();
42     if (rflag) write_section(tables);
43     if (!jflag)    /*rwj*/
44       write_section(header);
45     output_trailing_text();
46     if (jflag)  { /*rwj*/
47 		/* yio 20020304: nodebug and throws options */
48 		if (jdebug == TRUE) {
49 			write_section(jbody_a);
50 			if (strlen(jyyparse_throws)>0)
51 				fprintf(code_file,"throws %s\n",jyyparse_throws);
52 			write_section(jbody_b);
53 		}
54 		else {
55 			write_section(jbody_nodebug_a);
56 			if (strlen(jyyparse_throws)>0)
57 				fprintf(code_file,"throws %s\n",jyyparse_throws);
58 			write_section(jbody_nodebug_b);
59 		}
60 	}
61     else
62 		write_section(body);
63 
64     output_semantic_actions();
65     if (jflag) {  /*rwj*/
66 		/* yio 20020304: nodebug option */
67 		if (jdebug == TRUE)
68 			write_section(jtrailer);
69 		else
70 			write_section(jtrailer_nodebug);
71 	}
72     else
73 		write_section(trailer);
74 }
75 
76 
output_rule_data(void)77 void output_rule_data(void)
78 {
79 int i;
80 int j;
81 
82     if (jflag)  /*rwj*/
83       fprintf(output_file, "final static short yylhs[] = {%29d,",
84 	    symbol_value[start_symbol]);
85     else
86       fprintf(output_file, "short yylhs[] = {%42d,",
87 	    symbol_value[start_symbol]);
88 
89     j = 10;
90     for (i = 3; i < nrules; i++)
91     {
92 	if (j >= 10)
93 	{
94 	    if (!rflag) ++outline;
95 	    putc('\n', output_file);
96 	    j = 1;
97 	}
98         else
99 	    ++j;
100 
101         fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
102     }
103     if (!rflag) outline += 2;
104     fprintf(output_file, "\n};\n");
105 
106     if (jflag) /*rwj*/
107       fprintf(output_file, "final static short yylen[] = {%29d,",2);
108     else
109       fprintf(output_file, "short yylen[] = {%42d,", 2);
110 
111     j = 10;
112     for (i = 3; i < nrules; i++)
113     {
114 	if (j >= 10)
115 	{
116 	    if (!rflag) ++outline;
117 	    putc('\n', output_file);
118 	    j = 1;
119 	}
120 	else
121 	  j++;
122 
123         fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
124     }
125     if (!rflag) outline += 2;
126     fprintf(output_file, "\n};\n");
127 }
128 
129 
output_yydefred(void)130 void output_yydefred(void)
131 {
132 int i, j;
133 
134     if (jflag)
135        fprintf(output_file, "final static short yydefred[] = {%26d,",
136 	    (defred[0] ? defred[0] - 2 : 0));
137     else
138        fprintf(output_file, "short yydefred[] = {%39d,",
139 	    (defred[0] ? defred[0] - 2 : 0));
140 
141     j = 10;
142     for (i = 1; i < nstates; i++)
143     {
144 	if (j < 10)
145 	    ++j;
146 	else
147 	{
148 	    if (!rflag) ++outline;
149 	    putc('\n', output_file);
150 	    j = 1;
151 	}
152 
153 	fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
154     }
155 
156     if (!rflag) outline += 2;
157     fprintf(output_file, "\n};\n");
158 }
159 
160 
output_actions(void)161 void output_actions(void)
162 {
163     nvectors = 2*nstates + nvars;
164 
165     froms = NEW2(nvectors, short *);
166     tos = NEW2(nvectors, short *);
167     tally = NEW2(nvectors, short);
168     width = NEW2(nvectors, short);
169 
170     token_actions();
171     FREE(lookaheads);
172     FREE(LA);
173     FREE(LAruleno);
174     FREE(accessing_symbol);
175 
176     goto_actions();
177     FREE(goto_map + ntokens);
178     FREE(from_state);
179     FREE(to_state);
180 
181     sort_actions();
182     pack_table();
183     output_base();
184     output_table();
185     output_check();
186 }
187 
188 
token_actions(void)189 void token_actions(void)
190 {
191 int i, j;
192 int shiftcount, reducecount;
193 int max, min;
194 short *actionrow, *r, *s;
195 action *p;
196 
197     actionrow = NEW2(2*ntokens, short);
198     for (i = 0; i < nstates; ++i)
199     {
200 	if (parser[i])
201 	{
202 	    for (j = 0; j < 2*ntokens; ++j)
203 	    actionrow[j] = 0;
204 
205 	    shiftcount = 0;
206 	    reducecount = 0;
207 	    for (p = parser[i]; p; p = p->next)
208 	    {
209 		if (p->suppressed == 0)
210 		{
211 		    if (p->action_code == SHIFT)
212 		    {
213 			++shiftcount;
214 			actionrow[p->symbol] = p->number;
215 		    }
216 		    else if (p->action_code == REDUCE && p->number != defred[i])
217 		    {
218 			++reducecount;
219 			actionrow[p->symbol + ntokens] = p->number;
220 		    }
221 		}
222 	    }
223 
224 	    tally[i] = shiftcount;
225 	    tally[nstates+i] = reducecount;
226 	    width[i] = 0;
227 	    width[nstates+i] = 0;
228 	    if (shiftcount > 0)
229 	    {
230 		froms[i] = r = NEW2(shiftcount, short);
231 		tos[i] = s = NEW2(shiftcount, short);
232 		min = MAXSHORT;
233 		max = 0;
234 		for (j = 0; j < ntokens; ++j)
235 		{
236 		    if (actionrow[j])
237 		    {
238 			if (min > symbol_value[j])
239 			    min = symbol_value[j];
240 			if (max < symbol_value[j])
241 			    max = symbol_value[j];
242 			*r++ = symbol_value[j];
243 			*s++ = actionrow[j];
244 		    }
245 		}
246 		width[i] = max - min + 1;
247 	    }
248 	    if (reducecount > 0)
249 	    {
250 		froms[nstates+i] = r = NEW2(reducecount, short);
251 		tos[nstates+i] = s = NEW2(reducecount, short);
252 		min = MAXSHORT;
253 		max = 0;
254 		for (j = 0; j < ntokens; ++j)
255 		{
256 		    if (actionrow[ntokens+j])
257 		    {
258 			if (min > symbol_value[j])
259 			    min = symbol_value[j];
260 			if (max < symbol_value[j])
261 			    max = symbol_value[j];
262 			*r++ = symbol_value[j];
263 			*s++ = actionrow[ntokens+j] - 2;
264 		    }
265 		}
266 		width[nstates+i] = max - min + 1;
267 	    }
268 	}
269     }
270     FREE(actionrow);
271 }
272 
goto_actions(void)273 void goto_actions(void)
274 {
275     register int i, j, k;
276 
277     state_count = NEW2(nstates, short);
278 
279     k = default_goto(start_symbol + 1);
280     if (jflag)  /*rwj*/
281       fprintf(output_file, "final static short yydgoto[] = {%27d,",k);
282     else
283       fprintf(output_file, "short yydgoto[] = {%40d,", k);
284     save_column(start_symbol + 1, k);
285 
286     j = 10;
287     for (i = start_symbol + 2; i < nsyms; i++)
288     {
289 	if (j >= 10)
290 	{
291 	    if (!rflag) ++outline;
292 	    putc('\n', output_file);
293 	    j = 1;
294 	}
295 	else
296 	    ++j;
297 
298 	k = default_goto(i);
299 	fprintf(output_file, "%5d,", k);
300 	save_column(i, k);
301     }
302 
303     if (!rflag) outline += 2;
304     fprintf(output_file, "\n};\n");
305     FREE(state_count);
306 }
307 
default_goto(int symbol)308 int default_goto(int symbol)
309 {
310 int i;
311 int m;
312 int n;
313 int default_state;
314 int max;
315 
316     m = goto_map[symbol];
317     n = goto_map[symbol + 1];
318 
319     if (m == n) return (0);
320 
321     for (i = 0; i < nstates; i++)
322 	state_count[i] = 0;
323 
324     for (i = m; i < n; i++)
325 	state_count[to_state[i]]++;
326 
327     max = 0;
328     default_state = 0;
329     for (i = 0; i < nstates; i++)
330     {
331 	if (state_count[i] > max)
332 	{
333 	    max = state_count[i];
334 	    default_state = i;
335 	}
336     }
337 
338     return (default_state);
339 }
340 
341 
342 
save_column(int symbol,int default_state)343 void save_column(int symbol,int default_state)
344 {
345 int i;
346 int m;
347 int n;
348 short *sp;
349 short *sp1;
350 short *sp2;
351 int count;
352 int symno;
353 
354     m = goto_map[symbol];
355     n = goto_map[symbol + 1];
356 
357     count = 0;
358     for (i = m; i < n; i++)
359     {
360 	if (to_state[i] != default_state)
361 	    ++count;
362     }
363     if (count == 0) return;
364 
365     symno = symbol_value[symbol] + 2*nstates;
366 
367     froms[symno] = sp1 = sp = NEW2(count, short);
368     tos[symno] = sp2 = NEW2(count, short);
369 
370     for (i = m; i < n; i++)
371     {
372 	if (to_state[i] != default_state)
373 	{
374 	    *sp1++ = from_state[i];
375 	    *sp2++ = to_state[i];
376 	}
377     }
378 
379     tally[symno] = count;
380     width[symno] = sp1[-1] - sp[0] + 1;
381 }
382 
sort_actions(void)383 void sort_actions(void)
384 {
385 int i;
386 int j;
387 int k;
388 int t;
389 int w;
390 
391   order = NEW2(nvectors, short);
392   nentries = 0;
393 
394   for (i = 0; i < nvectors; i++)
395     {
396       if (tally[i] > 0)
397 	{
398 	  t = tally[i];
399 	  w = width[i];
400 	  j = nentries - 1;
401 
402 	  while (j >= 0 && (width[order[j]] < w))
403 	    j--;
404 
405 	  while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
406 	    j--;
407 
408 	  for (k = nentries - 1; k > j; k--)
409 	    order[k + 1] = order[k];
410 
411 	  order[j + 1] = i;
412 	  nentries++;
413 	}
414     }
415 }
416 
417 
pack_table(void)418 void pack_table(void)
419 {
420 int i;
421 int place;
422 int state;
423 
424     base = NEW2(nvectors, short);
425     pos = NEW2(nentries, short);
426 
427     maxtable = 1000;
428     table = NEW2(maxtable, short);
429     check = NEW2(maxtable, short);
430 
431     lowzero = 0;
432     high = 0;
433 
434     for (i = 0; i < maxtable; i++)
435 	check[i] = -1;
436 
437     for (i = 0; i < nentries; i++)
438     {
439 	state = matching_vector(i);
440 
441 	if (state < 0)
442 	    place = pack_vector(i);
443 	else
444 	    place = base[state];
445 
446 	pos[i] = place;
447 	base[order[i]] = place;
448     }
449 
450     for (i = 0; i < nvectors; i++)
451     {
452 	if (froms[i])
453 	    FREE(froms[i]);
454 	if (tos[i])
455 	    FREE(tos[i]);
456     }
457 
458     FREE(froms);
459     FREE(tos);
460     FREE(pos);
461 }
462 
463 
464 /*  The function matching_vector determines if the vector specified by	*/
465 /*  the input parameter matches a previously considered	vector.  The	*/
466 /*  test at the start of the function checks if the vector represents	*/
467 /*  a row of shifts over terminal symbols or a row of reductions, or a	*/
468 /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not	*/
469 /*  check if a column of shifts over a nonterminal symbols matches a	*/
470 /*  previously considered vector.  Because of the nature of LR parsing	*/
471 /*  tables, no two columns can match.  Therefore, the only possible	*/
472 /*  match would be between a row and a column.  Such matches are	*/
473 /*  unlikely.  Therefore, to save time, no attempt is made to see if a	*/
474 /*  column matches a previously considered vector.			*/
475 /*									*/
476 /*  Matching_vector is poorly designed.  The test could easily be made	*/
477 /*  faster.  Also, it depends on the vectors being in a specific	*/
478 /*  order.								*/
479 
matching_vector(int vector)480 int matching_vector(int vector)
481 {
482 int i;
483 int j;
484 int k;
485 int t;
486 int w;
487 int match;
488 int prev;
489 
490     i = order[vector];
491     if (i >= 2*nstates)
492 	return (-1);
493 
494     t = tally[i];
495     w = width[i];
496 
497     for (prev = vector - 1; prev >= 0; prev--)
498     {
499 	j = order[prev];
500 	if (width[j] != w || tally[j] != t)
501 	    return (-1);
502 
503 	match = 1;
504 	for (k = 0; match && k < t; k++)
505 	{
506 	    if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
507 		match = 0;
508 	}
509 
510 	if (match)
511 	    return (j);
512     }
513 
514     return (-1);
515 }
516 
517 
518 
pack_vector(int vector)519 int pack_vector(int vector)
520 {
521 int i, j, k, l;
522 int t;
523 int loc;
524 int ok;
525 short *from;
526 short *to;
527 int newmax;
528 
529     i = order[vector];
530     t = tally[i];
531     assert(t);
532 
533     from = froms[i];
534     to = tos[i];
535 
536     j = lowzero - from[0];
537     for (k = 1; k < t; ++k)
538 	if (lowzero - from[k] > j)
539 	    j = lowzero - from[k];
540     for (;; ++j)
541     {
542 	if (j == 0)
543 	    continue;
544 	ok = 1;
545 	for (k = 0; ok && k < t; k++)
546 	{
547 	    loc = j + from[k];
548 	    if (loc >= maxtable)
549 	    {
550 		if (loc >= MAXTABLE)
551 		    fatal("maximum table size exceeded");
552 
553 		newmax = maxtable;
554 		do { newmax += 200; } while (newmax <= loc);
555 		table = (short *) REALLOC(table, newmax*sizeof(short));
556 		if (table == 0) no_space();
557 		check = (short *) REALLOC(check, newmax*sizeof(short));
558 		if (check == 0) no_space();
559 		for (l  = maxtable; l < newmax; ++l)
560 		{
561 		    table[l] = 0;
562 		    check[l] = -1;
563 		}
564 		maxtable = newmax;
565 	    }
566 
567 	    if (check[loc] != -1)
568 		ok = 0;
569 	}
570 	for (k = 0; ok && k < vector; k++)
571 	{
572 	    if (pos[k] == j)
573 		ok = 0;
574 	}
575 	if (ok)
576 	{
577 	    for (k = 0; k < t; k++)
578 	    {
579 		loc = j + from[k];
580 		table[loc] = to[k];
581 		check[loc] = from[k];
582 		if (loc > high) high = loc;
583 	    }
584 
585 	    while (check[lowzero] != -1)
586 		++lowzero;
587 
588 	    return (j);
589 	}
590     }
591 }
592 
593 
594 
output_base(void)595 void output_base(void)
596 {
597 int i, j;
598 
599     if (jflag)  /*rwj*/
600       fprintf(output_file, "final static short yysindex[] = {%26d,",base[0]);
601     else
602       fprintf(output_file, "short yysindex[] = {%39d,", base[0]);
603 
604     j = 10;
605     for (i = 1; i < nstates; i++)
606     {
607 	if (j >= 10)
608 	{
609 	    if (!rflag) ++outline;
610 	    putc('\n', output_file);
611 	    j = 1;
612 	}
613 	else
614 	    ++j;
615 
616 	fprintf(output_file, "%5d,", base[i]);
617     }
618 
619     if (!rflag) outline += 2;
620 
621     if (jflag) /*rwj*/
622       fprintf(output_file, "\n};\nfinal static short yyrindex[] = {%26d,",
623 	    base[nstates]);
624     else
625       fprintf(output_file, "\n};\nshort yyrindex[] = {%39d,",
626 	    base[nstates]);
627 
628     j = 10;
629     for (i = nstates + 1; i < 2*nstates; i++)
630     {
631 	if (j >= 10)
632 	{
633 	    if (!rflag) ++outline;
634 	    putc('\n', output_file);
635 	    j = 1;
636 	}
637 	else
638 	    ++j;
639 
640 	fprintf(output_file, "%5d,", base[i]);
641     }
642 
643     if (!rflag) outline += 2;
644     if (jflag)/*rwj*/
645       fprintf(output_file, "\n};\nfinal static short yygindex[] = {%26d,",
646 	    base[2*nstates]);
647     else
648       fprintf(output_file, "\n};\nshort yygindex[] = {%39d,",
649 	    base[2*nstates]);
650 
651     j = 10;
652     for (i = 2*nstates + 1; i < nvectors - 1; i++)
653     {
654 	if (j >= 10)
655 	{
656 	    if (!rflag) ++outline;
657 	    putc('\n', output_file);
658 	    j = 1;
659 	}
660 	else
661 	    ++j;
662 
663 	fprintf(output_file, "%5d,", base[i]);
664     }
665 
666     if (!rflag) outline += 2;
667     fprintf(output_file, "\n};\n");
668     FREE(base);
669 }
670 
671 
672 
output_table(void)673 void output_table(void)
674 {
675 int i;
676 int j;
677 
678     ++outline;
679     if (jflag)  /*rwj*/
680       {
681       fprintf(code_file, "final static int YYTABLESIZE=%d;\n", high);
682       fprintf(output_file, "static short yytable[];\nstatic { yytable();}\nstatic void yytable(){\nyytable = new short[]{%27d,", table[0]);
683       }
684     else
685       {
686       fprintf(code_file, "#define YYTABLESIZE %d\n", high);
687       fprintf(output_file, "short yytable[] = {%40d,", table[0]);
688       }
689 
690     j = 10;
691     for (i = 1; i <= high; i++)
692     {
693 	if (j >= 10)
694 	{
695 	    if (!rflag) ++outline;
696 	    putc('\n', output_file);
697 	    j = 1;
698 	}
699 	else
700 	    ++j;
701 
702 	fprintf(output_file, "%5d,", table[i]);
703     }
704 
705     if (!rflag) outline += 2;
706     fprintf(output_file, "\n};\n");
707     if (jflag)
708       fprintf(output_file, "}\n");
709     FREE(table);
710 }
711 
712 
713 
output_check(void)714 void output_check(void)
715 {
716     register int i;
717     register int j;
718 
719     if (jflag)   /*rwj*/
720       fprintf(output_file, "static short yycheck[];\nstatic { yycheck(); }\nstatic void yycheck() {\nyycheck = new short[] {%27d,",check[0]);
721     else
722       fprintf(output_file, "short yycheck[] = {%40d,", check[0]);
723 
724     j = 10;
725     for (i = 1; i <= high; i++)
726     {
727 	if (j >= 10)
728 	{
729 	    if (!rflag) ++outline;
730 	    putc('\n', output_file);
731 	    j = 1;
732 	}
733 	else
734 	    ++j;
735 
736 	fprintf(output_file, "%5d,", check[i]);
737     }
738 
739     if (!rflag) outline += 2;
740     fprintf(output_file, "\n};\n");
741     if (jflag)
742       fprintf(output_file, "}\n");
743     FREE(check);
744 }
745 
746 
is_C_identifier(char * name)747 int is_C_identifier(char *name)
748 {
749 char *s;
750 int c;
751 
752     s = name;
753     c = *s;
754     if (c == '"')
755     {
756 	c = *++s;
757 	if (!isalpha(c) && c != '_' && c != '$')
758 	    return (0);
759 	while ((c = *++s) != '"')
760 	{
761 	    if (!isalnum(c) && c != '_' && c != '$')
762 		return (0);
763 	}
764 	return (1);
765     }
766 
767     if (!isalpha(c) && c != '_' && c != '$')
768 	return (0);
769     while ((c = *++s)!=0)
770     {
771 	if (!isalnum(c) && c != '_' && c != '$')
772 	    return (0);
773     }
774     return (1);
775 }
776 
777 
output_defines(void)778 void output_defines(void)
779 {
780 int c, i;
781 char *s;
782 
783     if (jflag && dflag)
784     {
785         if (jpackage_name && strlen(jpackage_name)>0)
786             fprintf(defines_file,"package %s;\n",jpackage_name);
787 	fprintf(defines_file, "public interface %s%s {\n",jclass_name,JAVA_INTERFACE_SUFFIX);
788     }
789     for (i = 2; i < ntokens; ++i)
790     {
791 	s = symbol_name[i];
792 	if (is_C_identifier(s))
793 	{
794 	    if (jflag)    /*rwj*/
795                 fprintf(dflag?defines_file:code_file, "public final static short ");
796 	    else
797 	    {
798                 fprintf(code_file, "#define ");
799                 if (dflag) fprintf(defines_file, "#define ");
800             }
801 	    c = *s;
802 	    if (c == '"')
803 	    {
804 		while ((c = *++s) != '"')
805 		{
806 		    if (!jflag || (jflag && !dflag)) putc(c, code_file);
807 		    if (dflag) putc(c, defines_file);
808 		}
809 	    }
810 	    else
811 	    {
812 		do
813 		{
814 		    if (!jflag || (jflag && !dflag)) putc(c, code_file);
815 		    if (dflag) putc(c, defines_file);
816 		}
817 		while ((c = *++s)!=0);
818 	    }
819 	    ++outline;
820 	    if (jflag)  /*rwj*/
821                 fprintf(dflag?defines_file:code_file, "=%d;\n", symbol_value[i]);
822 	    else
823             {
824                 fprintf(code_file, " %d\n", symbol_value[i]);
825                 if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]);
826             }
827 	}
828     }
829 
830     ++outline;
831     if (jflag) /*rwj*/
832       fprintf(code_file, "public final static short YYERRCODE=%d;\n", symbol_value[1]);
833     else
834       fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
835 
836     if (dflag && unionized)
837     {
838 	fclose(union_file);
839 	union_file = fopen(union_file_name, "r");
840 	if (union_file == NULL) open_error(union_file_name);
841 	while ((c = getc(union_file)) != EOF)
842 	    putc(c, defines_file);
843 	fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE yylval;\n");
844     }
845     if (jflag && dflag)
846 	fprintf(defines_file, "}\n",jclass_name,JAVA_INTERFACE_SUFFIX);
847 }
848 
849 
output_stored_text(void)850 void output_stored_text(void)
851 {
852 int c;
853 FILE *in, *out;
854 
855     fclose(text_file);
856     text_file = fopen(text_file_name, "r");
857     if (text_file == NULL)
858 	open_error(text_file_name);
859     in = text_file;
860     if ((c = getc(in)) == EOF)
861 	return;
862     out = code_file;
863     if (c ==  '\n')
864 	++outline;
865     putc(c, out);
866     while ((c = getc(in)) != EOF)
867     {
868 	if (c == '\n')
869 	    ++outline;
870 	putc(c, out);
871     }
872     if (!lflag)
873       if (jflag)/*rwj*/
874 	fprintf(out, jline_format, ++outline + 1, code_file_name);
875       else
876 	fprintf(out, line_format, ++outline + 1, code_file_name);
877 }
878 
879 
output_debug(void)880 void output_debug(void)
881 {
882 int i, j, k, max;
883 char **symnam, *s;
884 
885     ++outline;
886     if (jflag)  /*rwj*/
887       fprintf(code_file, "final static short YYFINAL=%d;\n", final_state);
888     else
889       fprintf(code_file, "#define YYFINAL %d\n", final_state);
890     outline += 3;
891     if (!jflag)/*rwj*/
892       fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
893 	    tflag);
894     if (rflag)
895 	fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
896 		tflag);
897 
898     max = 0;
899     for (i = 2; i < ntokens; ++i)
900 	if (symbol_value[i] > max)
901 	    max = symbol_value[i];
902     ++outline;
903     if (jflag) /*rjw*/
904       fprintf(code_file, "final static short YYMAXTOKEN=%d;\n", max);
905     else
906       fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
907 
908     symnam = (char **) MALLOC((max+1)*sizeof(char *));
909     if (symnam == 0) no_space();
910 
911     /* Note that it is  not necessary to initialize the element		*/
912     /* symnam[max].							*/
913     for (i = 0; i < max; ++i)
914 	symnam[i] = 0;
915     for (i = ntokens - 1; i >= 2; --i)
916 	symnam[symbol_value[i]] = symbol_name[i];
917     symnam[0] = "end-of-file";
918 
919     if (!rflag) ++outline;
920     if (jflag)/*rwj*/
921       fprintf(output_file, "final static String yyname[] = {");
922     else
923       fprintf(output_file, "#if YYDEBUG\nchar *yyname[] = {");
924     j = 80;
925     for (i = 0; i <= max; ++i)
926     {
927 	if ((s = symnam[i])!=0)
928 	{
929 	    if (s[0] == '"')
930 	    {
931 		k = 7;
932 		while (*++s != '"')
933 		{
934 		    ++k;
935 		    if (*s == '\\')
936 		    {
937 			k += 2;
938 			if (*++s == '\\')
939 			    ++k;
940 		    }
941 		}
942 		j += k;
943 		if (j > 80)
944 		{
945 		    if (!rflag) ++outline;
946 		    putc('\n', output_file);
947 		    j = k;
948 		}
949 		fprintf(output_file, "\"\\\"");
950 		s = symnam[i];
951 		while (*++s != '"')
952 		{
953 		    if (*s == '\\')
954 		    {
955 			fprintf(output_file, "\\\\");
956 			if (*++s == '\\')
957 			    fprintf(output_file, "\\\\");
958 			else
959 			    putc(*s, output_file);
960 		    }
961 		    else
962 			putc(*s, output_file);
963 		}
964 		fprintf(output_file, "\\\"\",");
965 	    }
966 	    else if (s[0] == '\'')
967 	    {
968 		if (s[1] == '"')
969 		{
970 		    j += 7;
971 		    if (j > 80)
972 		    {
973 			if (!rflag) ++outline;
974 			putc('\n', output_file);
975 			j = 7;
976 		    }
977 		    fprintf(output_file, "\"'\\\"'\",");
978 		}
979 		else
980 		{
981 		    k = 5;
982 		    while (*++s != '\'')
983 		    {
984 			++k;
985 			if (*s == '\\')
986 			{
987 			    k += 2;
988 			    if (*++s == '\\')
989 				++k;
990 			}
991 		    }
992 		    j += k;
993 		    if (j > 80)
994 		    {
995 			if (!rflag) ++outline;
996 			putc('\n', output_file);
997 			j = k;
998 		    }
999 		    fprintf(output_file, "\"'");
1000 		    s = symnam[i];
1001 		    while (*++s != '\'')
1002 		    {
1003 			if (*s == '\\')
1004 			{
1005 			    fprintf(output_file, "\\\\");
1006 			    if (*++s == '\\')
1007 				fprintf(output_file, "\\\\");
1008 			    else
1009 				putc(*s, output_file);
1010 			}
1011 			else
1012 			    putc(*s, output_file);
1013 		    }
1014 		    fprintf(output_file, "'\",");
1015 		}
1016 	    }
1017 	    else
1018 	    {
1019 		k = strlen(s) + 3;
1020 		j += k;
1021 		if (j > 80)
1022 		{
1023 		    if (!rflag) ++outline;
1024 		    putc('\n', output_file);
1025 		    j = k;
1026 		}
1027 		putc('"', output_file);
1028 		do { putc(*s, output_file); } while (*++s);
1029 		fprintf(output_file, "\",");
1030 	    }
1031 	}
1032 	else
1033 	{
1034 	if (jflag)/*rwj -- null strings should be 'null'*/
1035 	    {
1036 	    j += 5;
1037 	    if (j > 80)
1038 	    {
1039 		if (!rflag) ++outline;
1040 		putc('\n', output_file);
1041 		j = 5;
1042 	    }
1043 	    fprintf(output_file, "null,");
1044 	    }
1045 	  else /*rwj -- not jflag, output a 0*/
1046 	    {
1047 	    j += 2;
1048 	    if (j > 80)
1049 	    {
1050 		if (!rflag) ++outline;
1051 		putc('\n', output_file);
1052 		j = 2;
1053 	    }
1054 	    fprintf(output_file, "0,");
1055 	    }
1056 	}
1057     }
1058     if (!rflag) outline += 2;
1059     fprintf(output_file, "\n};\n");
1060     FREE(symnam);
1061 
1062     if (!rflag) ++outline;
1063     if (jflag)/*rwj*/
1064       fprintf(output_file, "final static String yyrule[] = {\n");
1065     else
1066       fprintf(output_file, "char *yyrule[] = {\n");
1067     for (i = 2; i < nrules; ++i)
1068     {
1069 	fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1070 	for (j = rrhs[i]; ritem[j] > 0; ++j)
1071 	{
1072 	    s = symbol_name[ritem[j]];
1073 	    if (s[0] == '"')
1074 	    {
1075 		fprintf(output_file, " \\\"");
1076 		while (*++s != '"')
1077 		{
1078 		    if (*s == '\\')
1079 		    {
1080 			if (s[1] == '\\')
1081 			    fprintf(output_file, "\\\\\\\\");
1082 			else
1083 			    fprintf(output_file, "\\\\%c", s[1]);
1084 			++s;
1085 		    }
1086 		    else
1087 			putc(*s, output_file);
1088 		}
1089 		fprintf(output_file, "\\\"");
1090 	    }
1091 	    else if (s[0] == '\'')
1092 	    {
1093 		if (s[1] == '"')
1094 		    fprintf(output_file, " '\\\"'");
1095 		else if (s[1] == '\\')
1096 		{
1097 		    if (s[2] == '\\')
1098 			fprintf(output_file, " '\\\\\\\\");
1099 		    else
1100 			fprintf(output_file, " '\\\\%c", s[2]);
1101 		    s += 2;
1102 		    while (*++s != '\'')
1103 			putc(*s, output_file);
1104 		    putc('\'', output_file);
1105 		}
1106 		else
1107 		    fprintf(output_file, " '%c'", s[1]);
1108 	    }
1109 	    else
1110 		fprintf(output_file, " %s", s);
1111 	}
1112 	if (!rflag) ++outline;
1113 	fprintf(output_file, "\",\n");
1114     }
1115 
1116     if (!rflag) outline += 2;
1117     if (jflag)/*rwj*/
1118       fprintf(output_file, "};\n\n");
1119     else
1120       fprintf(output_file, "};\n#endif\n");
1121 }
1122 
output_stype(void)1123 void output_stype(void)
1124 {
1125 int prim; /*is the Java semantic type a primitive?*/
1126 char filenam[128];
1127 
1128 char *jvalclass; /* either [Parser]Val or a user-defined class */
1129 
1130 FILE *f;
1131   if (jflag)/*rwj*/
1132     {
1133 	jvalclass = (char *) MALLOC(strlen(jclass_name) + 4);  /* Val\0 */
1134 	sprintf(jvalclass,"%sVal",jclass_name);
1135 
1136     if (jsemantic_type && strlen(jsemantic_type)>0)/*specific type requested*/
1137       {
1138     char *raw_type=jsemantic_type;
1139     if (strcmp(jsemantic_type,"byte")==0 ||
1140         strcmp(jsemantic_type,"short")==0 ||
1141         strcmp(jsemantic_type,"char")==0 ||
1142         strcmp(jsemantic_type,"int")==0 ||
1143         strcmp(jsemantic_type,"long")==0 ||
1144         strcmp(jsemantic_type,"float")==0 ||
1145         strcmp(jsemantic_type,"double")==0) {
1146        prim=1;
1147     } else {
1148        prim=0;
1149        char *end=strchr(jsemantic_type,'<');
1150        if (end!=NULL) {
1151          raw_type=(char *)CALLOC(end-jsemantic_type+1,sizeof(char));
1152          strncpy(raw_type,jsemantic_type,end-jsemantic_type);
1153        }
1154     }
1155     fprintf(code_file,"\n\n//########## SEMANTIC VALUES ##########\n");
1156     fprintf(code_file,"//## **user defined:%s\n",jsemantic_type);
1157     fprintf(code_file,"String   yytext;//user variable to return contextual strings\n");
1158     fprintf(code_file,"%s yyval; //used to return semantic vals from action routines\n",
1159                           jsemantic_type);
1160     fprintf(code_file,"%s yylval;//the 'lval' (result) I got from yylex()\n",
1161                           jsemantic_type);
1162     fprintf(code_file,"%s valstk[] = new %s[YYSTACKSIZE];\n",
1163                           jsemantic_type,raw_type);
1164     fprintf(code_file,"int valptr;\n");
1165     fprintf(code_file,"//###############################################################\n");
1166     fprintf(code_file,"// methods: value stack push,pop,drop,peek.\n");
1167     fprintf(code_file,"//###############################################################\n");
1168     fprintf(code_file,"final void val_init()\n");
1169     fprintf(code_file,"{\n");
1170     if (prim)
1171       {
1172       fprintf(code_file,"  yyval=(%s)0;\n",jsemantic_type);
1173       fprintf(code_file,"  yylval=(%s)0;\n",jsemantic_type);
1174       }
1175     else
1176       {
1177       fprintf(code_file,"  yyval=new %s();\n",jsemantic_type);  /*fix 980108*/
1178       fprintf(code_file,"  yylval=new %s();\n",jsemantic_type); /* ditto */
1179       }
1180     fprintf(code_file,"  valptr=-1;\n");
1181     fprintf(code_file,"}\n");
1182     fprintf(code_file,"final void val_push(%s val)\n",jsemantic_type);
1183     fprintf(code_file,"{\n");
1184     fprintf(code_file,"  try {\n");
1185     fprintf(code_file,"    valptr++;\n");
1186 	fprintf(code_file,"    valstk[valptr]=val;\n");
1187 	fprintf(code_file,"  }\n");
1188 	fprintf(code_file,"  catch (ArrayIndexOutOfBoundsException e) {\n");
1189 	fprintf(code_file,"    int oldsize = valstk.length;\n");
1190 	fprintf(code_file,"    int newsize = oldsize*2;\n");
1191 	fprintf(code_file,"    %s[] newstack = new %s[newsize];\n",jsemantic_type,raw_type);
1192 	fprintf(code_file,"    System.arraycopy(valstk,0,newstack,0,oldsize);\n");
1193 	fprintf(code_file,"    valstk = newstack;\n");
1194 	fprintf(code_file,"    valstk[valptr]=val;\n");
1195 	fprintf(code_file,"  }\n");
1196     fprintf(code_file,"}\n");
1197     fprintf(code_file,"final %s val_pop()\n",jsemantic_type);
1198     fprintf(code_file,"{\n");
1199     fprintf(code_file,"  return valstk[valptr--];\n");
1200     fprintf(code_file,"}\n");
1201     fprintf(code_file,"final void val_drop(int cnt)\n");
1202     fprintf(code_file,"{\n");
1203 	fprintf(code_file,"  valptr -= cnt;\n");
1204     fprintf(code_file,"}\n");
1205     fprintf(code_file,"final %s val_peek(int relative)\n",jsemantic_type);
1206     fprintf(code_file,"{\n");
1207 	fprintf(code_file,"  return valstk[valptr-relative];\n");
1208     fprintf(code_file,"}\n");
1209     fprintf(code_file,"final %s dup_yyval(%s val)\n",jsemantic_type,jsemantic_type);
1210     fprintf(code_file,"{\n");
1211     fprintf(code_file,"  return val;\n");
1212     fprintf(code_file,"}\n");
1213     fprintf(code_file,"//#### end semantic value section ####\n");
1214       }
1215 
1216     else /*no definition -- use our semantic class*/
1217       {
1218     fprintf(code_file,"\n\n//########## SEMANTIC VALUES ##########\n");
1219 
1220 	fprintf(code_file,"//public class %s is defined in %s.java\n\n\n",
1221                     jvalclass,jvalclass);
1222 
1223 	sprintf(filenam,"%s.java",jvalclass);
1224 	f=fopen(filenam,"w");
1225 	if (!f)
1226 	  return;
1227 	fprintf(f,"//#############################################\n");
1228 	fprintf(f,"//## file: %s.java\n",jclass_name);
1229 	fprintf(f,"//## Generated by Byacc/j\n");
1230 	fprintf(f,"//#############################################\n");
1231 	if (jpackage_name && strlen(jpackage_name)>0)
1232 	  fprintf(f,"package %s;\n\n",jpackage_name);
1233 	fprintf(f,"/**\n");
1234 	fprintf(f," * BYACC/J Semantic Value for parser: %s\n",jclass_name);
1235 	fprintf(f," * This class provides some of the functionality\n");
1236 	fprintf(f," * of the yacc/C 'union' directive\n");
1237 	fprintf(f," */\n");
1238 
1239 	/* yio 20020304: option to make the class final */
1240 	if (jfinal_class == TRUE)
1241 		fprintf(f,"final ");
1242 
1243 	fprintf(f,"public class %s\n",jvalclass);
1244 	fprintf(f,"{\n");
1245 	fprintf(f,"/**\n");
1246 	fprintf(f," * integer value of this 'union'\n");
1247 	fprintf(f," */\n");
1248 	fprintf(f,"public int ival;\n");
1249 	fprintf(f,"\n");
1250 	fprintf(f,"/**\n");
1251 	fprintf(f," * double value of this 'union'\n");
1252 	fprintf(f," */\n");
1253 	fprintf(f,"public double dval;\n");
1254 	fprintf(f,"\n");
1255 	fprintf(f,"/**\n");
1256 	fprintf(f," * string value of this 'union'\n");
1257 	fprintf(f," */\n");
1258 	fprintf(f,"public String sval;\n");
1259 	fprintf(f,"\n");
1260 	fprintf(f,"/**\n");
1261 	fprintf(f," * object value of this 'union'\n");
1262 	fprintf(f," */\n");
1263 	fprintf(f,"public Object obj;\n");
1264 	fprintf(f,"\n");
1265 	fprintf(f,"//#############################################\n");
1266 	fprintf(f,"//## C O N S T R U C T O R S\n");
1267 	fprintf(f,"//#############################################\n");
1268 	fprintf(f,"/**\n");
1269 	fprintf(f," * Initialize me without a value\n");
1270 	fprintf(f," */\n");
1271 	fprintf(f,"public %s()\n",jvalclass);
1272 	fprintf(f,"{\n");
1273 	fprintf(f,"}\n");
1274 	fprintf(f,"/**\n");
1275 	fprintf(f," * Initialize me as an int\n");
1276 	fprintf(f," */\n");
1277 	fprintf(f,"public %s(int val)\n",jvalclass);
1278 	fprintf(f,"{\n");
1279 	fprintf(f,"  ival=val;\n");
1280 	fprintf(f,"}\n");
1281 	fprintf(f,"\n");
1282 	fprintf(f,"/**\n");
1283 	fprintf(f," * Initialize me as a double\n");
1284 	fprintf(f," */\n");
1285 	fprintf(f,"public %s(double val)\n",jvalclass);
1286 	fprintf(f,"{\n");
1287 	fprintf(f,"  dval=val;\n");
1288 	fprintf(f,"}\n");
1289 	fprintf(f,"\n");
1290 	fprintf(f,"/**\n");
1291 	fprintf(f," * Initialize me as a string\n");
1292 	fprintf(f," */\n");
1293 	fprintf(f,"public %s(String val)\n",jvalclass);
1294 	fprintf(f,"{\n");
1295 	fprintf(f,"  sval=val;\n");
1296 	fprintf(f,"}\n");
1297 	fprintf(f,"\n");
1298 	fprintf(f,"/**\n");
1299 	fprintf(f," * Initialize me as an Object\n");
1300 	fprintf(f," */\n");
1301 	fprintf(f,"public %s(Object val)\n",jvalclass);
1302 	fprintf(f,"{\n");
1303 	fprintf(f,"  obj=val;\n");
1304 	fprintf(f,"}\n");
1305 	fprintf(f,"}//end class\n\n");
1306 	fprintf(f,"//#############################################\n");
1307 	fprintf(f,"//## E N D    O F    F I L E\n");
1308 	fprintf(f,"//#############################################\n");
1309 	fclose(f);
1310 
1311 
1312     fprintf(code_file,"String   yytext;//user variable to return contextual strings\n");
1313     fprintf(code_file,"%s yyval; //used to return semantic vals from action routines\n",jvalclass);
1314     fprintf(code_file,"%s yylval;//the 'lval' (result) I got from yylex()\n",jvalclass);
1315     fprintf(code_file,"%s valstk[];\n",jvalclass);
1316     fprintf(code_file,"int valptr;\n");
1317     fprintf(code_file,"//###############################################################\n");
1318     fprintf(code_file,"// methods: value stack push,pop,drop,peek.\n");
1319     fprintf(code_file,"//###############################################################\n");
1320     fprintf(code_file,"void val_init()\n");
1321     fprintf(code_file,"{\n");
1322     fprintf(code_file,"  valstk=new %s[YYSTACKSIZE];\n",jvalclass);
1323     fprintf(code_file,"  yyval=new %s();\n",jvalclass);
1324     fprintf(code_file,"  yylval=new %s();\n",jvalclass);
1325     fprintf(code_file,"  valptr=-1;\n");
1326     fprintf(code_file,"}\n");
1327     fprintf(code_file,"void val_push(%s val)\n",jvalclass);
1328     fprintf(code_file,"{\n");
1329     fprintf(code_file,"  if (valptr>=YYSTACKSIZE)\n");
1330     fprintf(code_file,"    return;\n");
1331     fprintf(code_file,"  valstk[++valptr]=val;\n");
1332     fprintf(code_file,"}\n");
1333     fprintf(code_file,"%s val_pop()\n",jvalclass);
1334     fprintf(code_file,"{\n");
1335     fprintf(code_file,"  if (valptr<0)\n");
1336     fprintf(code_file,"    return new %s();\n",jvalclass);
1337     fprintf(code_file,"  return valstk[valptr--];\n");
1338     fprintf(code_file,"}\n");
1339     fprintf(code_file,"void val_drop(int cnt)\n");
1340     fprintf(code_file,"{\n");
1341     fprintf(code_file,"int ptr;\n");
1342     fprintf(code_file,"  ptr=valptr-cnt;\n");
1343     fprintf(code_file,"  if (ptr<0)\n");
1344     fprintf(code_file,"    return;\n");
1345     fprintf(code_file,"  valptr = ptr;\n");
1346     fprintf(code_file,"}\n");
1347     fprintf(code_file,"%s val_peek(int relative)\n",jvalclass);
1348     fprintf(code_file,"{\n");
1349     fprintf(code_file,"int ptr;\n");
1350     fprintf(code_file,"  ptr=valptr-relative;\n");
1351     fprintf(code_file,"  if (ptr<0)\n");
1352     fprintf(code_file,"    return new %s();\n",jvalclass);
1353     fprintf(code_file,"  return valstk[ptr];\n");
1354     fprintf(code_file,"}\n");
1355     fprintf(code_file,"final %s dup_yyval(%s val)\n",jvalclass,jvalclass);
1356     fprintf(code_file,"{\n");
1357     fprintf(code_file,"  %s dup = new %s();\n",jvalclass,jvalclass);
1358     fprintf(code_file,"  dup.ival = val.ival;\n");
1359     fprintf(code_file,"  dup.dval = val.dval;\n");
1360     fprintf(code_file,"  dup.sval = val.sval;\n");
1361     fprintf(code_file,"  dup.obj = val.obj;\n");
1362     fprintf(code_file,"  return dup;\n");
1363     fprintf(code_file,"}\n");
1364     fprintf(code_file,"//#### end semantic value section ####\n");
1365       }
1366     }
1367   else  /*normal stuff  -- rwj*/
1368     {
1369       if (!unionized && ntags == 0)
1370       {
1371 	outline += 3;
1372 	fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
1373       }
1374     }
1375 }
1376 
1377 
output_trailing_text(void)1378 void output_trailing_text(void)
1379 {
1380 int c, last;
1381 FILE *in, *out;
1382 
1383     if (line == 0)
1384 	return;
1385 
1386     in = input_file;
1387     out = code_file;
1388     c = *cptr;
1389     if (c == '\n')
1390     {
1391 	++lineno;
1392 	if ((c = getc(in)) == EOF)
1393 	    return;
1394 	if (!lflag)
1395 	{
1396 	    ++outline;
1397 	    if (jflag)
1398 	      fprintf(out, jline_format, lineno, input_file_name);
1399 	    else
1400 	      fprintf(out, line_format, lineno, input_file_name);
1401 	}
1402 	if (c == '\n')
1403 	    ++outline;
1404 	putc(c, out);
1405 	last = c;
1406     }
1407     else
1408     {
1409 	if (!lflag)
1410 	{
1411 	    ++outline;
1412 	    if (jflag)/*rwj*/
1413 	      fprintf(out, jline_format, lineno, input_file_name);
1414 	    else
1415 	      fprintf(out, line_format, lineno, input_file_name);
1416 	}
1417 	do { putc(c, out); } while ((c = *++cptr) != '\n');
1418 	++outline;
1419 	putc('\n', out);
1420 	last = '\n';
1421     }
1422 
1423     while ((c = getc(in)) != EOF)
1424     {
1425 	if (c == '\n')
1426 	    ++outline;
1427 	putc(c, out);
1428 	last = c;
1429     }
1430 
1431     if (last != '\n')
1432     {
1433 	++outline;
1434 	putc('\n', out);
1435     }
1436     if (!lflag)
1437         if (jflag)
1438 	  fprintf(out, jline_format, ++outline + 1, code_file_name);
1439 	else
1440 	  fprintf(out, line_format, ++outline + 1, code_file_name);
1441 }
1442 
1443 
output_semantic_actions(void)1444 void output_semantic_actions(void)
1445 {
1446 int c, last;
1447 FILE *out;
1448 
1449     fclose(action_file);
1450     action_file = fopen(action_file_name, "r");
1451     if (action_file == NULL)
1452 	open_error(action_file_name);
1453 
1454     if ((c = getc(action_file)) == EOF)
1455 	return;
1456 
1457     out = code_file;
1458     last = c;
1459     if (c == '\n')
1460 	++outline;
1461     putc(c, out);
1462     while ((c = getc(action_file)) != EOF)
1463     {
1464 	if (c == '\n')
1465 	    ++outline;
1466 	putc(c, out);
1467 	last = c;
1468     }
1469 
1470     if (last != '\n')
1471     {
1472 	++outline;
1473 	putc('\n', out);
1474     }
1475 
1476     if (!lflag)
1477         if (jflag)/*rwj*/
1478 	  fprintf(out, jline_format, ++outline + 1, code_file_name);
1479 	else
1480 	  fprintf(out, line_format, ++outline + 1, code_file_name);
1481 }
1482 
free_itemsets(void)1483 void free_itemsets(void)
1484 {
1485 core *cp, *next;
1486 
1487   FREE(state_table);
1488   for (cp = first_state; cp; cp = next)
1489     {
1490 	 next = cp->next;
1491 	 FREE(cp);
1492     }
1493 }
1494 
1495 
free_shifts(void)1496 void free_shifts(void)
1497 {
1498 shifts *sp, *next;
1499 
1500   FREE(shift_table);
1501   for (sp = first_shift; sp; sp = next)
1502     {
1503 	 next = sp->next;
1504 	 FREE(sp);
1505     }
1506 }
1507 
1508 
1509 
free_reductions(void)1510 void free_reductions(void)
1511 {
1512 reductions *rp, *next;
1513 
1514   FREE(reduction_table);
1515   for (rp = first_reduction; rp; rp = next)
1516     {
1517 	 next = rp->next;
1518 	 FREE(rp);
1519     }
1520 }
1521