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

📄 sub2.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
# include "ldefs.c"cfoll(v)	int v;	{	register int i,j,k;	char *p;	i = name[v];	if(i < NCH) i = 1;	/* character */	switch(i){		case 1: case RSTR: case RCCL: case RNCCL: case RNULLS:			for(j=0;j<tptr;j++)				tmpstat[j] = FALSE;			count = 0;			follow(v);# ifdef PP			padd(foll,v);		/* packing version */# endif# ifndef PP			add(foll,v);		/* no packing version */# endif			if(i == RSTR) cfoll(left[v]);			else if(i == RCCL || i == RNCCL){	/* compress ccl list */				for(j=1; j<NCH;j++)					symbol[j] = (i==RNCCL);				p = left[v];				while(*p)					symbol[*p++] = (i == RCCL);				p = pcptr;				for(j=1;j<NCH;j++)					if(symbol[j]){						for(k=0;p+k < pcptr; k++)							if(cindex[j] == *(p+k))								break;						if(p+k >= pcptr)*pcptr++ = cindex[j];						}				*pcptr++ = 0;				if(pcptr > pchar + pchlen)					error("Too many packed character classes");				left[v] = p;				name[v] = RCCL;	/* RNCCL eliminated */# ifdef DEBUG				if(debug && *p){					printf("ccl %d: %d",v,*p++);					while(*p)						printf(", %d",*p++);					putchar('\n');					}# endif				}			break;		case CARAT:			cfoll(left[v]);			break;		case STAR: case PLUS: case QUEST: case RSCON: 			cfoll(left[v]);			break;		case BAR: case RCAT: case DIV: case RNEWE:			cfoll(left[v]);			cfoll(right[v]);			break;# ifdef DEBUG		case FINAL:		case S1FINAL:		case S2FINAL:			break;		default:			warning("bad switch cfoll %d",v);# endif		}	return;	}# ifdef DEBUGpfoll()	{	register int i,k,*p;	int j;	/* print sets of chars which may follow positions */	printf("pos\tchars\n");	for(i=0;i<tptr;i++)		if(p=foll[i]){			j = *p++;			if(j >= 1){				printf("%d:\t%d",i,*p++);				for(k=2;k<=j;k++)					printf(", %d",*p++);				putchar('\n');				}			}	return;	}# endifadd(array,n)  int **array;  int n; {	register int i, *temp;	register char *ctemp;	temp = nxtpos;	ctemp = tmpstat;	array[n] = nxtpos;		/* note no packing is done in positions */	*temp++ = count;	for(i=0;i<tptr;i++)		if(ctemp[i] == TRUE)			*temp++ = i;	nxtpos = temp;	if(nxtpos >= positions+maxpos)		error("Too many positions %s",(maxpos== MAXPOS?"\nTry using %p num":""));	return;	}follow(v)  int v;	{	register int p;	if(v >= tptr-1)return;	p = parent[v];	if(p == 0) return;	switch(name[p]){			/* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */		case RSTR:			if(tmpstat[p] == FALSE){				count++;				tmpstat[p] = TRUE;				}			break;		case STAR: case PLUS:			first(v);			follow(p);			break;		case BAR: case QUEST: case RNEWE:			follow(p);			break;		case RCAT: case DIV: 			if(v == left[p]){				if(nullstr[right[p]])					follow(p);				first(right[p]);				}			else follow(p);			break;		case RSCON: case CARAT: 			follow(p);			break;# ifdef DEBUG		default:			warning("bad switch follow %d",p);# endif		}	return;	}first(v)	/* calculate set of positions with v as root which can be active initially */  int v; {	register int i;	register char *p;	i = name[v];	if(i < NCH)i = 1;	switch(i){		case 1: case RCCL: case RNCCL: case RNULLS: case FINAL: case S1FINAL: case S2FINAL:			if(tmpstat[v] == FALSE){				count++;				tmpstat[v] = TRUE;				}			break;		case BAR: case RNEWE:			first(left[v]);			first(right[v]);			break;		case CARAT:			if(stnum % 2 == 1)				first(left[v]);			break;		case RSCON:			i = stnum/2 +1;			p = right[v];			while(*p)				if(*p++ == i){					first(left[v]);					break;					}			break;		case STAR: case QUEST: case PLUS:  case RSTR:			first(left[v]);			break;		case RCAT: case DIV:			first(left[v]);			if(nullstr[left[v]])				first(right[v]);			break;# ifdef DEBUG		default:			warning("bad switch first %d",v);# endif		}	return;	}cgoto(){	register int i, j, s;	int npos, curpos, n;	int tryit;	char tch[NCH];	int tst[NCH];	char *q;	/* generate initial state, for each start condition */	if(ratfor){		fprintf(fout,"blockdata\n");		fprintf(fout,"common /Lvstop/ vstop\n");		fprintf(fout,"define Svstop %d\n",nstates+1);		fprintf(fout,"integer vstop(Svstop)\n");		}	else fprintf(fout,"int yyvstop[] ={\n0,\n");	while(stnum < 2 || stnum/2 < sptr){		for(i = 0; i<tptr; i++) tmpstat[i] = 0;		count = 0;		if(tptr > 0)first(tptr-1);		add(state,stnum);# ifdef DEBUG		if(debug){			if(stnum > 1)				printf("%s:\n",sname[stnum/2]);			pstate(stnum);			}# endif		stnum++;		}	stnum--;	/* even stnum = might not be at line begin */	/* odd stnum  = must be at line begin */	/* even states can occur anywhere, odd states only at line begin */	for(s = 0; s <= stnum; s++){		tryit = FALSE;		cpackflg[s] = FALSE;		sfall[s] = -1;		acompute(s);		for(i=0;i<NCH;i++) symbol[i] = 0;		npos = *state[s];		for(i = 1; i<=npos; i++){			curpos = *(state[s]+i);			if(name[curpos] < NCH) symbol[name[curpos]] = TRUE;			else switch(name[curpos]){			case RCCL:				tryit = TRUE;				q = left[curpos];				while(*q){					for(j=1;j<NCH;j++)						if(cindex[j] == *q)							symbol[j] = TRUE;					q++;					}				break;			case RSTR:				symbol[right[curpos]] = TRUE;				break;# ifdef DEBUG			case RNULLS:			case FINAL:			case S1FINAL:			case S2FINAL:				break;			default:				warning("bad switch cgoto %d state %d",curpos,s);				break;# endif			}		}# ifdef DEBUG		if(debug){			printf("State %d transitions on:\n\t",s);			charc = 0;			for(i = 1; i<NCH; i++){				if(symbol[i]) allprint(i);				if(charc > LINESIZE){					charc = 0;					printf("\n\t");					}				}			putchar('\n');			}# endif		/* for each char, calculate next state */		n = 0;		for(i = 1; i<NCH; i++){			if(symbol[i]){				nextstate(s,i);		/* executed for each state, transition pair */				xstate = notin(stnum);				if(xstate == -2) warning("bad state  %d %o",s,i);				else if(xstate == -1){					if(stnum >= nstates)						error("Too many states %s",(nstates == NSTATES ? "\nTry using %n num":""));					add(state,++stnum);# ifdef DEBUG					if(debug)pstate(stnum);# endif					tch[n] = i;					tst[n++] = stnum;					}				else {		/* xstate >= 0 ==> state exists */					tch[n] = i;					tst[n++] = xstate;					}				}			}		tch[n] = 0;		tst[n] = -1;		/* pack transitions into permanent array */		if(n > 0) packtrans(s,tch,tst,n,tryit);		else gotof[s] = -1;		}	ratfor ? fprintf(fout,"end\n") : fprintf(fout,"0};\n");	return;	}	/*	Beware -- 70% of total CPU time is spent in this subroutine -		if you don't believe me - try it yourself ! */nextstate(s,c)  int s,c; {	register int j, *newpos;	register char *temp, *tz;	int *pos, i, *f, num, curpos, number;	/* state to goto from state s on char c */	num = *state[s];	temp = tmpstat;	pos = state[s] + 1;	for(i = 0; i<num; i++){		curpos = *pos++;		j = name[curpos];		if(j < NCH && j == c		|| j == RSTR && c == right[curpos]		|| j == RCCL && member(c,left[curpos])){			f = foll[curpos];			number = *f;			newpos = f+1;			for(j=0;j<number;j++)				temp[*newpos++] = 2;			}		}	j = 0;	tz = temp + tptr;	while(temp < tz){		if(*temp == 2){			j++;			*temp++ = 1;			}		else *temp++ = 0;		}	count = j;	return;	}notin(n)  int n;	{	/* see if tmpstat occurs previously */	register int *j,k;	register char *temp;	int i;	if(count == 0)		return(-2);	temp = tmpstat;	for(i=n;i>=0;i--){	/* for each state */		j = state[i];		if(count == *j++){			for(k=0;k<count;k++)				if(!temp[*j++])break;			if(k >= count)				return(i);			}		}	return(-1);	}packtrans(st,tch,tst,cnt,tryit)  int st, *tst, cnt,tryit;  char *tch; {	/* pack transitions into nchar, nexts */	/* nchar is terminated by '\0', nexts uses cnt, followed by elements */	/* gotof[st] = index into nchr, nexts for state st */	/* sfall[st] =  t implies t is fall back state for st */	/*	        == -1 implies no fall back */	int cmin, cval, tcnt, diff, p, *ast;	register int i,j,k;	char *ach;	int go[NCH], temp[NCH], c;	int swork[NCH];	char cwork[NCH];	int upper;	rcount =+ cnt;	cmin = -1;	cval = NCH;	ast = tst;	ach = tch;	/* try to pack transitions using ccl's */	if(!optim)goto nopack;		/* skip all compaction */	if(tryit){	/* ccl's used */		for(i=1;i<NCH;i++){			go[i] = temp[i] = -1;			symbol[i] = 1;			}		for(i=0;i<cnt;i++){			go[tch[i]] = tst[i];			symbol[tch[i]] = 0;			}		for(i=0; i<cnt;i++){			c = match[tch[i]];			if(go[c] != tst[i] || c == tch[i])				temp[tch[i]] = tst[i];			}		/* fill in error entries */		for(i=1;i<NCH;i++)			if(symbol[i]) temp[i] = -2;	/* error trans */		/* count them */		k = 0;		for(i=1;i<NCH;i++)			if(temp[i] != -1)k++;		if(k <cnt){	/* compress by char */# ifdef DEBUG			if(debug) printf("use compression  %d,  %d vs %d\n",st,k,cnt);# endif			k = 0;			for(i=1;i<NCH;i++)				if(temp[i] != -1){					cwork[k] = i;					swork[k++] = (temp[i] == -2 ? -1 : temp[i]);					}			cwork[k] = 0;# ifdef PC			ach = cwork;			ast = swork;			cnt = k;			cpackflg[st] = TRUE;# endif			}		}	for(i=0; i<st; i++){	/* get most similar state */				/* reject state with more transitions, state already represented by a third state,					and state which is compressed by char if ours is not to be */		if(sfall[i] != -1) continue;		if(cpackflg[st] == 1) if(!(cpackflg[i] == 1)) continue;		p = gotof[i];		if(p == -1) /* no transitions */ continue;		tcnt = nexts[p];		if(tcnt > cnt) continue;		diff = 0;		k = 0;		j = 0;		upper = p + tcnt;		while(ach[j] && p < upper){			while(ach[j] < nchar[p] && ach[j]){diff++; j++; }			if(ach[j] == 0)break;			if(ach[j] > nchar[p]){diff=NCH;break;}			/* ach[j] == nchar[p] */			if(ast[j] != nexts[++p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]]))diff++;			j++;			}		while(ach[j]){			diff++;			j++;			}		if(p < upper)diff = NCH;		if(diff < cval && diff < tcnt){			cval = diff;			cmin = i;			if(cval == 0)break;			}		}	/* cmin = state "most like" state st */# ifdef DEBUG	if(debug)printf("select st %d for st %d diff %d\n",cmin,st,cval);# endif# ifdef PS	if(cmin != -1){ /* if we can use st cmin */		gotof[st] = nptr;		k = 0;		sfall[st] = cmin;		p = gotof[cmin]+1;		j = 0;		while(ach[j]){			/* if cmin has a transition on c, then so will st */			/* st may be "larger" than cmin, however */			while(ach[j] < nchar[p-1] && ach[j]){				k++;

⌨️ 快捷键说明

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