123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643 |
- #ifndef NORCSID
- static char rcsidp5[] = "$Id$";
- #endif
- #include "parser.h"
- #include "Lpars.h"
- FILE *ofile;
- PRIVATE openofile();
- PRIVATE installofile();
- PRIVATE UNLINK();
- PRIVATE RENAME();
- PRIVATE outdfa();
- PRIVATE outmnems();
- PRIVATE outdotrans();
- PRIVATE outoneaction();
- PRIVATE outrepl();
- PRIVATE outexp();
- PRIVATE outext();
- PRIVATE outop();
- outputnopt()
- {
- openofile("dfa.c");
- outdfa();
- installofile();
- openofile("trans.c");
- outdotrans();
- installofile();
- openofile("incalls.r");
- outputincalls();
- installofile();
- }
- static char ofilename[80];
- static char ofiletemp[80];
- PRIVATE
- openofile(filename)
- char *filename;
- {
- char *strcpy(), *strcat();
- strcpy(ofilename,filename);
- strcpy(ofiletemp,filename);
- strcat(ofiletemp,".new");
- if((ofile=fopen(ofiletemp,"w"))==NULL) {
- fprintf(stderr,"Fatal Error: cannot open output file %s\n",ofiletemp);
- sys_stop(S_EXIT);
- }
- }
- PRIVATE
- installofile()
- {
- /*
- * if contents of newly generated ofiletemp is different
- * from that of ofilename then copy over old file else
- * delete newly generated file
- */
- register FILE *f1, *f2;
- register int c1, c2;
- fclose(ofile);
- if((f1 = fopen(ofiletemp,"r")) == NULL) {
- fprintf(stderr,"Fatal Error: cannont reopen file %s\n",ofiletemp);
- sys_stop(S_EXIT);
- }
- if((f2 = fopen(ofilename,"r")) == NULL) {
- fclose(f1);
- RENAME(ofiletemp,ofilename);
- return;
- }
- do {
- c1 = getc(f1);
- c2 = getc(f2);
- } while (c1 == c2 && c1 != EOF);
- fclose(f1);
- fclose(f2);
- if (c1 != c2) {
- RENAME(ofiletemp,ofilename);
- }
- else UNLINK(ofiletemp);
- }
- PRIVATE
- UNLINK(x)
- char *x;
- {
- /* Must remove the file "x" */
- unlink(x); /* systemcall to remove file */
- }
- PRIVATE
- RENAME(x,y)
- char *x, *y;
- {
- /* Must move the file "x" to the file "y" */
- unlink(y);
- if(link(x,y)!=0) {
- fprintf(stderr,"Cannot link to %s",y);
- sys_stop(S_EXIT);
- }
- unlink(x);
- }
- # define MAXOPCODE 255
- # define EMPTY -1
- int *next, *check, *base;
- unsigned currsize; /* current size of next and check arrays */
- int maxpos = 0; /* highest used position in these arrayes */
- PRIVATE
- increase_next(size)
- int size;
- {
- /* realloc arrays next and check so they are at least
- * of size 'size'
- */
- char *Realloc();
- unsigned newsize = currsize;
- register int i;
- do {
- newsize *= 2;
- } while (newsize<size);
- printf("Note: Extending next/check arrays from %d to %d\n",currsize,newsize);
- next = (int *)Realloc(next,newsize);
- check = (int *)Realloc(check,newsize);
- /* clear ends of new arrays */
- for(i=currsize;i<newsize;i++)
- next[i] = check[i] = EMPTY;
- currsize = newsize;
- }
- PRIVATE
- store_row(state,row)
- int state;
- register int *row;
- {
- /* find a place to store row in arrays */
- register b,i,o;
- register int *n = next;
- b=0;
- for(;;) {
- /* look for first possible place to store it */
- for(i=0;i<MAXOPCODE;i++) {
- if(row[i]) {
- if((o = b+i)>currsize) increase_next(o);
- if(n[o]!=EMPTY) goto nextpos;
- }
- }
- /* found a place */
- base[state]=b;
- for(i=0;i<MAXOPCODE;i++)
- if(row[i]) {
- if((o=b+i) >maxpos) maxpos = o;
- next[o] = row[i];
- check[o] = state;
- }
- return;
- nextpos:
- ++b;
- }
- }
- PRIVATE
- outdfa()
- {
- register int s,i;
- register struct state *p;
- int nout, ncpy, ngto;
- int row[MAXOPCODE];
- int numinrow;
- int numentries = 0;
-
- fprintf(ofile,"#include \"nopt.h\"\n");
- fprintf(ofile,"\n");
- fprintf(ofile,"int OO_maxreplacement = %d;\n", maxreplacement);
- fprintf(ofile,"\n");
- /* find how many entries in dfa */
- for(s=0;s<=higheststate;s++)
- for(p=states[s];p!=(struct state *)NULL;p=p->next)
- numentries++;
- /* start with next and check arrays twice this size */
- currsize = 2 * numentries;
- next = (int *)Malloc(currsize*sizeof(int));
- check = (int *)Malloc(currsize*sizeof(int));
- base = (int *)Malloc(((unsigned)(higheststate+1))*sizeof(int));
- /* fill next array with EMPTY */
- for(i=0;i<currsize;i++) check[i]=next[i]=EMPTY;
- for(s=0;s<=higheststate;s++) {
- /* empty row */
- for(i=0;i<MAXOPCODE;i++) row[i]=0;
- numinrow = 0;
- /* fill in non zero entries */
- for(p=states[s];p!=(struct state *)NULL;p=p->next) {
- numinrow++;
- row[p->op->id_opcode] = p->goto_state;
- }
- /* look for a place to store row */
- if(numinrow)
- store_row(s,row);
- else
- base[s] = EMPTY;
- }
- /* give some statistics on size of dfa */
- printf("Number of patterns: %d\n", numpatterns);
- printf("Longest pattern: %d\n", maxpattern);
- printf("Longest replacement: %d\n", maxreplacement);
- printf("Dfa contains %d states and %d distinct state/opcode pairs\n",
- higheststate+1,numentries);
- printf("Compacted using row displacement into %d entries\n",maxpos);
- /* output the arrays */
- fprintf(ofile,"struct dfa OO_checknext[] = {\n");
- for(i=0;i<=maxpos;i++) {
- fprintf(ofile,"\t/* %4d */\t",i);
- fprintf(ofile,"{%4d,%4d},\n", check[i], next[i]);
- }
- fprintf(ofile,"};\n\n");
- fprintf(ofile,"struct dfa *OO_base[] = {\n");
- for(s=0;s<=higheststate;s++) {
- fprintf(ofile,"\t/* %4d: ",s);
- outmnems(patterns[s]);
- fprintf(ofile,"*/\t");
- if(base[s]==EMPTY)
- fprintf(ofile,"0,\n");
- else
- fprintf(ofile,"&OO_checknext[%4d],\n", base[s]);
- }
- fprintf(ofile,"};\n\n");
- fprintf(ofile,"struct dodefault OO_default[] = {\n");
- for(s=0;s<=higheststate;s++) {
- fprintf(ofile,"\t/* %4d: ",s);
- outmnems(patterns[s]);
- fprintf(ofile,"*/\t");
- findfail(s,&nout,&ncpy,&ngto);
- fprintf(ofile,"{%4d,%4d},\n", nout,ngto);
- }
- fprintf(ofile,"};\n\n");
- }
- PRIVATE
- outmnems(l)
- struct mnems l;
- {
- int i;
- for(i=1;i<=l.m_len;i++)
- fprintf(ofile,"%s ",l.m_elems[i-1]->op_code->id_text);
- }
- PRIVATE int
- sametest(s1,s2,e1,e2)
- int s1,s2;
- struct exp_node *e1,*e2;
- {
- /* return 1 if tests are identical */
- if(e1) {
- if(!e2) return 0;
- if(e1->node_type!=e2->node_type) return 0;
- switch(e1->node_type) {
- case LOGAND:
- case LOGOR:
- case BITAND:
- case BITOR:
- case XOR:
- case MINUS:
- case PLUS:
- case TIMES:
- case DIV:
- case MOD:
- case EQ:
- case NE:
- case LT:
- case LE:
- case GT:
- case GE:
- case LSHIFT:
- case RSHIFT:
- case COMMA:
- case SAMESIGN:
- case SFIT:
- case UFIT:
- case ROTATE:
- case SAMEEXT:
- case SAMENAM:
- return (sametest(s1,s2,e1->exp_left,e2->exp_left) &&
- sametest(s1,s2,e1->exp_right,e2->exp_right));
- case NOT:
- case COMP:
- case UPLUS:
- case UMINUS:
- return sametest(s1,s2,e1->exp_left,e2->exp_left);
- case DEFINED:
- case UNDEFINED:
- case INT:
- return (e1->leaf_val == e2->leaf_val);
- case PATARG:
- /* depends on pattern !! */
- if (e1->leaf_val != e2->leaf_val) return 0;
- return (patterns[s1].m_elems[e1->leaf_val-1]->
- op_code->id_argfmt
- == patterns[s2].m_elems[e2->leaf_val-1]->
- op_code->id_argfmt);
- case PSIZE:
- case WSIZE:
- case DWSIZE:
- return 1;
- }
- /*NOTREACHED*/
- }
- else return (e2==0);
- }
- PRIVATE int
- samerepl(s1,s2,r1,r2)
- int s1,s2;
- struct mnems r1,r2;
- {
- /* return 1 if replacements are identical */
- register int i;
- register struct mnem_elem *m1,*m2;
- if (r1.m_len != r2.m_len) return 0; /* different length */
- for(i=0;i<r1.m_len;i++) {
- m1=r1.m_elems[i];
- m2=r2.m_elems[i];
- if(m1->op_code!=m2->op_code) return 0;
- if(!sametest(s1,s2,m1->arg,m2->arg)) return 0;
- }
- return 1;
- }
- PRIVATE int
- samecode(s1,s2)
- int s1,s2;
- {
- /* return 1 if replacement code of state s1 and s2 are identical */
- register struct action *a1,*a2;
- if (patterns[s1].m_len != patterns[s2].m_len) return 0;
- a1 = actions[s1];
- a2 = actions[s2];
- while(a1) {
- if(!a2) return 0; /* a2 is shorter */
- if(!samerepl(s1,s2,a1->replacement,a2->replacement)) return 0;
- if(!sametest(s1,s2,a1->test,a2->test)) return 0;
- a1 = a1->next;
- a2 = a2->next;
- }
- if(a2) return 0; /* a2 is longer */
- return 1;
- }
- PRIVATE
- outdotrans()
- {
- register int s,t;
- struct action *a;
- int seennontested;
- int *farray;
- fprintf(ofile,"#include \"nopt.h\"\n\n");
- /* keep track of which procedure used for each state */
- farray = (int *)Malloc((unsigned)(higheststate+1)*sizeof(int));
- for(s=0;s<=higheststate;s++) farray[s] = EMPTY;
- /* output the functions avoiding duplicates */
- for(s=0;s<=higheststate;s++) {
- if(actions[s]!=(struct action *)NULL) {
- /* first look for a previous identical function */
- for(t=0;t<s;t++) {
- if(actions[t]!=(struct action *)NULL &&
- samecode(s,t)) {
- /* use state 't' instead */
- farray[s]=t;
- goto next_func;
- }
- }
- /* no identical function so make new one */
- farray[s] = s;
- fprintf(ofile,"\nstatic do%dtrans() {\n",s);
- fprintf(ofile,"\tregister p_instr patt = OO_patternqueue;\n");
- fprintf(ofile,"\t/* ");
- outmnems(patterns[s]);
- fprintf(ofile," */\n");
- seennontested=0;
- for(a=actions[s];a!=(struct action *)NULL;a=a->next) {
- if(a->test!=(struct exp_node *)NULL) {
- fprintf(ofile,"\tif(");
- outexp(a->test,s);
- fprintf(ofile,") {\n");
- outoneaction(s,a);
- fprintf(ofile,"\t\treturn;\n");
- fprintf(ofile,"\t}\n");
- }
- else {
- if(seennontested) {
- fprintf(stderr,"parser: more than one untested action on state %d\n",s);
- nerrors++;
- }
- seennontested++;
- outoneaction(s,a);
- }
- }
- fprintf(ofile,"}\n");
- }
- next_func:
- continue;
- }
- /* output the array itself */
- fprintf(ofile,"\n\nint (*OO_ftrans[])()=\n{\n");
- for(s=0;s<=higheststate;s++) {
- if(farray[s]!=EMPTY)
- fprintf(ofile,"\tdo%dtrans,\n",farray[s]);
- else
- fprintf(ofile,"\t0,\n");
- }
- fprintf(ofile,"};\n");
- }
- PRIVATE
- outoneaction(s,a)
- int s;
- struct action *a;
- {
- fprintf(ofile,"\t\t/* -> ");
- outmnems(a->replacement);
- fprintf(ofile," */\n");
- fprintf(ofile,"#ifdef STATS\n");
- fprintf(ofile,"\t\tif(OO_wrstats) fprintf(stderr,\"%d\\n\");\n",a->linenum);
- fprintf(ofile,"#endif\n");
- outrepl(s,a->replacement);
- findworst(patterns[s],a->replacement);
- }
- PRIVATE
- outrepl(state,repl)
- int state;
- struct mnems repl;
- {
- /*
- /* Contruct <repl>=r1 r2 ... rn and put on output queue.
- */
- int n = repl.m_len;
- int i;
- for(i=1;i<=n;i++) {
- struct mnem_elem *ri = repl.m_elems[i-1];
- char *mnem = ri->op_code->id_text;
- switch(ri->op_code->id_argfmt) {
- case NOARG:
- fprintf(ofile,"\t\tEM_Rop(op_%s);\n",mnem);
- break;
- case CST:
- fprintf(ofile,"\t\tEM_Rcst(op_%s,",mnem);
- fprintf(ofile,"(arith)");
- outexp(ri->arg,state);
- fprintf(ofile,");\n");
- break;
- case CSTOPT:
- if(ri->arg) {
- fprintf(ofile,"\t\tEM_Rcst(op_%s,",mnem);
- fprintf(ofile,"(arith)");
- outexp(ri->arg,state);
- }
- else {
- fprintf(ofile,"\t\tEM_Rnarg(op_%s);\n",mnem);
- }
- fprintf(ofile,");\n");
- break;
- case LAB:
- fprintf(ofile,"\t\tEM_Rilb(op_%s,",mnem);
- outexp(ri->arg,state);
- fprintf(ofile,");\n");
- break;
- case DEFILB:
- fprintf(ofile,"\t\tEM_Rdefilb(op_%s,",mnem);
- outexp(ri->arg,state);
- fprintf(ofile,");\n");
- break;
- case PNAM:
- fprintf(ofile,"\t\tEM_Rpro(op_%s,",mnem);
- outexp(ri->arg,state);
- fprintf(ofile,");\n");
- break;
- case EXT:
- fprintf(ofile,"\t\tOO_mkext(GETNXTREPL(), op_%s,",mnem);
- outexp(ri->arg,state);
- fprintf(ofile,");\n");
- break;
- }
- }
- }
- PRIVATE
- outexp(e,state)
- struct exp_node *e;
- int state;
- {
- switch(e->node_type) {
- case LOGAND:
- case LOGOR:
- case BITAND:
- case BITOR:
- case XOR:
- case MINUS:
- case PLUS:
- case TIMES:
- case DIV:
- case MOD:
- case EQ:
- case NE:
- case LT:
- case LE:
- case GT:
- case GE:
- case LSHIFT:
- case RSHIFT:
- fprintf(ofile,"(");
- outexp(e->exp_left,state);
- outop(e->node_type);
- outexp(e->exp_right,state);
- fprintf(ofile,")");
- break;
- case NOT:
- case COMP:
- case UPLUS:
- case UMINUS:
- fprintf(ofile,"(");
- outop(e->node_type);
- outexp(e->exp_left,state);
- fprintf(ofile,")");
- break;
- case DEFINED:
- fprintf(ofile,"DEFINED(patt[%d])",e->leaf_val-1);
- break;
- case UNDEFINED:
- fprintf(ofile,"!DEFINED(patt[%d])",e->leaf_val-1);
- break;
- case COMMA:
- outext(e->exp_left);
- fprintf(ofile,",");
- fprintf(ofile,"(arith)");
- outexp(e->exp_right,state);
- break;
- case SAMESIGN:
- case SFIT:
- case UFIT:
- case ROTATE:
- outop(e->node_type);
- fprintf(ofile,"(arith)");
- outexp(e->exp_left,state);
- fprintf(ofile,",");
- fprintf(ofile,"(arith)");
- outexp(e->exp_right,state);
- fprintf(ofile,")");
- break;
- case SAMEEXT:
- case SAMENAM:
- outop(e->node_type);
- outext(e->exp_left);
- fprintf(ofile,",");
- outext(e->exp_right);
- fprintf(ofile,")");
- break;
- case PATARG:
- switch(patterns[state].m_elems[e->leaf_val-1]->op_code->id_argfmt) {
- case NOARG:
- fprintf(stderr,"error: mnem %d has no argument\n",e->leaf_val);
- nerrors++;
- break;
- case CST:
- case CSTOPT:
- fprintf(ofile,"CST(patt[%d])",e->leaf_val-1);
- break;
- case LAB:
- fprintf(ofile,"LAB(patt[%d])",e->leaf_val-1);
- break;
- case DEFILB:
- fprintf(ofile,"DEFILB(patt[%d])",e->leaf_val-1);
- break;
- case PNAM:
- fprintf(ofile,"PNAM(patt[%d])",e->leaf_val-1);
- break;
- case EXT:
- fprintf(ofile,"OO_offset(patt+%d)",e->leaf_val-1);
- break;
- }
- break;
- case PSIZE:
- fprintf(ofile,"OO_PSIZE"); break;
- case WSIZE:
- fprintf(ofile,"OO_WSIZE"); break;
- case DWSIZE:
- fprintf(ofile,"OO_DWSIZE"); break;
- case INT:
- fprintf(ofile,"%d",e->leaf_val); break;
- }
- }
- PRIVATE
- outext(e)
- struct exp_node *e;
- {
- if(e->node_type!=PATARG) {
- fprintf(stderr,"Internal error in outext of parser\n");
- nerrors++;
- }
- fprintf(ofile,"patt+%d",e->leaf_val-1);
- }
- PRIVATE
- outop(op)
- int op;
- {
- switch(op) {
- case LOGAND: fprintf(ofile,"&&"); break;
- case LOGOR: fprintf(ofile,"||"); break;
- case BITAND: fprintf(ofile,"&"); break;
- case BITOR: fprintf(ofile,"|"); break;
- case XOR: fprintf(ofile,"^"); break;
- case MINUS: fprintf(ofile,"-"); break;
- case PLUS: fprintf(ofile,"+"); break;
- case TIMES: fprintf(ofile,"*"); break;
- case DIV: fprintf(ofile,"/"); break;
- case MOD: fprintf(ofile,"%%"); break;
- case EQ: fprintf(ofile,"=="); break;
- case NE: fprintf(ofile,"!="); break;
- case LT: fprintf(ofile,"<"); break;
- case LE: fprintf(ofile,"<="); break;
- case GT: fprintf(ofile,">"); break;
- case GE: fprintf(ofile,">="); break;
- case LSHIFT: fprintf(ofile,"<<"); break;
- case RSHIFT: fprintf(ofile,">>"); break;
- case NOT: fprintf(ofile,"!"); break;
- case COMP: fprintf(ofile,"~"); break;
- case UPLUS: fprintf(ofile,"+"); break;
- case UMINUS: fprintf(ofile,"-"); break;
- case SAMESIGN: fprintf(ofile,"OO_signsame("); break;
- case SFIT: fprintf(ofile,"OO_sfit("); break;
- case UFIT: fprintf(ofile,"OO_ufit("); break;
- case ROTATE: fprintf(ofile,"OO_rotate("); break;
- case SAMEEXT: fprintf(ofile,"OO_extsame("); break;
- case SAMENAM: fprintf(ofile,"OO_namsame("); break;
- }
- }
|