⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 b.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -