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