|
|
1.1 ! root 1: #include "regprog.h" ! 2: ! 3: /* ! 4: * Machine state ! 5: */ ! 6: #define LISTINCREMENT 8 ! 7: typedef struct List{ ! 8: Inst *inst; /* Instruction of the thread */ ! 9: Subexp se; /* matched subexpressions in this thread */ ! 10: }List; ! 11: static List *tl, *nl; /* This list, next list */ ! 12: static List *tle, *nle; /* ends of this and next list */ ! 13: static List *list[2]; ! 14: static List *liste[2]; ! 15: static int listsize = LISTINCREMENT; ! 16: ! 17: static Subexp sempty; /* empty set of matches */ ! 18: static int match; /* true if match is found */ ! 19: ! 20: /* ! 21: * Note optimization in addinst: ! 22: * *lp must be pending when addinst called; if *l has been looked ! 23: * at already, the optimization is a bug. ! 24: */ ! 25: static List * ! 26: newthread(lp, ip, sep) ! 27: List *lp; /* list to add to */ ! 28: Inst *ip; /* instruction to add */ ! 29: register Subexp *sep; /* pointers to subexpressions */ ! 30: { ! 31: register List *p; ! 32: ! 33: for(p=lp; p->inst != NULL; p++){ ! 34: if(p->inst==ip){ ! 35: if((sep)->m[0].sp < p->se.m[0].sp) ! 36: p->se = *sep; ! 37: return NULL; ! 38: } ! 39: } ! 40: p->inst = ip; ! 41: p->se = *sep; ! 42: (++p)->inst = NULL; ! 43: return p; ! 44: } ! 45: ! 46: static void ! 47: newmatch(mp, ms, sp) ! 48: regsubexp *mp; ! 49: int ms; ! 50: register Subexp *sp; ! 51: { ! 52: register int i; ! 53: ! 54: if (mp==NULL || ms <=0) ! 55: return; ! 56: if(mp[0].sp==0 || sp->m[0].sp<mp[0].sp || ! 57: (sp->m[0].sp==mp[0].sp && sp->m[0].ep>mp[0].ep)) { ! 58: for (i=0; i<ms && i<NSUBEXP; i++) ! 59: mp[i] = sp->m[i]; ! 60: for (; i<ms; i++) ! 61: mp[i].sp = mp[i].ep = NULL; ! 62: } ! 63: } ! 64: ! 65: extern int ! 66: regexec(progp, starts, mp, ms) ! 67: Prog *progp; /* program to run */ ! 68: char *starts; /* string to run machine on */ ! 69: regsubexp *mp; /* subexpression elements */ ! 70: int ms; /* number of elements pointed to by mp */ ! 71: { ! 72: register flag=0; ! 73: register Inst *inst; ! 74: register List *tlp; ! 75: register char *s; ! 76: int startchar=progp->startinst->type<OPERATOR? progp->startinst->type : 0; ! 77: int i, checkstart; ! 78: ! 79: restart: ! 80: match = 0; ! 81: checkstart = startchar; ! 82: sempty.m[0].sp = NULL; ! 83: if (mp!=NULL && ms >0) ! 84: mp[0].sp = mp[0].ep = NULL; ! 85: if (list[0] == NULL) { ! 86: list[0] = (List *)malloc(2*listsize*sizeof(List)); ! 87: list[1] = list[0] + listsize; ! 88: liste[0] = list[0] + listsize - 1; ! 89: liste[1] = list[1] + listsize - 1; ! 90: if (list[0] == NULL) ! 91: regerror("list overflow"); ! 92: } ! 93: list[0][0].inst = list[1][0].inst = NULL; ! 94: ! 95: /* Execute machine once for each character, including terminal NUL */ ! 96: s=starts; ! 97: do{ ! 98: /* fast check for first char */ ! 99: if(checkstart && *s!=startchar) ! 100: continue; ! 101: tl=list[flag]; ! 102: tle=liste[flag]; ! 103: nl=list[flag^=1]; ! 104: nle=liste[flag]; ! 105: nl->inst=0; ! 106: /* Add first instruction to this list */ ! 107: sempty.m[0].sp = s; ! 108: (void)newthread(tl, progp->startinst, &sempty); ! 109: /* Execute machine until this list is empty */ ! 110: for(tlp=tl; inst=tlp->inst; tlp++){ /* assignment = */ ! 111: Switchstmt: ! 112: switch(inst->type){ ! 113: default: /* regular character */ ! 114: if(inst->type == *s){ ! 115: Addinst: ! 116: if(newthread(nl, inst->next, &tlp->se)==nle) ! 117: goto realloc; ! 118: } ! 119: break; ! 120: case LBRA: ! 121: tlp->se.m[inst->subid].sp = s; ! 122: inst=inst->next; ! 123: goto Switchstmt; ! 124: case RBRA: ! 125: tlp->se.m[inst->subid].ep = s; ! 126: inst=inst->next; ! 127: goto Switchstmt; ! 128: case ANY: ! 129: goto Addinst; ! 130: case BOL: ! 131: if(s == starts){ ! 132: inst=inst->next; ! 133: goto Switchstmt; ! 134: } ! 135: break; ! 136: case EOL: ! 137: if(*s=='\0'){ ! 138: inst=inst->next; ! 139: goto Switchstmt; ! 140: } ! 141: break; ! 142: case CCLASS: ! 143: if(((char *)inst->right)[*s/8]&(1<<(*s&07))) ! 144: goto Addinst; ! 145: break; ! 146: case OR: ! 147: /* evaluate right choice later */ ! 148: if (newthread(tlp, inst->right, &tlp->se) == tle) ! 149: goto realloc; ! 150: /* efficiency: advance and re-evaluate */ ! 151: inst=inst->left; ! 152: goto Switchstmt; ! 153: case END: /* Match! */ ! 154: match = 1; ! 155: tlp->se.m[0].ep = s; ! 156: if (mp != NULL && ms > 0) newmatch(mp, ms, &tlp->se); ! 157: break; ! 158: } ! 159: } ! 160: checkstart = startchar && nl->inst==NULL; ! 161: }while(*s++); ! 162: return match; ! 163: realloc: ! 164: free(list[0]); ! 165: list[0] = NULL; ! 166: listsize += LISTINCREMENT; ! 167: goto restart; ! 168: } ! 169:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.