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