653 lines · 13.9 KB · Text
RawDownload
%token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS%left SCON '/' NEWE%left '|'%left '$' '^'%left CHAR CCL NCCL '(' '.' STR NULLS%left ITER%left CAT%left '*' '+' '?' %{# include "ldefs.h"#define YYSTYPE union _yystype_union _yystype_{	int	i;	uchar	*cp;};%}%%%{int i;int j,k;int g;uchar *p;%}acc	:	lexinput	={	# ifdef DEBUG		if(debug) sect2dump();# endif	}	;lexinput:	defns delim prods end	|	defns delim end	={		if(!funcflag)phead2();		funcflag = TRUE;	}	| error	={# ifdef DEBUG		if(debug) {			sect1dump();			sect2dump();			}# endif		}	;end:		delim | ;defns:	defns STR STR	={	strcpy((char*)dp,(char*)$2.cp);		def[dptr] = dp;		dp += strlen((char*)$2.cp) + 1;		strcpy((char*)dp,(char*)$3.cp);		subs[dptr++] = dp;		if(dptr >= DEFSIZE)			error("Too many definitions");		dp += strlen((char*)$3.cp) + 1;		if(dp >= dchar+DEFCHAR)			error("Definitions too long");		subs[dptr]=def[dptr]=0;	/* for lookup - require ending null */	}	|	;delim:	DELIM	={# ifdef DEBUG		if(sect == DEFSECTION && debug) sect1dump();# endif		sect++;		}	;prods:	prods pr	={	$$.i = mn2(RNEWE,$1.i,$2.i);		}	|	pr	={	$$.i = $1.i;}	;pr:	r NEWE	={		if(divflg == TRUE)			i = mn1(S1FINAL,casecount);		else i = mn1(FINAL,casecount);		$$.i = mn2(RCAT,$1.i,i);		divflg = FALSE;		casecount++;		}	| error NEWE	={# ifdef DEBUG		if(debug) sect2dump();# endif		}r:	CHAR	={	$$.i = mn0($1.i); }	| STR	={		p = $1.cp;		i = mn0(*p++);		while(*p)			i = mn2(RSTR,i,*p++);		$$.i = i;		}	| '.'	={	symbol['\n'] = 0;		if(psave == FALSE){			p = ccptr;			psave = ccptr;			for(i=1;i<'\n';i++){				symbol[i] = 1;				*ccptr++ = i;				}			for(i='\n'+1;i<NCH;i++){				symbol[i] = 1;				*ccptr++ = i;				}			*ccptr++ = 0;			if(ccptr > ccl+CCLSIZE)				error("Too many large character classes");			}		else			p = psave;		$$.i = mnp(RCCL, p);		cclinter(1);		}	| CCL	={	$$.i = mnp(RCCL,$1.cp); }	| NCCL	={	$$.i = mnp(RNCCL,$1.cp); }	| r '*'	={	$$.i = mn1(STAR,$1.i); }	| r '+'	={	$$.i = mn1(PLUS,$1.i); }	| r '?'	={	$$.i = mn1(QUEST,$1.i); }	| r '|' r	={	$$.i = mn2(BAR,$1.i,$3.i); }	| r r %prec CAT	={	$$.i = mn2(RCAT,$1.i,$2.i); }	| r '/' r	={	if(!divflg){			j = mn1(S2FINAL,-casecount);			i = mn2(RCAT,$1.i,j);			$$.i = mn2(DIV,i,$3.i);			}		else {			$$.i = mn2(RCAT,$1.i,$3.i);			warning("Extra slash removed");			}		divflg = TRUE;		}	| r ITER ',' ITER '}'	={	if($2.i > $4.i){			i = $2.i;			$2.i = $4.i;			$4.i = i;			}		if($4.i <= 0)			warning("Iteration range must be positive");		else {			j = $1.i;			for(k = 2; k<=$2.i;k++)				j = mn2(RCAT,j,dupl($1.i));			for(i = $2.i+1; i<=$4.i; i++){				g = dupl($1.i);				for(k=2;k<=i;k++)					g = mn2(RCAT,g,dupl($1.i));				j = mn2(BAR,j,g);				}			$$.i = j;			}	}	| r ITER '}'	={		if($2.i < 0)warning("Can't have negative iteration");		else if($2.i == 0) $$.i = mn0(RNULLS);		else {			j = $1.i;			for(k=2;k<=$2.i;k++)				j = mn2(RCAT,j,dupl($1.i));			$$.i = j;			}		}	| r ITER ',' '}'	={				/* from n to infinity */		if($2.i < 0)warning("Can't have negative iteration");		else if($2.i == 0) $$.i = mn1(STAR,$1.i);		else if($2.i == 1)$$.i = mn1(PLUS,$1.i);		else {		/* >= 2 iterations minimum */			j = $1.i;			for(k=2;k<$2.i;k++)				j = mn2(RCAT,j,dupl($1.i));			k = mn1(PLUS,dupl($1.i));			$$.i = mn2(RCAT,j,k);			}		}	| SCON r	={	$$.i = mn2(RSCON,$2.i,(uintptr)$1.cp); }	| '^' r	={	$$.i = mn1(CARAT,$2.i); }	| r '$'	={	i = mn0('\n');		if(!divflg){			j = mn1(S2FINAL,-casecount);			k = mn2(RCAT,$1.i,j);			$$.i = mn2(DIV,k,i);			}		else $$.i = mn2(RCAT,$1.i,i);		divflg = TRUE;		}	| '(' r ')'	={	$$.i = $2.i; }	|	NULLS	={	$$.i = mn0(RNULLS); }	;%%intyylex(void){	uchar *p;	int c, i;	uchar  *t, *xp;	int n, j, k, x;	static int sectbegin;	static uchar token[TOKENSIZE];	static int iter; # ifdef DEBUG	yylval.i = 0;	yylval.p = 0;# endif 	if(sect == DEFSECTION) {		/* definitions section */		while(!eof) {			if(prev == '\n'){		/* next char is at beginning of line */				getl(p=buf);				switch(*p){				case '%':					switch(*(p+1)){					case '%':						lgate();						Bprint(&fout,"#define YYNEWLINE %d\n",'\n');						Bprint(&fout,"yylex(void){\nint nstr; extern int yyprevious;\n");						sectbegin = TRUE;						i = treesize*(sizeof(*name)+sizeof(*left)+							sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA;						p = myalloc(i,1);						if(p == 0)							error("Too little core for parse tree");						free(p);						name = myalloc(treesize,sizeof(*name));						left = myalloc(treesize,sizeof(*left));						right = myalloc(treesize,sizeof(*right));						nullstr = myalloc(treesize,sizeof(*nullstr));						parent = myalloc(treesize,sizeof(*parent));						ptr = myalloc(treesize,sizeof(*ptr));						if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0 || ptr == 0)							error("Too little core for parse tree");						return(freturn(DELIM));					case 'p': case 'P':	/* has overridden number of positions */						while(*p && !isdigit(*p))p++;						maxpos = atol((char*)p);# ifdef DEBUG						if (debug) print("positions (%%p) now %d\n",maxpos);# endif						if(report == 2)report = 1;						continue;					case 'n': case 'N':	/* has overridden number of states */						while(*p && !isdigit(*p))p++;						nstates = atol((char*)p);# ifdef DEBUG						if(debug)print( " no. states (%%n) now %d\n",nstates);# endif						if(report == 2)report = 1;						continue;					case 'e': case 'E':		/* has overridden number of tree nodes */						while(*p && !isdigit(*p))p++;						treesize = atol((char*)p);# ifdef DEBUG						if (debug) print("treesize (%%e) now %d\n",treesize);# endif						if(report == 2)report = 1;						continue;					case 'o': case 'O':						while (*p && !isdigit(*p))p++;						outsize = atol((char*)p);						if (report ==2) report=1;						continue;					case 'a': case 'A':		/* has overridden number of transitions */						while(*p && !isdigit(*p))p++;						if(report == 2)report = 1;						ntrans = atol((char*)p);# ifdef DEBUG						if (debug)print("N. trans (%%a) now %d\n",ntrans);# endif						continue;					case 'k': case 'K': /* overriden packed char classes */						while (*p && !isdigit(*p))p++;						if (report==2) report=1;						free(pchar);						pchlen = atol((char*)p);# ifdef DEBUG						if (debug) print( "Size classes (%%k) now %d\n",pchlen);# endif						pchar=pcptr=myalloc(pchlen, sizeof(*pchar));						continue;					case '{':						lgate();						while(getl(p) && strcmp((char*)p,"%}") != 0)							Bprint(&fout, "%s\n",(char*)p);						if(p[0] == '%') continue;						error("Premature eof");					case 's': case 'S':		/* start conditions */						lgate();						while(*p && strchr(" \t,", *p) == 0) p++;						n = TRUE;						while(n){							while(*p && strchr(" \t,", *p)) p++;							t = p;							while(*p && strchr(" \t,", *p) == 0)p++;							if(!*p) n = FALSE;							*p++ = 0;							if (*t == 0) continue;							i = sptr*2;							Bprint(&fout,"#define %s %d\n",(char*)t,i);							strcpy((char*)sp, (char*)t);							sname[sptr++] = sp;							sname[sptr] = 0;	/* required by lookup */							if(sptr >= STARTSIZE)								error("Too many start conditions");							sp += strlen((char*)sp) + 1;							if(sp >= stchar+STARTCHAR)								error("Start conditions too long");						}						continue;					default:						warning("Invalid request %s",p);						continue;					}	/* end of switch after seeing '%' */				case ' ': case '\t':		/* must be code */					lgate();					Bprint(&fout, "%s\n",(char*)p);					continue;				default:		/* definition */					while(*p && !isspace(*p)) p++;					if(*p == 0)						continue;					prev = *p;					*p = 0;					bptr = p+1;					yylval.cp = buf;					if(isdigit(buf[0]))						warning("Substitution strings may not begin with digits");					return(freturn(STR));				}			}			/* still sect 1, but prev != '\n' */			else {				p = bptr;				while(*p && isspace(*p)) p++;				if(*p == 0)					warning("No translation given - null string assumed");				strcpy((char*)token, (char*)p);				yylval.cp = token;				prev = '\n';				return(freturn(STR));			}		}		/* end of section one processing */	} else if(sect == RULESECTION){		/* rules and actions */		while(!eof){			switch(c=gch()){			case '\0':				return(freturn(0));			case '\n':				if(prev == '\n') continue;				x = NEWE;				break;			case ' ':			case '\t':				if(sectbegin == TRUE){					cpyact();					while((c=gch()) && c != '\n');					continue;				}				if(!funcflag)phead2();				funcflag = TRUE;				Bprint(&fout,"case %d:\n",casecount);				if(cpyact())					Bprint(&fout,"break;\n");				while((c=gch()) && c != '\n');				if(peek == ' ' || peek == '\t' || sectbegin == TRUE){					warning("Executable statements should occur right after %%");					continue;				}				x = NEWE;				break;			case '%':				if(prev != '\n') goto character;				if(peek == '{'){	/* included code */					getl(buf);					while(!eof && getl(buf) && strcmp("%}",(char*)buf) != 0)						Bprint(&fout,"%s\n",(char*)buf);					continue;				}				if(peek == '%'){					gch();					gch();					x = DELIM;					break;				}				goto character;			case '|':				if(peek == ' ' || peek == '\t' || peek == '\n'){					Bprint(&fout,"%d\n",30000+casecount++);					continue;				}				x = '|';				break;			case '$':				if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){					x = c;					break;				}				goto character;			case '^':				if(prev != '\n' && scon != TRUE) goto character;	/* valid only at line begin */				x = c;				break;			case '?':			case '+':			case '.':			case '*':			case '(':			case ')':			case ',':			case '/':				x = c;				break;			case '}':				iter = FALSE;				x = c;				break;			case '{':	/* either iteration or definition */				if(isdigit(c=gch())){	/* iteration */					iter = TRUE;				ieval:					i = 0;					while(isdigit(c)){						token[i++] = c;						c = gch();					}					token[i] = 0;					yylval.i = atol((char*)token);					munputc(c);					x = ITER;					break;				} else {		/* definition */					i = 0;					while(c && c!='}'){						token[i++] = c;						c = gch();					}					token[i] = 0;					i = lookup(token,def);					if(i < 0)						warning("Definition %s not found",token);					else						munputs(subs[i]);					continue;				}			case '<':		/* start condition ? */				if(prev != '\n')		/* not at line begin, not start */					goto character;				t = slptr;				do {					i = 0;					c = gch();					while(c != ',' && c && c != '>'){						token[i++] = c;						c = gch();					}					token[i] = 0;					if(i == 0)						goto character;					i = lookup(token,sname);					if(i < 0) {						warning("Undefined start condition %s",token);						continue;					}					*slptr++ = i+1;				} while(c && c != '>');				*slptr++ = 0;				/* check if previous value re-usable */				for (xp=slist; xp<t; ){					if (strcmp((char*)xp, (char*)t)==0)						break;					while (*xp++);				}

Lines 1–500 of 653.