#ifndef NORCSID static char rcsidp3[] = "$Header$"; #endif #include "parser.h" #define UPDATEWORST(backups) if(backups>mostbackups) mostbackups = backups; findworst(patt,repl) struct mnems patt,repl; { /* /* Find the pattern that requires the most backup of output queue. /* Let repl be r1 r2 ... rn. All these are already on the output queue. /* Possibilities in order of most backup first are: /* a) pattern of form: p1 .... pb r1 r2 .... rn pc ... pd /* i.e. completely in pattern. /* requires a backup of b+n instructions /* and a goto to state 0. /* b) pattern of form: p1 .... pb r1 r2 .... ri /* i.e. a prefix of ends a pattern. /* requires a backup of b+n instructions /* and a goto to state 0. /* c) pattern of form: ri ri+1 ... rn pc ... pd /* i.e. a suffix of starts a pattern. /* requires a backup of n-i+1 instructions and a goto to state 0. */ int n = repl.m_len; int diff = patt.m_len - repl.m_len; int first,i; int s; int mostbackups = 0; if(n==0) { fprintf(ofile,"\t\tOO_mkrepl(0,%d,%d);\n",diff,maxpattern-1); return; } for(s=1;s<=higheststate;s++) { /* only match complete patterns */ if(actions[s]==(struct action *)NULL) continue; /* look for case a */ if(first=rightmatch(patterns[s],repl,1,n)) { UPDATEWORST(first-1+n); } /* look for case b */ for(i=n-1;i;i--) { if((first=rightmatch(patterns[s],repl,1,i)) && (first+i-1==patterns[s].m_len)) { UPDATEWORST(first-1+n); } } /* look for case c */ for(i=2;i<=n;i++) { if((first=leftmatch(patterns[s],repl,i,n)) && (first==1)) { UPDATEWORST(n-i+1); } } } fprintf(ofile,"\t\tOO_mkrepl(%d,%d,%d);\n",n,diff,mostbackups); } findfail(state,resout,rescpy,resgto) int state; int *resout, *rescpy, *resgto; { /* /* If pattern matching fails in 'state', how many outputs and how many /* push backs are requires. If pattern is of the form p1 p2 .... pn /* look for patterns of the form p2 p3 ... pn; then p3 p4 ... pn; etc. /* The first such match of the form pi pi+1 ... pn requires an output /* of p1 p2 ... pi-1 and a push back of pn pn-1 ... pi. */ int s,i; struct state *p; int istrans; int n = patterns[state].m_len; for(i=2;i<=n;i++) { for(s=1;s<=higheststate;s++) { /* exclude those on transitions from this state */ istrans = 0; for(p=states[state];p!=(struct state *)NULL;p=p->next) if(s==p->goto_state) istrans++; if(istrans) continue; if((leftmatch(patterns[s],patterns[state],i,n)==1)&& patterns[s].m_len==(n-i+1)) { *resout = i-1; *rescpy = n-i+1; *resgto = s; return; } } } *resout = n; *rescpy = 0; *resgto = 0; } PRIVATE int leftmatch(patt,repl,i,j) struct mnems patt,repl; int i,j; { /* /* Return the first complete match of the mnems of /* 'repl' in the mnems of 'patt'. Find the leftmost match. /* Return 0 if fails. */ int lenrij = j-i+1; int lastpos = patt.m_len - lenrij + 1; int k,n; for(k=1;k<=lastpos;k++) { for(n=1;n<=lenrij;n++) { if(patt.m_elems[(k+n-1)-1]->op_code != repl.m_elems[(i+n-1)-1]->op_code) break; } if(n>lenrij) { return(k); } } return(0); } PRIVATE int rightmatch(patt,repl,i,j) struct mnems patt,repl; int i,j; { /* /* Return the first complete match of the mnems of /* 'repl' in the mnems of 'patt'. Find the rightmost match. /* Return 0 if fails. */ int lenrij = j-i+1; int lastpos = patt.m_len - lenrij + 1; int k,n; for(k=lastpos;k>=1;k--) { for(n=1;n<=lenrij;n++) { if(patt.m_elems[(k+n-1)-1]->op_code != repl.m_elems[(i+n-1)-1]->op_code) break; } if(n>lenrij) { return(k); } } return(0); }