📄 b.c
字号:
follow(p); return; case CAT: if (v == left(p)) { /* v is left child of p */ if (first(right(p)) == 0) { follow(p); return; } } else /* v is right child */ follow(p); return; }}member(int c, uchar *s) /* is c in s? */{ while (*s) if (c == *s++) return(1); return(0);}match(fa *f, uchar *p) /* shortest match ? */{ register int s, ns; s = f->reset ? makeinit(f,0) : f->initstat; if (f->out[s]) return(1); do { if (ns=f->gototab[s][*p]) s = ns; else s = cgoto(f,s,*p); if (f->out[s]) return(1); } while (*p++ != 0); return(0);}pmatch(fa *f, uchar *p) /* longest match, for sub */{ register int s, ns; register uchar *q; int i, k; s = f->reset ? makeinit(f,1) : f->initstat; patbeg = p; patlen = -1; do { q = p; do { if (f->out[s]) /* final state */ patlen = q-p; if (ns=f->gototab[s][*q]) s = ns; else s = cgoto(f,s,*q); if (s == 1) /* no transition */ if (patlen >= 0) { patbeg = p; return(1); } else goto nextin; /* no match */ } while (*q++ != 0); if (f->out[s]) patlen = q-p-1; /* don't count $ */ if (patlen >= 0) { patbeg = p; return(1); } nextin: s = 2; if (f->reset) { for (i = 2; i <= f->curstat; i++) xfree(f->posns[i]); k = *f->posns[0]; if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL) overflo("out of space in pmatch"); for (i = 0; i <= k; i++) (f->posns[2])[i] = (f->posns[0])[i]; f->initstat = f->curstat = 2; f->out[2] = f->out[0]; for (i = 0; i < NCHARS; i++) f->gototab[2][i] = 0; } } while (*p++ != 0); return (0);}nematch(fa *f, uchar *p) /* non-empty match, for sub */{ register int s, ns; register uchar *q; int i, k; s = f->reset ? makeinit(f,1) : f->initstat; patlen = -1; while (*p) { q = p; do { if (f->out[s]) /* final state */ patlen = q-p; if (ns = f->gototab[s][*q]) s = ns; else s = cgoto(f,s,*q); if (s == 1) /* no transition */ if (patlen > 0) { patbeg = p; return(1); } else goto nnextin; /* no nonempty match */ } while (*q++ != 0); if (f->out[s]) patlen = q-p-1; /* don't count $ */ if (patlen > 0 ) { patbeg = p; return(1); } nnextin: s = 2; if (f->reset) { for (i = 2; i <= f->curstat; i++) xfree(f->posns[i]); k = *f->posns[0]; if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL) overflo("out of state space"); for (i = 0; i <= k; i++) (f->posns[2])[i] = (f->posns[0])[i]; f->initstat = f->curstat = 2; f->out[2] = f->out[0]; for (i = 0; i < NCHARS; i++) f->gototab[2][i] = 0; } p++; } return (0);}Node *reparse(uchar *p) /* parses regular expression pointed to by p */{ /* uses relex() to scan regular expression */ Node *np; dprintf( ("reparse <%s>\n", p) ); lastre = prestr = p; /* prestr points to string to be parsed */ rtok = relex(); if (rtok == '\0') ERROR "empty regular expression" FATAL; np = regexp(); if (rtok != '\0') ERROR "syntax error in regular expression %s at %s", lastre, prestr FATAL; return(np);}Node *regexp(void) /* top-level parse of reg expr */{ return (alt(concat(primary())));}Node *primary(void){ Node *np; switch (rtok) { case CHAR: np = op2(CHAR, NIL, (Node *) rlxval); rtok = relex(); return (unary(np)); case ALL: rtok = relex(); return (unary(op2(ALL, NIL, NIL))); case DOT: rtok = relex(); return (unary(op2(DOT, NIL, NIL))); case CCL: np = op2(CCL, NIL, (Node*) cclenter(rlxstr)); rtok = relex(); return (unary(np)); case NCCL: np = op2(NCCL, NIL, (Node *) cclenter(rlxstr)); rtok = relex(); return (unary(np)); case '^': rtok = relex(); return (unary(op2(CHAR, NIL, (Node *) HAT))); case '$': rtok = relex(); return (unary(op2(CHAR, NIL, NIL))); case '(': rtok = relex(); if (rtok == ')') { /* special pleading for () */ rtok = relex(); return unary(op2(CCL, NIL, (Node *) tostring(""))); } np = regexp(); if (rtok == ')') { rtok = relex(); return (unary(np)); } else ERROR "syntax error in regular expression %s at %s", lastre, prestr FATAL; default: ERROR "illegal primary in regular expression %s at %s", lastre, prestr FATAL; } return 0; /*NOTREACHED*/}Node *concat(Node *np){ switch (rtok) { case CHAR: case DOT: case ALL: case CCL: case NCCL: case '$': case '(': return (concat(op2(CAT, np, primary()))); } return (np);}Node *alt(Node *np){ if (rtok == OR) { rtok = relex(); return (alt(op2(OR, np, concat(primary())))); } return (np);}Node *unary(Node *np){ switch (rtok) { case STAR: rtok = relex(); return (unary(op2(STAR, np, NIL))); case PLUS: rtok = relex(); return (unary(op2(PLUS, np, NIL))); case QUEST: rtok = relex(); return (unary(op2(QUEST, np, NIL))); default: return (np); }}relex(void) /* lexical analyzer for reparse */{ register int c; uchar cbuf[MAXLIN]; int clen, cflag; switch (c = *prestr++) { case '|': return OR; case '*': return STAR; case '+': return PLUS; case '?': return QUEST; case '.': return DOT; case '\0': prestr--; return '\0'; case '^': case '$': case '(': case ')': return c; case '\\': rlxval = quoted(&prestr); return CHAR; default: rlxval = c; return CHAR; case '[': clen = 0; if (*prestr == '^') { cflag = 1; prestr++; } else cflag = 0; for ( ; clen < MAXLIN-1; ) { if ((c = *prestr++) == '\\') { cbuf[clen++] = '\\'; if ((c = *prestr++) == '\0') ERROR "nonterminated character class %.20s...", lastre FATAL; cbuf[clen++] = c; } else if (c == ']') { cbuf[clen] = 0; rlxstr = tostring(cbuf); if (cflag == 0) return CCL; else return NCCL; } else if (c == '\n') { ERROR "newline in character class %.20s...", lastre FATAL; } else if (c == '\0') { ERROR "nonterminated character class %.20s", lastre FATAL; } else cbuf[clen++] = c; } if (clen >= MAXLIN-1) ERROR "character class %.20s... too long", cbuf FATAL; } /* can't happen */ return 0;}int cgoto(fa *f, int s, int c){ register int i, j, k; register int *p, *q; for (i = 0; i <= f->accept; i++) setvec[i] = 0; setcnt = 0; /* compute positions of gototab[s,c] into setvec */ p = f->posns[s]; for (i = 1; i <= *p; i++) { if ((k = f->re[p[i]].ltype) != FINAL) { if (k == CHAR && c == f->re[p[i]].lval || k == DOT && c != 0 && c != HAT || k == ALL && c != 0 || k == CCL && member(c, (uchar *) f->re[p[i]].lval) || k == NCCL && !member(c, (uchar *) f->re[p[i]].lval) && c != 0 && c != HAT) { q = f->re[p[i]].lfollow; for (j = 1; j <= *q; j++) { if (setvec[q[j]] == 0) { setcnt++; setvec[q[j]] = 1; } } } } } /* determine if setvec is a previous state */ tmpset[0] = setcnt; j = 1; for (i = f->accept; i >= 0; i--) if (setvec[i]) { tmpset[j++] = i; } /* tmpset == previous state? */ for (i = 1; i <= f->curstat; i++) { p = f->posns[i]; if ((k = tmpset[0]) != p[0]) goto different; for (j = 1; j <= k; j++) if (tmpset[j] != p[j]) goto different; /* setvec is state i */ f->gototab[s][c] = i; return i; different:; } /* add tmpset to current set of states */ if (f->curstat >= NSTATES-1) { f->curstat = 2; f->reset = 1; for (i = 2; i < NSTATES; i++) xfree(f->posns[i]); } else ++(f->curstat); for (i = 0; i < NCHARS; i++) f->gototab[f->curstat][i] = 0; xfree(f->posns[f->curstat]); if ((p = (int *) calloc(1, (setcnt+1)*sizeof(int))) == NULL) overflo("out of space in cgoto"); f->posns[f->curstat] = p; f->gototab[s][c] = f->curstat; for (i = 0; i <= setcnt; i++) p[i] = tmpset[i]; if (setvec[f->accept]) f->out[f->curstat] = 1; else f->out[f->curstat] = 0; return f->curstat;}void freefa(fa *f) /* free a finite automaton */{ register int i; if (f == NULL) return; for (i = 0; i <= f->curstat; i++) xfree(f->posns[i]); for (i = 0; i <= f->accept; i++) { xfree(f->re[i].lfollow); if (f->re[i].ltype == CCL || f->re[i].ltype == NCCL) xfree(f->re[i].lval); } xfree(f->restr); xfree(f);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -