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

📄 b.c

📁 著名Awk语言的编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
			s = ns;		else			s = cgoto(f, s, *p);		if (f->out[s])			return(1);	} while (*p++ != 0);	return(0);}int pmatch(fa *f, const char *p0)	/* longest match, for sub */{	int s, ns;	uschar *p = (uschar *) p0;	uschar *q;	int i, k;	/* s = f->reset ? makeinit(f,1) : f->initstat; */	if (f->reset) {		f->initstat = s = makeinit(f,1);	} else {		s = f->initstat;	}	patbeg = (char *) p;	patlen = -1;	do {		q = p;		do {			if (f->out[s])		/* final state */				patlen = q-p;			if ((ns = f->gototab[s][*q]) != 0)				s = ns;			else				s = cgoto(f, s, *q);			if (s == 1) {	/* no transition */				if (patlen >= 0) {					patbeg = (char *) 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 = (char *) 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);}int nematch(fa *f, const char *p0)	/* non-empty match, for sub */{	int s, ns;	uschar *p = (uschar *) p0;	uschar *q;	int i, k;	/* s = f->reset ? makeinit(f,1) : f->initstat; */	if (f->reset) {		f->initstat = s = makeinit(f,1);	} else {		s = f->initstat;	}	patlen = -1;	while (*p) {		q = p;		do {			if (f->out[s])		/* final state */				patlen = q-p;			if ((ns = f->gototab[s][*q]) != 0)				s = ns;			else				s = cgoto(f, s, *q);			if (s == 1) {	/* no transition */				if (patlen > 0) {					patbeg = (char *) 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 = (char *) 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(const char *p)	/* parses regular expression pointed to by p */{			/* uses relex() to scan regular expression */	Node *np;	dprintf( ("reparse <%s>\n", p) );	lastre = prestr = (uschar *) p;	/* prestr points to string to be parsed */	rtok = relex();	/* GNU compatibility: an empty regexp matches anything */	if (rtok == '\0')		/* FATAL("empty regular expression"); previous */		return(op2(ALL, NIL, NIL));	np = regexp();	if (rtok != '\0')		FATAL("syntax error in regular expression %s at %s", lastre, prestr);	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, itonp(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((char *) rlxstr));		rtok = relex();		return (unary(np));	case NCCL:		np = op2(NCCL, NIL, (Node *) cclenter((char *) rlxstr));		rtok = relex();		return (unary(np));	case '^':		rtok = relex();		return (unary(op2(CHAR, NIL, itonp(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			FATAL("syntax error in regular expression %s at %s", lastre, prestr);	default:		FATAL("illegal primary in regular expression %s at %s", lastre, prestr);	}	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);	}}/* * Character class definitions conformant to the POSIX locale as * defined in IEEE P1003.1 draft 7 of June 2001, assuming the source * and operating character sets are both ASCII (ISO646) or supersets * thereof. * * Note that to avoid overflowing the temporary buffer used in * relex(), the expanded character class (prior to range expansion) * must be less than twice the size of their full name. *//* Because isblank doesn't show up in any of the header files on any * system i use, it's defined here.  if some other locale has a richer * definition of "blank", define HAS_ISBLANK and provide your own * version. * the parentheses here are an attempt to find a path through the maze * of macro definition and/or function and/or version provided.  thanks * to nelson beebe for the suggestion; let's see if it works everywhere. */#ifndef HAS_ISBLANKint (isblank)(int c){	return c==' ' || c=='\t';}#endifstruct charclass {	const char *cc_name;	int cc_namelen;	int (*cc_func)(int);} charclasses[] = {	{ "alnum",	5,	isalnum },	{ "alpha",	5,	isalpha },	{ "blank",	5,	isblank },	{ "cntrl",	5,	iscntrl },	{ "digit",	5,	isdigit },	{ "graph",	5,	isgraph },	{ "lower",	5,	islower },	{ "print",	5,	isprint },	{ "punct",	5,	ispunct },	{ "space",	5,	isspace },	{ "upper",	5,	isupper },	{ "xdigit",	6,	isxdigit },	{ NULL,		0,	NULL },};int relex(void)		/* lexical analyzer for reparse */{	int c, n;	int cflag;	static uschar *buf = 0;	static int bufsz = 100;	uschar *bp;	struct charclass *cc;	int i;	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((char **) &prestr);		return CHAR;	default:		rlxval = c;		return CHAR;	case '[': 		if (buf == 0 && (buf = (uschar *) malloc(bufsz)) == NULL)			FATAL("out of space in reg expr %.10s..", lastre);		bp = buf;		if (*prestr == '^') {			cflag = 1;			prestr++;		}		else			cflag = 0;		n = 2 * strlen((const char *) prestr)+1;		if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, 0))			FATAL("out of space for reg expr %.10s...", lastre);		for (; ; ) {			if ((c = *prestr++) == '\\') {				*bp++ = '\\';				if ((c = *prestr++) == '\0')					FATAL("nonterminated character class %.20s...", lastre);				*bp++ = c;			/* } else if (c == '\n') { */			/* 	FATAL("newline in character class %.20s...", lastre); */			} else if (c == '[' && *prestr == ':') {				/* POSIX char class names, Dag-Erling Smorgrav, des@ofug.org */				for (cc = charclasses; cc->cc_name; cc++)					if (strncmp((const char *) prestr + 1, (const char *) cc->cc_name, cc->cc_namelen) == 0)						break;				if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' &&				    prestr[2 + cc->cc_namelen] == ']') {					prestr += cc->cc_namelen + 3;					for (i = 0; i < NCHARS; i++) {						if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, 0))						    FATAL("out of space for reg expr %.10s...", lastre);						if (cc->cc_func(i)) {							*bp++ = i;							n++;						}					}				} else					*bp++ = c;			} else if (c == '\0') {				FATAL("nonterminated character class %.20s", lastre);			} else if (bp == buf) {	/* 1st char is special */				*bp++ = c;			} else if (c == ']') {				*bp++ = 0;				rlxstr = (uschar *) tostring((char *) buf);				if (cflag == 0)					return CCL;				else					return NCCL;			} else				*bp++ = c;		}	}}int cgoto(fa *f, int s, int c){	int i, j, k;	int *p, *q;	while (f->accept >= maxsetvec) {	/* guessing here! */		maxsetvec *= 4;		setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));		tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));		if (setvec == 0 || tmpset == 0)			overflo("out of space in cgoto()");	}	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 == ptoi(f->re[p[i]].lval.np))			 || (k == DOT && c != 0 && c != HAT)			 || (k == ALL && c != 0)			 || (k == CCL && member(c, (char *) f->re[p[i]].lval.up))			 || (k == NCCL && !member(c, (char *) f->re[p[i]].lval.up) && c != 0 && c != HAT)) {				q = f->re[p[i]].lfollow;				for (j = 1; j <= *q; j++) {					if (q[j] >= maxsetvec) {						maxsetvec *= 4;						setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));						tmpset = (int *) realloc(setvec, maxsetvec * sizeof(int));						if (setvec == 0 || tmpset == 0)							overflo("cgoto overflow");					}					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 */{	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.np));	}	xfree(f->restr);	xfree(f);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -