2 static char rcsidp5[] = "$Id: outputdfa.c,v 2.16 1994/06/24 11:14:26 ceriel Exp $";
11 PRIVATE installofile();
17 PRIVATE outoneaction();
31 openofile("incalls.r");
36 static char ofilename[80];
37 static char ofiletemp[80];
43 char *strcpy(), *strcat();
44 strcpy(ofilename,filename);
45 strcpy(ofiletemp,filename);
46 strcat(ofiletemp,".new");
47 if((ofile=fopen(ofiletemp,"w"))==NULL) {
48 fprintf(stderr,"Fatal Error: cannot open output file %s\n",ofiletemp);
57 * if contents of newly generated ofiletemp is different
58 * from that of ofilename then copy over old file else
59 * delete newly generated file
61 register FILE *f1, *f2;
64 if((f1 = fopen(ofiletemp,"r")) == NULL) {
65 fprintf(stderr,"Fatal Error: cannont reopen file %s\n",ofiletemp);
68 if((f2 = fopen(ofilename,"r")) == NULL) {
70 RENAME(ofiletemp,ofilename);
76 } while (c1 == c2 && c1 != EOF);
80 RENAME(ofiletemp,ofilename);
82 else UNLINK(ofiletemp);
89 /* Must remove the file "x" */
90 unlink(x); /* systemcall to remove file */
97 /* Must move the file "x" to the file "y" */
100 fprintf(stderr,"Cannot link to %s",y);
106 # define MAXOPCODE 255
109 int *next, *check, *base;
110 unsigned currsize; /* current size of next and check arrays */
111 int maxpos = 0; /* highest used position in these arrayes */
117 /* realloc arrays next and check so they are at least
121 unsigned newsize = currsize;
125 } while (newsize<size);
126 printf("Note: Extending next/check arrays from %d to %d\n",currsize,newsize);
127 next = (int *)Realloc(next,newsize);
128 check = (int *)Realloc(check,newsize);
129 /* clear ends of new arrays */
130 for(i=currsize;i<newsize;i++)
131 next[i] = check[i] = EMPTY;
140 /* find a place to store row in arrays */
142 register int *n = next;
145 /* look for first possible place to store it */
146 for(i=0;i<MAXOPCODE;i++) {
148 if((o = b+i)>currsize) increase_next(o);
149 if(n[o]!=EMPTY) goto nextpos;
154 for(i=0;i<MAXOPCODE;i++)
156 if((o=b+i) >maxpos) maxpos = o;
170 register struct state *p;
171 int nout, ncpy, ngto;
176 fprintf(ofile,"#include \"nopt.h\"\n");
178 fprintf(ofile,"int OO_maxreplacement = %d;\n", maxreplacement);
181 /* find how many entries in dfa */
182 for(s=0;s<=higheststate;s++)
183 for(p=states[s];p!=(struct state *)NULL;p=p->next)
185 /* start with next and check arrays twice this size */
186 currsize = 2 * numentries;
187 next = (int *)Malloc(currsize*sizeof(int));
188 check = (int *)Malloc(currsize*sizeof(int));
189 base = (int *)Malloc(((unsigned)(higheststate+1))*sizeof(int));
190 /* fill next array with EMPTY */
191 for(i=0;i<currsize;i++) check[i]=next[i]=EMPTY;
192 for(s=0;s<=higheststate;s++) {
194 for(i=0;i<MAXOPCODE;i++) row[i]=0;
196 /* fill in non zero entries */
197 for(p=states[s];p!=(struct state *)NULL;p=p->next) {
199 row[p->op->id_opcode] = p->goto_state;
201 /* look for a place to store row */
207 /* give some statistics on size of dfa */
208 printf("Number of patterns: %d\n", numpatterns);
209 printf("Longest pattern: %d\n", maxpattern);
210 printf("Longest replacement: %d\n", maxreplacement);
211 printf("Dfa contains %d states and %d distinct state/opcode pairs\n",
212 higheststate+1,numentries);
213 printf("Compacted using row displacement into %d entries\n",maxpos);
214 /* output the arrays */
215 fprintf(ofile,"struct dfa OO_checknext[] = {\n");
216 for(i=0;i<=maxpos;i++) {
217 fprintf(ofile,"\t/* %4d */\t",i);
218 fprintf(ofile,"{%4d,%4d},\n", check[i], next[i]);
220 fprintf(ofile,"};\n\n");
221 fprintf(ofile,"struct dfa *OO_base[] = {\n");
222 for(s=0;s<=higheststate;s++) {
223 fprintf(ofile,"\t/* %4d: ",s);
224 outmnems(patterns[s]);
225 fprintf(ofile,"*/\t");
227 fprintf(ofile,"0,\n");
229 fprintf(ofile,"&OO_checknext[%4d],\n", base[s]);
231 fprintf(ofile,"};\n\n");
232 fprintf(ofile,"struct dodefault OO_default[] = {\n");
233 for(s=0;s<=higheststate;s++) {
234 fprintf(ofile,"\t/* %4d: ",s);
235 outmnems(patterns[s]);
236 fprintf(ofile,"*/\t");
237 findfail(s,&nout,&ncpy,&ngto);
238 fprintf(ofile,"{%4d,%4d},\n", nout,ngto);
240 fprintf(ofile,"};\n\n");
248 for(i=1;i<=l.m_len;i++)
249 fprintf(ofile,"%s ",l.m_elems[i-1]->op_code->id_text);
253 sametest(s1,s2,e1,e2)
255 struct exp_node *e1,*e2;
257 /* return 1 if tests are identical */
260 if(e1->node_type!=e2->node_type) return 0;
261 switch(e1->node_type) {
287 return (sametest(s1,s2,e1->exp_left,e2->exp_left) &&
288 sametest(s1,s2,e1->exp_right,e2->exp_right));
293 return sametest(s1,s2,e1->exp_left,e2->exp_left);
297 return (e1->leaf_val == e2->leaf_val);
299 /* depends on pattern !! */
300 if (e1->leaf_val != e2->leaf_val) return 0;
301 return (patterns[s1].m_elems[e1->leaf_val-1]->
303 == patterns[s2].m_elems[e2->leaf_val-1]->
317 samerepl(s1,s2,r1,r2)
321 /* return 1 if replacements are identical */
323 register struct mnem_elem *m1,*m2;
324 if (r1.m_len != r2.m_len) return 0; /* different length */
325 for(i=0;i<r1.m_len;i++) {
328 if(m1->op_code!=m2->op_code) return 0;
329 if(!sametest(s1,s2,m1->arg,m2->arg)) return 0;
338 /* return 1 if replacement code of state s1 and s2 are identical */
339 register struct action *a1,*a2;
340 if (patterns[s1].m_len != patterns[s2].m_len) return 0;
344 if(!a2) return 0; /* a2 is shorter */
345 if(!samerepl(s1,s2,a1->replacement,a2->replacement)) return 0;
346 if(!sametest(s1,s2,a1->test,a2->test)) return 0;
350 if(a2) return 0; /* a2 is longer */
361 fprintf(ofile,"#include \"nopt.h\"\n\n");
362 /* keep track of which procedure used for each state */
363 farray = (int *)Malloc((unsigned)(higheststate+1)*sizeof(int));
364 for(s=0;s<=higheststate;s++) farray[s] = EMPTY;
365 /* output the functions avoiding duplicates */
366 for(s=0;s<=higheststate;s++) {
367 if(actions[s]!=(struct action *)NULL) {
368 /* first look for a previous identical function */
370 if(actions[t]!=(struct action *)NULL &&
372 /* use state 't' instead */
377 /* no identical function so make new one */
379 fprintf(ofile,"\nstatic do%dtrans() {\n",s);
380 fprintf(ofile,"\tregister p_instr patt = OO_patternqueue;\n");
381 fprintf(ofile,"\t/* ");
382 outmnems(patterns[s]);
383 fprintf(ofile," */\n");
385 for(a=actions[s];a!=(struct action *)NULL;a=a->next) {
386 if(a->test!=(struct exp_node *)NULL) {
387 fprintf(ofile,"\tif(");
389 fprintf(ofile,") {\n");
391 fprintf(ofile,"\t\treturn;\n");
392 fprintf(ofile,"\t}\n");
396 fprintf(stderr,"parser: more than one untested action on state %d\n",s);
403 fprintf(ofile,"}\n");
408 /* output the array itself */
409 fprintf(ofile,"\n\nint (*OO_ftrans[])()=\n{\n");
410 for(s=0;s<=higheststate;s++) {
412 fprintf(ofile,"\tdo%dtrans,\n",farray[s]);
414 fprintf(ofile,"\t0,\n");
416 fprintf(ofile,"};\n");
424 fprintf(ofile,"\t\t/* -> ");
425 outmnems(a->replacement);
426 fprintf(ofile," */\n");
427 fprintf(ofile,"#ifdef STATS\n");
428 fprintf(ofile,"\t\tif(OO_wrstats) fprintf(stderr,\"%d\\n\");\n",a->linenum);
429 fprintf(ofile,"#endif\n");
430 outrepl(s,a->replacement);
431 findworst(patterns[s],a->replacement);
440 /* Contruct <repl>=r1 r2 ... rn and put on output queue.
445 struct mnem_elem *ri = repl.m_elems[i-1];
446 char *mnem = ri->op_code->id_text;
447 switch(ri->op_code->id_argfmt) {
449 fprintf(ofile,"\t\tEM_Rop(op_%s);\n",mnem);
452 fprintf(ofile,"\t\tEM_Rcst(op_%s,",mnem);
453 fprintf(ofile,"(arith)");
454 outexp(ri->arg,state);
455 fprintf(ofile,");\n");
459 fprintf(ofile,"\t\tEM_Rcst(op_%s,",mnem);
460 fprintf(ofile,"(arith)");
461 outexp(ri->arg,state);
464 fprintf(ofile,"\t\tEM_Rnarg(op_%s);\n",mnem);
466 fprintf(ofile,");\n");
469 fprintf(ofile,"\t\tEM_Rilb(op_%s,",mnem);
470 outexp(ri->arg,state);
471 fprintf(ofile,");\n");
474 fprintf(ofile,"\t\tEM_Rdefilb(op_%s,",mnem);
475 outexp(ri->arg,state);
476 fprintf(ofile,");\n");
479 fprintf(ofile,"\t\tEM_Rpro(op_%s,",mnem);
480 outexp(ri->arg,state);
481 fprintf(ofile,");\n");
484 fprintf(ofile,"\t\tOO_mkext(GETNXTREPL(), op_%s,",mnem);
485 outexp(ri->arg,state);
486 fprintf(ofile,");\n");
497 switch(e->node_type) {
517 outexp(e->exp_left,state);
519 outexp(e->exp_right,state);
528 outexp(e->exp_left,state);
532 fprintf(ofile,"DEFINED(patt[%d])",e->leaf_val-1);
535 fprintf(ofile,"!DEFINED(patt[%d])",e->leaf_val-1);
540 fprintf(ofile,"(arith)");
541 outexp(e->exp_right,state);
548 fprintf(ofile,"(arith)");
549 outexp(e->exp_left,state);
551 fprintf(ofile,"(arith)");
552 outexp(e->exp_right,state);
560 outext(e->exp_right);
564 switch(patterns[state].m_elems[e->leaf_val-1]->op_code->id_argfmt) {
566 fprintf(stderr,"error: mnem %d has no argument\n",e->leaf_val);
571 fprintf(ofile,"CST(patt[%d])",e->leaf_val-1);
574 fprintf(ofile,"LAB(patt[%d])",e->leaf_val-1);
577 fprintf(ofile,"DEFILB(patt[%d])",e->leaf_val-1);
580 fprintf(ofile,"PNAM(patt[%d])",e->leaf_val-1);
583 fprintf(ofile,"OO_offset(patt+%d)",e->leaf_val-1);
588 fprintf(ofile,"OO_PSIZE"); break;
590 fprintf(ofile,"OO_WSIZE"); break;
592 fprintf(ofile,"OO_DWSIZE"); break;
594 fprintf(ofile,"%d",e->leaf_val); break;
602 if(e->node_type!=PATARG) {
603 fprintf(stderr,"Internal error in outext of parser\n");
606 fprintf(ofile,"patt+%d",e->leaf_val-1);
614 case LOGAND: fprintf(ofile,"&&"); break;
615 case LOGOR: fprintf(ofile,"||"); break;
616 case BITAND: fprintf(ofile,"&"); break;
617 case BITOR: fprintf(ofile,"|"); break;
618 case XOR: fprintf(ofile,"^"); break;
619 case MINUS: fprintf(ofile,"-"); break;
620 case PLUS: fprintf(ofile,"+"); break;
621 case TIMES: fprintf(ofile,"*"); break;
622 case DIV: fprintf(ofile,"/"); break;
623 case MOD: fprintf(ofile,"%%"); break;
624 case EQ: fprintf(ofile,"=="); break;
625 case NE: fprintf(ofile,"!="); break;
626 case LT: fprintf(ofile,"<"); break;
627 case LE: fprintf(ofile,"<="); break;
628 case GT: fprintf(ofile,">"); break;
629 case GE: fprintf(ofile,">="); break;
630 case LSHIFT: fprintf(ofile,"<<"); break;
631 case RSHIFT: fprintf(ofile,">>"); break;
632 case NOT: fprintf(ofile,"!"); break;
633 case COMP: fprintf(ofile,"~"); break;
634 case UPLUS: fprintf(ofile,"+"); break;
635 case UMINUS: fprintf(ofile,"-"); break;
636 case SAMESIGN: fprintf(ofile,"OO_signsame("); break;
637 case SFIT: fprintf(ofile,"OO_sfit("); break;
638 case UFIT: fprintf(ofile,"OO_ufit("); break;
639 case ROTATE: fprintf(ofile,"OO_rotate("); break;
640 case SAMEEXT: fprintf(ofile,"OO_extsame("); break;
641 case SAMENAM: fprintf(ofile,"OO_namsame("); break;