xref: /csrg-svn/bin/expr/expr.y (revision 53811)
147840Sbostic /*-
247840Sbostic  * Copyright (c) 1991 The Regents of the University of California.
347840Sbostic  * All rights reserved.
447840Sbostic  *
5*53811Sbostic  * %sccs.include.proprietary.c%
647840Sbostic  */
747840Sbostic 
81177Sbill /* Yacc productions for "expr" command: */
943665Sbostic %{
1043665Sbostic typedef char *yystype;
1143665Sbostic #define	YYSTYPE yystype
1243665Sbostic %}
131177Sbill 
141177Sbill %token OR AND ADD SUBT MULT DIV REM EQ GT GEQ LT LEQ NEQ
151177Sbill %token A_STRING SUBSTR LENGTH INDEX NOARG MATCH
161177Sbill 
171177Sbill /* operators listed below in increasing precedence: */
181177Sbill %left OR
191177Sbill %left AND
201177Sbill %left EQ LT GT GEQ LEQ NEQ
211177Sbill %left ADD SUBT
221177Sbill %left MULT DIV REM
231177Sbill %left MCH
241177Sbill %left MATCH
251177Sbill %left SUBSTR
261177Sbill %left LENGTH INDEX
271177Sbill %%
281177Sbill 
291177Sbill /* a single `expression' is evaluated and printed: */
301177Sbill 
311177Sbill expression:	expr NOARG = {
321177Sbill 			printf("%s\n", $1);
331177Sbill 			exit((!strcmp($1,"0")||!strcmp($1,"\0"))? 1: 0);
341177Sbill 			}
351177Sbill 	;
361177Sbill 
371177Sbill 
381177Sbill expr:	'(' expr ')' = { $$ = $2; }
391177Sbill 	| expr OR expr   = { $$ = conj(OR, $1, $3); }
401177Sbill 	| expr AND expr   = { $$ = conj(AND, $1, $3); }
411177Sbill 	| expr EQ expr   = { $$ = rel(EQ, $1, $3); }
421177Sbill 	| expr GT expr   = { $$ = rel(GT, $1, $3); }
431177Sbill 	| expr GEQ expr   = { $$ = rel(GEQ, $1, $3); }
441177Sbill 	| expr LT expr   = { $$ = rel(LT, $1, $3); }
451177Sbill 	| expr LEQ expr   = { $$ = rel(LEQ, $1, $3); }
461177Sbill 	| expr NEQ expr   = { $$ = rel(NEQ, $1, $3); }
471177Sbill 	| expr ADD expr   = { $$ = arith(ADD, $1, $3); }
481177Sbill 	| expr SUBT expr   = { $$ = arith(SUBT, $1, $3); }
491177Sbill 	| expr MULT expr   = { $$ = arith(MULT, $1, $3); }
501177Sbill 	| expr DIV expr   = { $$ = arith(DIV, $1, $3); }
511177Sbill 	| expr REM expr   = { $$ = arith(REM, $1, $3); }
521177Sbill 	| expr MCH expr	 = { $$ = match($1, $3); }
531177Sbill 	| MATCH expr expr = { $$ = match($2, $3); }
541177Sbill 	| SUBSTR expr expr expr = { $$ = substr($2, $3, $4); }
551177Sbill 	| LENGTH expr       = { $$ = length($2); }
561177Sbill 	| INDEX expr expr = { $$ = index($2, $3); }
571177Sbill 	| A_STRING
581177Sbill 	;
591177Sbill %%
601177Sbill /*	expression command */
6147840Sbostic 
6247840Sbostic #ifndef lint
6347840Sbostic char copyright[] =
6447840Sbostic "@(#) Copyright (c) 1991 The Regents of the University of California.\n\
6547840Sbostic  All rights reserved.\n";
6647840Sbostic #endif /* not lint */
6747840Sbostic 
6847840Sbostic #ifndef lint
69*53811Sbostic static char sccsid[] = "@(#)expr.y	5.3 (Berkeley) 06/02/92";
7047840Sbostic #endif /* not lint */
7147840Sbostic 
721177Sbill #include <stdio.h>
731177Sbill #define ESIZE	256
741177Sbill #define error(c)	errxx(c)
751177Sbill #define EQL(x,y) !strcmp(x,y)
761177Sbill long atol();
771177Sbill char	**Av;
781177Sbill int	Ac;
791177Sbill int	Argi;
801177Sbill 
811177Sbill char Mstring[1][128];
821177Sbill char *malloc();
831177Sbill extern int nbra;
841177Sbill 
851177Sbill main(argc, argv) char **argv; {
861177Sbill 	Ac = argc;
871177Sbill 	Argi = 1;
881177Sbill 	Av = argv;
891177Sbill 	yyparse();
901177Sbill }
911177Sbill 
921177Sbill char *operators[] = { "|", "&", "+", "-", "*", "/", "%", ":",
931177Sbill 	"=", "==", "<", "<=", ">", ">=", "!=",
941177Sbill 	"match", "substr", "length", "index", "\0" };
951177Sbill int op[] = { OR, AND, ADD,  SUBT, MULT, DIV, REM, MCH,
961177Sbill 	EQ, EQ, LT, LEQ, GT, GEQ, NEQ,
971177Sbill 	MATCH, SUBSTR, LENGTH, INDEX };
981177Sbill yylex() {
991177Sbill 	register char *p;
1001177Sbill 	register i;
1011177Sbill 
1021177Sbill 	if(Argi >= Ac) return NOARG;
1031177Sbill 
1041177Sbill 	p = Av[Argi++];
1051177Sbill 
1061177Sbill 	if(*p == '(' || *p == ')')
1071177Sbill 		return (int)*p;
1081177Sbill 	for(i = 0; *operators[i]; ++i)
1091177Sbill 		if(EQL(operators[i], p))
1101177Sbill 			return op[i];
1111177Sbill 
1121177Sbill 	yylval = p;
1131177Sbill 	return A_STRING;
1141177Sbill }
1151177Sbill 
1161177Sbill char *rel(op, r1, r2) register char *r1, *r2; {
11713483Ssam 	register long i;
1181177Sbill 
1191177Sbill 	if(ematch(r1, "-*[0-9]*$") && ematch(r2, "[0-9]*$"))
1201177Sbill 		i = atol(r1) - atol(r2);
1211177Sbill 	else
1221177Sbill 		i = strcmp(r1, r2);
1231177Sbill 	switch(op) {
1241177Sbill 	case EQ: i = i==0; break;
1251177Sbill 	case GT: i = i>0; break;
1261177Sbill 	case GEQ: i = i>=0; break;
1271177Sbill 	case LT: i = i<0; break;
1283175Swnj 	case LEQ: i = i<=0; break;
1291177Sbill 	case NEQ: i = i!=0; break;
1301177Sbill 	}
1311177Sbill 	return i? "1": "0";
1321177Sbill }
1331177Sbill 
1341177Sbill char *arith(op, r1, r2) char *r1, *r2; {
1351177Sbill 	long i1, i2;
1361177Sbill 	register char *rv;
1371177Sbill 
13832132Sbostic 	if(!((ematch(r1, "[0-9]*$") || ematch(r1, "-[0-9]*$")) &&
13932132Sbostic 	     (ematch(r2, "[0-9]*$") || ematch(r2, "-[0-9]*$"))))
1401177Sbill 		yyerror("non-numeric argument");
1411177Sbill 	i1 = atol(r1);
1421177Sbill 	i2 = atol(r2);
1431177Sbill 
1441177Sbill 	switch(op) {
1451177Sbill 	case ADD: i1 = i1 + i2; break;
1461177Sbill 	case SUBT: i1 = i1 - i2; break;
1471177Sbill 	case MULT: i1 = i1 * i2; break;
14853608Sralph 	case DIV:
14953608Sralph 		if (i2 != 0)
15053608Sralph 			i1 = i1 / i2;
15153608Sralph 		else
15253608Sralph 			yyerror("Divide by zero");
15353608Sralph 		break;
15453608Sralph 	case REM:
15553608Sralph 		if (i2 != 0)
15653608Sralph 			i1 = i1 % i2;
15753608Sralph 		else
15853608Sralph 			yyerror("Remainder by zero");
15953608Sralph 		break;
1601177Sbill 	}
1611177Sbill 	rv = malloc(16);
16232411Sbostic 	(void)sprintf(rv, "%ld", i1);
1631177Sbill 	return rv;
1641177Sbill }
1651177Sbill char *conj(op, r1, r2) char *r1, *r2; {
1661177Sbill 	register char *rv;
1671177Sbill 
1681177Sbill 	switch(op) {
1691177Sbill 
1701177Sbill 	case OR:
1711177Sbill 		if(EQL(r1, "0")
1721177Sbill 		|| EQL(r1, ""))
1731177Sbill 			if(EQL(r2, "0")
1741177Sbill 			|| EQL(r2, ""))
1751177Sbill 				rv = "0";
1761177Sbill 			else
1771177Sbill 				rv = r2;
1781177Sbill 		else
1791177Sbill 			rv = r1;
1801177Sbill 		break;
1811177Sbill 	case AND:
1821177Sbill 		if(EQL(r1, "0")
1831177Sbill 		|| EQL(r1, ""))
1841177Sbill 			rv = "0";
1851177Sbill 		else if(EQL(r2, "0")
1861177Sbill 		|| EQL(r2, ""))
1871177Sbill 			rv = "0";
1881177Sbill 		else
1891177Sbill 			rv = r1;
1901177Sbill 		break;
1911177Sbill 	}
1921177Sbill 	return rv;
1931177Sbill }
1941177Sbill 
1951177Sbill char *substr(v, s, w) char *v, *s, *w; {
1961177Sbill register si, wi;
1971177Sbill register char *res;
1981177Sbill 
1991177Sbill 	si = atol(s);
2001177Sbill 	wi = atol(w);
2011177Sbill 	while(--si) if(*v) ++v;
2021177Sbill 
2031177Sbill 	res = v;
2041177Sbill 
2051177Sbill 	while(wi--) if(*v) ++v;
2061177Sbill 
2071177Sbill 	*v = '\0';
2081177Sbill 	return res;
2091177Sbill }
2101177Sbill 
2111177Sbill char *length(s) register char *s; {
2121177Sbill 	register i = 0;
2131177Sbill 	register char *rv;
2141177Sbill 
2151177Sbill 	while(*s++) ++i;
2161177Sbill 
2171177Sbill 	rv = malloc(8);
21832411Sbostic 	(void)sprintf(rv, "%d", i);
2191177Sbill 	return rv;
2201177Sbill }
2211177Sbill 
2221177Sbill char *index(s, t) char *s, *t; {
2231177Sbill 	register i, j;
2241177Sbill 	register char *rv;
2251177Sbill 
2261177Sbill 	for(i = 0; s[i] ; ++i)
2271177Sbill 		for(j = 0; t[j] ; ++j)
2281177Sbill 			if(s[i]==t[j]) {
22932411Sbostic 				(void)sprintf(rv = malloc(8), "%d", ++i);
2301177Sbill 				return rv;
2311177Sbill 			}
2321177Sbill 	return "0";
2331177Sbill }
2341177Sbill 
2351177Sbill char *match(s, p)
2361177Sbill {
2371177Sbill 	register char *rv;
2381177Sbill 
23932411Sbostic 	(void)sprintf(rv = malloc(8), "%d", ematch(s, p));
2401177Sbill 	if(nbra) {
2411177Sbill 		rv = malloc(strlen(Mstring[0])+1);
2421177Sbill 		strcpy(rv, Mstring[0]);
2431177Sbill 	}
2441177Sbill 	return rv;
2451177Sbill }
2461177Sbill 
2471177Sbill #define INIT	register char *sp = instring;
2481177Sbill #define GETC()		(*sp++)
2491177Sbill #define PEEKC()		(*sp)
2501177Sbill #define UNGETC(c)	(--sp)
2511177Sbill #define RETURN(c)	return
2521177Sbill #define ERROR(c)	errxx(c)
2531177Sbill 
2541177Sbill 
2551177Sbill ematch(s, p)
2561177Sbill char *s;
2571177Sbill register char *p;
2581177Sbill {
2591177Sbill 	static char expbuf[ESIZE];
2601177Sbill 	char *compile();
2611177Sbill 	register num;
2621177Sbill 	extern char *braslist[], *braelist[], *loc2;
2631177Sbill 
26416513Sralph 	compile(p, expbuf, &expbuf[ESIZE], 0);
2651177Sbill 	if(nbra > 1)
2661177Sbill 		yyerror("Too many '\\('s");
2671177Sbill 	if(advance(s, expbuf)) {
2681177Sbill 		if(nbra == 1) {
2691177Sbill 			p = braslist[0];
2701177Sbill 			num = braelist[0] - p;
2711177Sbill 			strncpy(Mstring[0], p, num);
2721177Sbill 			Mstring[0][num] = '\0';
2731177Sbill 		}
2741177Sbill 		return(loc2-s);
2751177Sbill 	}
2761177Sbill 	return(0);
2771177Sbill }
2781177Sbill 
2791177Sbill errxx(c)
2801177Sbill {
2811177Sbill 	yyerror("RE error");
2821177Sbill }
2831177Sbill 
2841177Sbill #define	CBRA	2
2851177Sbill #define	CCHR	4
2861177Sbill #define	CDOT	8
2871177Sbill #define	CCL	12
2881177Sbill #define	CDOL	20
2891177Sbill #define	CEOF	22
2901177Sbill #define	CKET	24
2911177Sbill #define	CBACK	36
2921177Sbill 
2931177Sbill #define	STAR	01
2941177Sbill #define RNGE	03
2951177Sbill 
2961177Sbill #define	NBRA	9
2971177Sbill 
2981177Sbill #define PLACE(c)	ep[c >> 3] |= bittab[c & 07]
2991177Sbill #define ISTHERE(c)	(ep[c >> 3] & bittab[c & 07])
3001177Sbill 
3011177Sbill char	*braslist[NBRA];
3021177Sbill char	*braelist[NBRA];
3031177Sbill int	nbra;
3041177Sbill char *loc1, *loc2, *locs;
3051177Sbill int	sed;
3061177Sbill 
3071177Sbill int	circf;
3081177Sbill int	low;
3091177Sbill int	size;
3101177Sbill 
3111177Sbill char	bittab[] = {
3121177Sbill 	1,
3131177Sbill 	2,
3141177Sbill 	4,
3151177Sbill 	8,
3161177Sbill 	16,
3171177Sbill 	32,
3181177Sbill 	64,
3191177Sbill 	128
3201177Sbill };
3211177Sbill 
3221177Sbill char *
3231177Sbill compile(instring, ep, endbuf, seof)
3241177Sbill register char *ep;
3251177Sbill char *instring, *endbuf;
3261177Sbill {
3271177Sbill 	INIT	/* Dependent declarations and initializations */
3281177Sbill 	register c;
3291177Sbill 	register eof = seof;
3301177Sbill 	char *lastep = instring;
3311177Sbill 	int cclcnt;
3321177Sbill 	char bracket[NBRA], *bracketp;
3331177Sbill 	int closed;
3341177Sbill 	char neg;
3351177Sbill 	int lc;
3361177Sbill 	int i, cflg;
3371177Sbill 
3381177Sbill 	lastep = 0;
3391177Sbill 	if((c = GETC()) == eof) {
3401177Sbill 		if(*ep == 0 && !sed)
3411177Sbill 			ERROR(41);
3421177Sbill 		RETURN(ep);
3431177Sbill 	}
3441177Sbill 	bracketp = bracket;
3451177Sbill 	circf = closed = nbra = 0;
3461177Sbill 	if (c == '^')
3471177Sbill 		circf++;
3481177Sbill 	else
3491177Sbill 		UNGETC(c);
3501177Sbill 	for (;;) {
3511177Sbill 		if (ep >= endbuf)
3521177Sbill 			ERROR(50);
3531177Sbill 		if((c = GETC()) != '*' && ((c != '\\') || (PEEKC() != '{')))
3541177Sbill 			lastep = ep;
3551177Sbill 		if (c == eof) {
3561177Sbill 			*ep++ = CEOF;
3571177Sbill 			RETURN(ep);
3581177Sbill 		}
3591177Sbill 		switch (c) {
3601177Sbill 
3611177Sbill 		case '.':
3621177Sbill 			*ep++ = CDOT;
3631177Sbill 			continue;
3641177Sbill 
3651177Sbill 		case '\n':
3661177Sbill 			ERROR(36);
3671177Sbill 		case '*':
3681177Sbill 			if (lastep==0 || *lastep==CBRA || *lastep==CKET)
3691177Sbill 				goto defchar;
3701177Sbill 			*lastep |= STAR;
3711177Sbill 			continue;
3721177Sbill 
3731177Sbill 		case '$':
3741177Sbill 			if(PEEKC() != eof)
3751177Sbill 				goto defchar;
3761177Sbill 			*ep++ = CDOL;
3771177Sbill 			continue;
3781177Sbill 
3791177Sbill 		case '[':
3801177Sbill 			if(&ep[17] >= endbuf)
3811177Sbill 				ERROR(50);
3821177Sbill 
3831177Sbill 			*ep++ = CCL;
3841177Sbill 			lc = 0;
3851177Sbill 			for(i = 0; i < 16; i++)
3861177Sbill 				ep[i] = 0;
3871177Sbill 
3881177Sbill 			neg = 0;
3891177Sbill 			if((c = GETC()) == '^') {
3901177Sbill 				neg = 1;
3911177Sbill 				c = GETC();
3921177Sbill 			}
3931177Sbill 
3941177Sbill 			do {
3951177Sbill 				if(c == '\0' || c == '\n')
3961177Sbill 					ERROR(49);
3971177Sbill 				if(c == '-' && lc != 0) {
3981177Sbill 					if ((c = GETC()) == ']') {
3991177Sbill 						PLACE('-');
4001177Sbill 						break;
4011177Sbill 					}
4021177Sbill 					while(lc < c) {
4031177Sbill 						PLACE(lc);
4041177Sbill 						lc++;
4051177Sbill 					}
4061177Sbill 				}
4071177Sbill 				lc = c;
4081177Sbill 				PLACE(c);
4091177Sbill 			} while((c = GETC()) != ']');
4101177Sbill 			if(neg) {
4111177Sbill 				for(cclcnt = 0; cclcnt < 16; cclcnt++)
4121177Sbill 					ep[cclcnt] ^= -1;
4131177Sbill 				ep[0] &= 0376;
4141177Sbill 			}
4151177Sbill 
4161177Sbill 			ep += 16;
4171177Sbill 
4181177Sbill 			continue;
4191177Sbill 
4201177Sbill 		case '\\':
4211177Sbill 			switch(c = GETC()) {
4221177Sbill 
4231177Sbill 			case '(':
4241177Sbill 				if(nbra >= NBRA)
4251177Sbill 					ERROR(43);
4261177Sbill 				*bracketp++ = nbra;
4271177Sbill 				*ep++ = CBRA;
4281177Sbill 				*ep++ = nbra++;
4291177Sbill 				continue;
4301177Sbill 
4311177Sbill 			case ')':
4321177Sbill 				if(bracketp <= bracket)
4331177Sbill 					ERROR(42);
4341177Sbill 				*ep++ = CKET;
4351177Sbill 				*ep++ = *--bracketp;
4361177Sbill 				closed++;
4371177Sbill 				continue;
4381177Sbill 
4391177Sbill 			case '{':
4401177Sbill 				if(lastep == (char *) (0))
4411177Sbill 					goto defchar;
4421177Sbill 				*lastep |= RNGE;
4431177Sbill 				cflg = 0;
4441177Sbill 			nlim:
4451177Sbill 				c = GETC();
4461177Sbill 				i = 0;
4471177Sbill 				do {
4481177Sbill 					if ('0' <= c && c <= '9')
4491177Sbill 						i = 10 * i + c - '0';
4501177Sbill 					else
4511177Sbill 						ERROR(16);
4521177Sbill 				} while(((c = GETC()) != '\\') && (c != ','));
4531177Sbill 				if (i > 255)
4541177Sbill 					ERROR(11);
4551177Sbill 				*ep++ = i;
4561177Sbill 				if (c == ',') {
4571177Sbill 					if(cflg++)
4581177Sbill 						ERROR(44);
4591177Sbill 					if((c = GETC()) == '\\')
4601177Sbill 						*ep++ = 255;
4611177Sbill 					else {
4621177Sbill 						UNGETC(c);
4631177Sbill 						goto nlim; /* get 2'nd number */
4641177Sbill 					}
4651177Sbill 				}
4661177Sbill 				if(GETC() != '}')
4671177Sbill 					ERROR(45);
4681177Sbill 				if(!cflg)	/* one number */
4691177Sbill 					*ep++ = i;
4701177Sbill 				else if((ep[-1] & 0377) < (ep[-2] & 0377))
4711177Sbill 					ERROR(46);
4721177Sbill 				continue;
4731177Sbill 
4741177Sbill 			case '\n':
4751177Sbill 				ERROR(36);
4761177Sbill 
4771177Sbill 			case 'n':
4781177Sbill 				c = '\n';
4791177Sbill 				goto defchar;
4801177Sbill 
4811177Sbill 			default:
4821177Sbill 				if(c >= '1' && c <= '9') {
4831177Sbill 					if((c -= '1') >= closed)
4841177Sbill 						ERROR(25);
4851177Sbill 					*ep++ = CBACK;
4861177Sbill 					*ep++ = c;
4871177Sbill 					continue;
4881177Sbill 				}
4891177Sbill 			}
4901177Sbill 			/* Drop through to default to use \ to turn off special chars */
4911177Sbill 
4921177Sbill 		defchar:
4931177Sbill 		default:
4941177Sbill 			lastep = ep;
4951177Sbill 			*ep++ = CCHR;
4961177Sbill 			*ep++ = c;
4971177Sbill 		}
4981177Sbill 	}
4991177Sbill }
5001177Sbill 
5011177Sbill step(p1, p2)
5021177Sbill register char *p1, *p2;
5031177Sbill {
5041177Sbill 	register c;
5051177Sbill 
5061177Sbill 	if (circf) {
5071177Sbill 		loc1 = p1;
5081177Sbill 		return(advance(p1, p2));
5091177Sbill 	}
5101177Sbill 	/* fast check for first character */
5111177Sbill 	if (*p2==CCHR) {
5121177Sbill 		c = p2[1];
5131177Sbill 		do {
5141177Sbill 			if (*p1 != c)
5151177Sbill 				continue;
5161177Sbill 			if (advance(p1, p2)) {
5171177Sbill 				loc1 = p1;
5181177Sbill 				return(1);
5191177Sbill 			}
5201177Sbill 		} while (*p1++);
5211177Sbill 		return(0);
5221177Sbill 	}
5231177Sbill 		/* regular algorithm */
5241177Sbill 	do {
5251177Sbill 		if (advance(p1, p2)) {
5261177Sbill 			loc1 = p1;
5271177Sbill 			return(1);
5281177Sbill 		}
5291177Sbill 	} while (*p1++);
5301177Sbill 	return(0);
5311177Sbill }
5321177Sbill 
5331177Sbill advance(lp, ep)
5341177Sbill register char *lp, *ep;
5351177Sbill {
5361177Sbill 	register char *curlp;
5371177Sbill 	char c;
5381177Sbill 	char *bbeg;
5391177Sbill 	int ct;
5401177Sbill 
5411177Sbill 	for (;;) switch (*ep++) {
5421177Sbill 
5431177Sbill 	case CCHR:
5441177Sbill 		if (*ep++ == *lp++)
5451177Sbill 			continue;
5461177Sbill 		return(0);
5471177Sbill 
5481177Sbill 	case CDOT:
5491177Sbill 		if (*lp++)
5501177Sbill 			continue;
5511177Sbill 		return(0);
5521177Sbill 
5531177Sbill 	case CDOL:
5541177Sbill 		if (*lp==0)
5551177Sbill 			continue;
5561177Sbill 		return(0);
5571177Sbill 
5581177Sbill 	case CEOF:
5591177Sbill 		loc2 = lp;
5601177Sbill 		return(1);
5611177Sbill 
5621177Sbill 	case CCL:
5631177Sbill 		c = *lp++ & 0177;
5641177Sbill 		if(ISTHERE(c)) {
5651177Sbill 			ep += 16;
5661177Sbill 			continue;
5671177Sbill 		}
5681177Sbill 		return(0);
5691177Sbill 	case CBRA:
5701177Sbill 		braslist[*ep++] = lp;
5711177Sbill 		continue;
5721177Sbill 
5731177Sbill 	case CKET:
5741177Sbill 		braelist[*ep++] = lp;
5751177Sbill 		continue;
5761177Sbill 
5771177Sbill 	case CCHR|RNGE:
5781177Sbill 		c = *ep++;
5791177Sbill 		getrnge(ep);
5801177Sbill 		while(low--)
5811177Sbill 			if(*lp++ != c)
5821177Sbill 				return(0);
5831177Sbill 		curlp = lp;
5841177Sbill 		while(size--)
5851177Sbill 			if(*lp++ != c)
5861177Sbill 				break;
5871177Sbill 		if(size < 0)
5881177Sbill 			lp++;
5891177Sbill 		ep += 2;
5901177Sbill 		goto star;
5911177Sbill 
5921177Sbill 	case CDOT|RNGE:
5931177Sbill 		getrnge(ep);
5941177Sbill 		while(low--)
5951177Sbill 			if(*lp++ == '\0')
5961177Sbill 				return(0);
5971177Sbill 		curlp = lp;
5981177Sbill 		while(size--)
5991177Sbill 			if(*lp++ == '\0')
6001177Sbill 				break;
6011177Sbill 		if(size < 0)
6021177Sbill 			lp++;
6031177Sbill 		ep += 2;
6041177Sbill 		goto star;
6051177Sbill 
6061177Sbill 	case CCL|RNGE:
6071177Sbill 		getrnge(ep + 16);
6081177Sbill 		while(low--) {
6091177Sbill 			c = *lp++ & 0177;
6101177Sbill 			if(!ISTHERE(c))
6111177Sbill 				return(0);
6121177Sbill 		}
6131177Sbill 		curlp = lp;
6141177Sbill 		while(size--) {
6151177Sbill 			c = *lp++ & 0177;
6161177Sbill 			if(!ISTHERE(c))
6171177Sbill 				break;
6181177Sbill 		}
6191177Sbill 		if(size < 0)
6201177Sbill 			lp++;
6211177Sbill 		ep += 18;		/* 16 + 2 */
6221177Sbill 		goto star;
6231177Sbill 
6241177Sbill 	case CBACK:
6251177Sbill 		bbeg = braslist[*ep];
6261177Sbill 		ct = braelist[*ep++] - bbeg;
6271177Sbill 
6281177Sbill 		if(ecmp(bbeg, lp, ct)) {
6291177Sbill 			lp += ct;
6301177Sbill 			continue;
6311177Sbill 		}
6321177Sbill 		return(0);
6331177Sbill 
6341177Sbill 	case CBACK|STAR:
6351177Sbill 		bbeg = braslist[*ep];
6361177Sbill 		ct = braelist[*ep++] - bbeg;
6371177Sbill 		curlp = lp;
6381177Sbill 		while(ecmp(bbeg, lp, ct))
6391177Sbill 			lp += ct;
6401177Sbill 
6411177Sbill 		while(lp >= curlp) {
6421177Sbill 			if(advance(lp, ep))	return(1);
6431177Sbill 			lp -= ct;
6441177Sbill 		}
6451177Sbill 		return(0);
6461177Sbill 
6471177Sbill 
6481177Sbill 	case CDOT|STAR:
6491177Sbill 		curlp = lp;
6501177Sbill 		while (*lp++);
6511177Sbill 		goto star;
6521177Sbill 
6531177Sbill 	case CCHR|STAR:
6541177Sbill 		curlp = lp;
6551177Sbill 		while (*lp++ == *ep);
6561177Sbill 		ep++;
6571177Sbill 		goto star;
6581177Sbill 
6591177Sbill 	case CCL|STAR:
6601177Sbill 		curlp = lp;
6611177Sbill 		do {
6621177Sbill 			c = *lp++ & 0177;
6631177Sbill 		} while(ISTHERE(c));
6641177Sbill 		ep += 16;
6651177Sbill 		goto star;
6661177Sbill 
6671177Sbill 	star:
6681177Sbill 		do {
6691177Sbill 			if(--lp == locs)
6701177Sbill 				break;
6711177Sbill 			if (advance(lp, ep))
6721177Sbill 				return(1);
6731177Sbill 		} while (lp > curlp);
6741177Sbill 		return(0);
6751177Sbill 
6761177Sbill 	}
6771177Sbill }
6781177Sbill 
6791177Sbill getrnge(str)
6801177Sbill register char *str;
6811177Sbill {
6821177Sbill 	low = *str++ & 0377;
68334081Sbostic 	size = (*str & 0377) == 255 ? 20000 : (*str & 0377) - low;
6841177Sbill }
6851177Sbill 
6861177Sbill ecmp(a, b, count)
6871177Sbill register char	*a, *b;
6881177Sbill register	count;
6891177Sbill {
6901177Sbill 	if(a == b) /* should have been caught in compile() */
6911177Sbill 		error(51);
6921177Sbill 	while(count--)
6931177Sbill 		if(*a++ != *b++)	return(0);
6941177Sbill 	return(1);
6951177Sbill }
6961177Sbill 
6971177Sbill yyerror(s)
6981177Sbill 
6991177Sbill {
7001177Sbill 	fprintf(stderr, "%s\n", s);
7011177Sbill 	exit(2);
7021177Sbill }
703