14c0d4567Sbill /* Yacc productions for "expr" command: */ 24c0d4567Sbill 34c0d4567Sbill %token OR AND ADD SUBT MULT DIV REM EQ GT GEQ LT LEQ NEQ 44c0d4567Sbill %token A_STRING SUBSTR LENGTH INDEX NOARG MATCH 54c0d4567Sbill 64c0d4567Sbill /* operators listed below in increasing precedence: */ 74c0d4567Sbill %left OR 84c0d4567Sbill %left AND 94c0d4567Sbill %left EQ LT GT GEQ LEQ NEQ 104c0d4567Sbill %left ADD SUBT 114c0d4567Sbill %left MULT DIV REM 124c0d4567Sbill %left MCH 134c0d4567Sbill %left MATCH 144c0d4567Sbill %left SUBSTR 154c0d4567Sbill %left LENGTH INDEX 164c0d4567Sbill %% 174c0d4567Sbill 184c0d4567Sbill /* a single `expression' is evaluated and printed: */ 194c0d4567Sbill 204c0d4567Sbill expression: expr NOARG = { 214c0d4567Sbill printf("%s\n", $1); 224c0d4567Sbill exit((!strcmp($1,"0")||!strcmp($1,"\0"))? 1: 0); 234c0d4567Sbill } 244c0d4567Sbill ; 254c0d4567Sbill 264c0d4567Sbill 274c0d4567Sbill expr: '(' expr ')' = { $$ = $2; } 284c0d4567Sbill | expr OR expr = { $$ = conj(OR, $1, $3); } 294c0d4567Sbill | expr AND expr = { $$ = conj(AND, $1, $3); } 304c0d4567Sbill | expr EQ expr = { $$ = rel(EQ, $1, $3); } 314c0d4567Sbill | expr GT expr = { $$ = rel(GT, $1, $3); } 324c0d4567Sbill | expr GEQ expr = { $$ = rel(GEQ, $1, $3); } 334c0d4567Sbill | expr LT expr = { $$ = rel(LT, $1, $3); } 344c0d4567Sbill | expr LEQ expr = { $$ = rel(LEQ, $1, $3); } 354c0d4567Sbill | expr NEQ expr = { $$ = rel(NEQ, $1, $3); } 364c0d4567Sbill | expr ADD expr = { $$ = arith(ADD, $1, $3); } 374c0d4567Sbill | expr SUBT expr = { $$ = arith(SUBT, $1, $3); } 384c0d4567Sbill | expr MULT expr = { $$ = arith(MULT, $1, $3); } 394c0d4567Sbill | expr DIV expr = { $$ = arith(DIV, $1, $3); } 404c0d4567Sbill | expr REM expr = { $$ = arith(REM, $1, $3); } 414c0d4567Sbill | expr MCH expr = { $$ = match($1, $3); } 424c0d4567Sbill | MATCH expr expr = { $$ = match($2, $3); } 434c0d4567Sbill | SUBSTR expr expr expr = { $$ = substr($2, $3, $4); } 444c0d4567Sbill | LENGTH expr = { $$ = length($2); } 454c0d4567Sbill | INDEX expr expr = { $$ = index($2, $3); } 464c0d4567Sbill | A_STRING 474c0d4567Sbill ; 484c0d4567Sbill %% 494c0d4567Sbill /* expression command */ 504c0d4567Sbill #include <stdio.h> 514c0d4567Sbill #define ESIZE 256 524c0d4567Sbill #define error(c) errxx(c) 534c0d4567Sbill #define EQL(x,y) !strcmp(x,y) 544c0d4567Sbill long atol(); 554c0d4567Sbill char **Av; 564c0d4567Sbill int Ac; 574c0d4567Sbill int Argi; 584c0d4567Sbill 594c0d4567Sbill char Mstring[1][128]; 604c0d4567Sbill char *malloc(); 614c0d4567Sbill extern int nbra; 624c0d4567Sbill 634c0d4567Sbill main(argc, argv) char **argv; { 644c0d4567Sbill Ac = argc; 654c0d4567Sbill Argi = 1; 664c0d4567Sbill Av = argv; 674c0d4567Sbill yyparse(); 684c0d4567Sbill } 694c0d4567Sbill 704c0d4567Sbill char *operators[] = { "|", "&", "+", "-", "*", "/", "%", ":", 714c0d4567Sbill "=", "==", "<", "<=", ">", ">=", "!=", 724c0d4567Sbill "match", "substr", "length", "index", "\0" }; 734c0d4567Sbill int op[] = { OR, AND, ADD, SUBT, MULT, DIV, REM, MCH, 744c0d4567Sbill EQ, EQ, LT, LEQ, GT, GEQ, NEQ, 754c0d4567Sbill MATCH, SUBSTR, LENGTH, INDEX }; 764c0d4567Sbill yylex() { 774c0d4567Sbill register char *p; 784c0d4567Sbill register i; 794c0d4567Sbill 804c0d4567Sbill if(Argi >= Ac) return NOARG; 814c0d4567Sbill 824c0d4567Sbill p = Av[Argi++]; 834c0d4567Sbill 844c0d4567Sbill if(*p == '(' || *p == ')') 854c0d4567Sbill return (int)*p; 864c0d4567Sbill for(i = 0; *operators[i]; ++i) 874c0d4567Sbill if(EQL(operators[i], p)) 884c0d4567Sbill return op[i]; 894c0d4567Sbill 904c0d4567Sbill yylval = p; 914c0d4567Sbill return A_STRING; 924c0d4567Sbill } 934c0d4567Sbill 944c0d4567Sbill char *rel(op, r1, r2) register char *r1, *r2; { 95264c46cbSsam register long i; 964c0d4567Sbill 974c0d4567Sbill if(ematch(r1, "-*[0-9]*$") && ematch(r2, "[0-9]*$")) 984c0d4567Sbill i = atol(r1) - atol(r2); 994c0d4567Sbill else 1004c0d4567Sbill i = strcmp(r1, r2); 1014c0d4567Sbill switch(op) { 1024c0d4567Sbill case EQ: i = i==0; break; 1034c0d4567Sbill case GT: i = i>0; break; 1044c0d4567Sbill case GEQ: i = i>=0; break; 1054c0d4567Sbill case LT: i = i<0; break; 10656abee86Swnj case LEQ: i = i<=0; break; 1074c0d4567Sbill case NEQ: i = i!=0; break; 1084c0d4567Sbill } 1094c0d4567Sbill return i? "1": "0"; 1104c0d4567Sbill } 1114c0d4567Sbill 1124c0d4567Sbill char *arith(op, r1, r2) char *r1, *r2; { 1134c0d4567Sbill long i1, i2; 1144c0d4567Sbill register char *rv; 1154c0d4567Sbill 116a9c19d04Sbostic if(!((ematch(r1, "[0-9]*$") || ematch(r1, "-[0-9]*$")) && 117a9c19d04Sbostic (ematch(r2, "[0-9]*$") || ematch(r2, "-[0-9]*$")))) 1184c0d4567Sbill yyerror("non-numeric argument"); 1194c0d4567Sbill i1 = atol(r1); 1204c0d4567Sbill i2 = atol(r2); 1214c0d4567Sbill 1224c0d4567Sbill switch(op) { 1234c0d4567Sbill case ADD: i1 = i1 + i2; break; 1244c0d4567Sbill case SUBT: i1 = i1 - i2; break; 1254c0d4567Sbill case MULT: i1 = i1 * i2; break; 1264c0d4567Sbill case DIV: i1 = i1 / i2; break; 1274c0d4567Sbill case REM: i1 = i1 % i2; break; 1284c0d4567Sbill } 1294c0d4567Sbill rv = malloc(16); 130f703d710Sbostic (void)sprintf(rv, "%ld", i1); 1314c0d4567Sbill return rv; 1324c0d4567Sbill } 1334c0d4567Sbill char *conj(op, r1, r2) char *r1, *r2; { 1344c0d4567Sbill register char *rv; 1354c0d4567Sbill 1364c0d4567Sbill switch(op) { 1374c0d4567Sbill 1384c0d4567Sbill case OR: 1394c0d4567Sbill if(EQL(r1, "0") 1404c0d4567Sbill || EQL(r1, "")) 1414c0d4567Sbill if(EQL(r2, "0") 1424c0d4567Sbill || EQL(r2, "")) 1434c0d4567Sbill rv = "0"; 1444c0d4567Sbill else 1454c0d4567Sbill rv = r2; 1464c0d4567Sbill else 1474c0d4567Sbill rv = r1; 1484c0d4567Sbill break; 1494c0d4567Sbill case AND: 1504c0d4567Sbill if(EQL(r1, "0") 1514c0d4567Sbill || EQL(r1, "")) 1524c0d4567Sbill rv = "0"; 1534c0d4567Sbill else if(EQL(r2, "0") 1544c0d4567Sbill || EQL(r2, "")) 1554c0d4567Sbill rv = "0"; 1564c0d4567Sbill else 1574c0d4567Sbill rv = r1; 1584c0d4567Sbill break; 1594c0d4567Sbill } 1604c0d4567Sbill return rv; 1614c0d4567Sbill } 1624c0d4567Sbill 1634c0d4567Sbill char *substr(v, s, w) char *v, *s, *w; { 1644c0d4567Sbill register si, wi; 1654c0d4567Sbill register char *res; 1664c0d4567Sbill 1674c0d4567Sbill si = atol(s); 1684c0d4567Sbill wi = atol(w); 1694c0d4567Sbill while(--si) if(*v) ++v; 1704c0d4567Sbill 1714c0d4567Sbill res = v; 1724c0d4567Sbill 1734c0d4567Sbill while(wi--) if(*v) ++v; 1744c0d4567Sbill 1754c0d4567Sbill *v = '\0'; 1764c0d4567Sbill return res; 1774c0d4567Sbill } 1784c0d4567Sbill 1794c0d4567Sbill char *length(s) register char *s; { 1804c0d4567Sbill register i = 0; 1814c0d4567Sbill register char *rv; 1824c0d4567Sbill 1834c0d4567Sbill while(*s++) ++i; 1844c0d4567Sbill 1854c0d4567Sbill rv = malloc(8); 186f703d710Sbostic (void)sprintf(rv, "%d", i); 1874c0d4567Sbill return rv; 1884c0d4567Sbill } 1894c0d4567Sbill 1904c0d4567Sbill char *index(s, t) char *s, *t; { 1914c0d4567Sbill register i, j; 1924c0d4567Sbill register char *rv; 1934c0d4567Sbill 1944c0d4567Sbill for(i = 0; s[i] ; ++i) 1954c0d4567Sbill for(j = 0; t[j] ; ++j) 1964c0d4567Sbill if(s[i]==t[j]) { 197f703d710Sbostic (void)sprintf(rv = malloc(8), "%d", ++i); 1984c0d4567Sbill return rv; 1994c0d4567Sbill } 2004c0d4567Sbill return "0"; 2014c0d4567Sbill } 2024c0d4567Sbill 2034c0d4567Sbill char *match(s, p) 2044c0d4567Sbill { 2054c0d4567Sbill register char *rv; 2064c0d4567Sbill 207f703d710Sbostic (void)sprintf(rv = malloc(8), "%d", ematch(s, p)); 2084c0d4567Sbill if(nbra) { 2094c0d4567Sbill rv = malloc(strlen(Mstring[0])+1); 2104c0d4567Sbill strcpy(rv, Mstring[0]); 2114c0d4567Sbill } 2124c0d4567Sbill return rv; 2134c0d4567Sbill } 2144c0d4567Sbill 2154c0d4567Sbill #define INIT register char *sp = instring; 2164c0d4567Sbill #define GETC() (*sp++) 2174c0d4567Sbill #define PEEKC() (*sp) 2184c0d4567Sbill #define UNGETC(c) (--sp) 2194c0d4567Sbill #define RETURN(c) return 2204c0d4567Sbill #define ERROR(c) errxx(c) 2214c0d4567Sbill 2224c0d4567Sbill 2234c0d4567Sbill ematch(s, p) 2244c0d4567Sbill char *s; 2254c0d4567Sbill register char *p; 2264c0d4567Sbill { 2274c0d4567Sbill static char expbuf[ESIZE]; 2284c0d4567Sbill char *compile(); 2294c0d4567Sbill register num; 2304c0d4567Sbill extern char *braslist[], *braelist[], *loc2; 2314c0d4567Sbill 232e74403baSralph compile(p, expbuf, &expbuf[ESIZE], 0); 2334c0d4567Sbill if(nbra > 1) 2344c0d4567Sbill yyerror("Too many '\\('s"); 2354c0d4567Sbill if(advance(s, expbuf)) { 2364c0d4567Sbill if(nbra == 1) { 2374c0d4567Sbill p = braslist[0]; 2384c0d4567Sbill num = braelist[0] - p; 2394c0d4567Sbill strncpy(Mstring[0], p, num); 2404c0d4567Sbill Mstring[0][num] = '\0'; 2414c0d4567Sbill } 2424c0d4567Sbill return(loc2-s); 2434c0d4567Sbill } 2444c0d4567Sbill return(0); 2454c0d4567Sbill } 2464c0d4567Sbill 2474c0d4567Sbill errxx(c) 2484c0d4567Sbill { 2494c0d4567Sbill yyerror("RE error"); 2504c0d4567Sbill } 2514c0d4567Sbill 2524c0d4567Sbill #define CBRA 2 2534c0d4567Sbill #define CCHR 4 2544c0d4567Sbill #define CDOT 8 2554c0d4567Sbill #define CCL 12 2564c0d4567Sbill #define CDOL 20 2574c0d4567Sbill #define CEOF 22 2584c0d4567Sbill #define CKET 24 2594c0d4567Sbill #define CBACK 36 2604c0d4567Sbill 2614c0d4567Sbill #define STAR 01 2624c0d4567Sbill #define RNGE 03 2634c0d4567Sbill 2644c0d4567Sbill #define NBRA 9 2654c0d4567Sbill 2664c0d4567Sbill #define PLACE(c) ep[c >> 3] |= bittab[c & 07] 2674c0d4567Sbill #define ISTHERE(c) (ep[c >> 3] & bittab[c & 07]) 2684c0d4567Sbill 2694c0d4567Sbill char *braslist[NBRA]; 2704c0d4567Sbill char *braelist[NBRA]; 2714c0d4567Sbill int nbra; 2724c0d4567Sbill char *loc1, *loc2, *locs; 2734c0d4567Sbill int sed; 2744c0d4567Sbill 2754c0d4567Sbill int circf; 2764c0d4567Sbill int low; 2774c0d4567Sbill int size; 2784c0d4567Sbill 2794c0d4567Sbill char bittab[] = { 2804c0d4567Sbill 1, 2814c0d4567Sbill 2, 2824c0d4567Sbill 4, 2834c0d4567Sbill 8, 2844c0d4567Sbill 16, 2854c0d4567Sbill 32, 2864c0d4567Sbill 64, 2874c0d4567Sbill 128 2884c0d4567Sbill }; 2894c0d4567Sbill 2904c0d4567Sbill char * 2914c0d4567Sbill compile(instring, ep, endbuf, seof) 2924c0d4567Sbill register char *ep; 2934c0d4567Sbill char *instring, *endbuf; 2944c0d4567Sbill { 2954c0d4567Sbill INIT /* Dependent declarations and initializations */ 2964c0d4567Sbill register c; 2974c0d4567Sbill register eof = seof; 2984c0d4567Sbill char *lastep = instring; 2994c0d4567Sbill int cclcnt; 3004c0d4567Sbill char bracket[NBRA], *bracketp; 3014c0d4567Sbill int closed; 3024c0d4567Sbill char neg; 3034c0d4567Sbill int lc; 3044c0d4567Sbill int i, cflg; 3054c0d4567Sbill 3064c0d4567Sbill lastep = 0; 3074c0d4567Sbill if((c = GETC()) == eof) { 3084c0d4567Sbill if(*ep == 0 && !sed) 3094c0d4567Sbill ERROR(41); 3104c0d4567Sbill RETURN(ep); 3114c0d4567Sbill } 3124c0d4567Sbill bracketp = bracket; 3134c0d4567Sbill circf = closed = nbra = 0; 3144c0d4567Sbill if (c == '^') 3154c0d4567Sbill circf++; 3164c0d4567Sbill else 3174c0d4567Sbill UNGETC(c); 3184c0d4567Sbill for (;;) { 3194c0d4567Sbill if (ep >= endbuf) 3204c0d4567Sbill ERROR(50); 3214c0d4567Sbill if((c = GETC()) != '*' && ((c != '\\') || (PEEKC() != '{'))) 3224c0d4567Sbill lastep = ep; 3234c0d4567Sbill if (c == eof) { 3244c0d4567Sbill *ep++ = CEOF; 3254c0d4567Sbill RETURN(ep); 3264c0d4567Sbill } 3274c0d4567Sbill switch (c) { 3284c0d4567Sbill 3294c0d4567Sbill case '.': 3304c0d4567Sbill *ep++ = CDOT; 3314c0d4567Sbill continue; 3324c0d4567Sbill 3334c0d4567Sbill case '\n': 3344c0d4567Sbill ERROR(36); 3354c0d4567Sbill case '*': 3364c0d4567Sbill if (lastep==0 || *lastep==CBRA || *lastep==CKET) 3374c0d4567Sbill goto defchar; 3384c0d4567Sbill *lastep |= STAR; 3394c0d4567Sbill continue; 3404c0d4567Sbill 3414c0d4567Sbill case '$': 3424c0d4567Sbill if(PEEKC() != eof) 3434c0d4567Sbill goto defchar; 3444c0d4567Sbill *ep++ = CDOL; 3454c0d4567Sbill continue; 3464c0d4567Sbill 3474c0d4567Sbill case '[': 3484c0d4567Sbill if(&ep[17] >= endbuf) 3494c0d4567Sbill ERROR(50); 3504c0d4567Sbill 3514c0d4567Sbill *ep++ = CCL; 3524c0d4567Sbill lc = 0; 3534c0d4567Sbill for(i = 0; i < 16; i++) 3544c0d4567Sbill ep[i] = 0; 3554c0d4567Sbill 3564c0d4567Sbill neg = 0; 3574c0d4567Sbill if((c = GETC()) == '^') { 3584c0d4567Sbill neg = 1; 3594c0d4567Sbill c = GETC(); 3604c0d4567Sbill } 3614c0d4567Sbill 3624c0d4567Sbill do { 3634c0d4567Sbill if(c == '\0' || c == '\n') 3644c0d4567Sbill ERROR(49); 3654c0d4567Sbill if(c == '-' && lc != 0) { 3664c0d4567Sbill if ((c = GETC()) == ']') { 3674c0d4567Sbill PLACE('-'); 3684c0d4567Sbill break; 3694c0d4567Sbill } 3704c0d4567Sbill while(lc < c) { 3714c0d4567Sbill PLACE(lc); 3724c0d4567Sbill lc++; 3734c0d4567Sbill } 3744c0d4567Sbill } 3754c0d4567Sbill lc = c; 3764c0d4567Sbill PLACE(c); 3774c0d4567Sbill } while((c = GETC()) != ']'); 3784c0d4567Sbill if(neg) { 3794c0d4567Sbill for(cclcnt = 0; cclcnt < 16; cclcnt++) 3804c0d4567Sbill ep[cclcnt] ^= -1; 3814c0d4567Sbill ep[0] &= 0376; 3824c0d4567Sbill } 3834c0d4567Sbill 3844c0d4567Sbill ep += 16; 3854c0d4567Sbill 3864c0d4567Sbill continue; 3874c0d4567Sbill 3884c0d4567Sbill case '\\': 3894c0d4567Sbill switch(c = GETC()) { 3904c0d4567Sbill 3914c0d4567Sbill case '(': 3924c0d4567Sbill if(nbra >= NBRA) 3934c0d4567Sbill ERROR(43); 3944c0d4567Sbill *bracketp++ = nbra; 3954c0d4567Sbill *ep++ = CBRA; 3964c0d4567Sbill *ep++ = nbra++; 3974c0d4567Sbill continue; 3984c0d4567Sbill 3994c0d4567Sbill case ')': 4004c0d4567Sbill if(bracketp <= bracket) 4014c0d4567Sbill ERROR(42); 4024c0d4567Sbill *ep++ = CKET; 4034c0d4567Sbill *ep++ = *--bracketp; 4044c0d4567Sbill closed++; 4054c0d4567Sbill continue; 4064c0d4567Sbill 4074c0d4567Sbill case '{': 4084c0d4567Sbill if(lastep == (char *) (0)) 4094c0d4567Sbill goto defchar; 4104c0d4567Sbill *lastep |= RNGE; 4114c0d4567Sbill cflg = 0; 4124c0d4567Sbill nlim: 4134c0d4567Sbill c = GETC(); 4144c0d4567Sbill i = 0; 4154c0d4567Sbill do { 4164c0d4567Sbill if ('0' <= c && c <= '9') 4174c0d4567Sbill i = 10 * i + c - '0'; 4184c0d4567Sbill else 4194c0d4567Sbill ERROR(16); 4204c0d4567Sbill } while(((c = GETC()) != '\\') && (c != ',')); 4214c0d4567Sbill if (i > 255) 4224c0d4567Sbill ERROR(11); 4234c0d4567Sbill *ep++ = i; 4244c0d4567Sbill if (c == ',') { 4254c0d4567Sbill if(cflg++) 4264c0d4567Sbill ERROR(44); 4274c0d4567Sbill if((c = GETC()) == '\\') 4284c0d4567Sbill *ep++ = 255; 4294c0d4567Sbill else { 4304c0d4567Sbill UNGETC(c); 4314c0d4567Sbill goto nlim; /* get 2'nd number */ 4324c0d4567Sbill } 4334c0d4567Sbill } 4344c0d4567Sbill if(GETC() != '}') 4354c0d4567Sbill ERROR(45); 4364c0d4567Sbill if(!cflg) /* one number */ 4374c0d4567Sbill *ep++ = i; 4384c0d4567Sbill else if((ep[-1] & 0377) < (ep[-2] & 0377)) 4394c0d4567Sbill ERROR(46); 4404c0d4567Sbill continue; 4414c0d4567Sbill 4424c0d4567Sbill case '\n': 4434c0d4567Sbill ERROR(36); 4444c0d4567Sbill 4454c0d4567Sbill case 'n': 4464c0d4567Sbill c = '\n'; 4474c0d4567Sbill goto defchar; 4484c0d4567Sbill 4494c0d4567Sbill default: 4504c0d4567Sbill if(c >= '1' && c <= '9') { 4514c0d4567Sbill if((c -= '1') >= closed) 4524c0d4567Sbill ERROR(25); 4534c0d4567Sbill *ep++ = CBACK; 4544c0d4567Sbill *ep++ = c; 4554c0d4567Sbill continue; 4564c0d4567Sbill } 4574c0d4567Sbill } 4584c0d4567Sbill /* Drop through to default to use \ to turn off special chars */ 4594c0d4567Sbill 4604c0d4567Sbill defchar: 4614c0d4567Sbill default: 4624c0d4567Sbill lastep = ep; 4634c0d4567Sbill *ep++ = CCHR; 4644c0d4567Sbill *ep++ = c; 4654c0d4567Sbill } 4664c0d4567Sbill } 4674c0d4567Sbill } 4684c0d4567Sbill 4694c0d4567Sbill step(p1, p2) 4704c0d4567Sbill register char *p1, *p2; 4714c0d4567Sbill { 4724c0d4567Sbill register c; 4734c0d4567Sbill 4744c0d4567Sbill if (circf) { 4754c0d4567Sbill loc1 = p1; 4764c0d4567Sbill return(advance(p1, p2)); 4774c0d4567Sbill } 4784c0d4567Sbill /* fast check for first character */ 4794c0d4567Sbill if (*p2==CCHR) { 4804c0d4567Sbill c = p2[1]; 4814c0d4567Sbill do { 4824c0d4567Sbill if (*p1 != c) 4834c0d4567Sbill continue; 4844c0d4567Sbill if (advance(p1, p2)) { 4854c0d4567Sbill loc1 = p1; 4864c0d4567Sbill return(1); 4874c0d4567Sbill } 4884c0d4567Sbill } while (*p1++); 4894c0d4567Sbill return(0); 4904c0d4567Sbill } 4914c0d4567Sbill /* regular algorithm */ 4924c0d4567Sbill do { 4934c0d4567Sbill if (advance(p1, p2)) { 4944c0d4567Sbill loc1 = p1; 4954c0d4567Sbill return(1); 4964c0d4567Sbill } 4974c0d4567Sbill } while (*p1++); 4984c0d4567Sbill return(0); 4994c0d4567Sbill } 5004c0d4567Sbill 5014c0d4567Sbill advance(lp, ep) 5024c0d4567Sbill register char *lp, *ep; 5034c0d4567Sbill { 5044c0d4567Sbill register char *curlp; 5054c0d4567Sbill char c; 5064c0d4567Sbill char *bbeg; 5074c0d4567Sbill int ct; 5084c0d4567Sbill 5094c0d4567Sbill for (;;) switch (*ep++) { 5104c0d4567Sbill 5114c0d4567Sbill case CCHR: 5124c0d4567Sbill if (*ep++ == *lp++) 5134c0d4567Sbill continue; 5144c0d4567Sbill return(0); 5154c0d4567Sbill 5164c0d4567Sbill case CDOT: 5174c0d4567Sbill if (*lp++) 5184c0d4567Sbill continue; 5194c0d4567Sbill return(0); 5204c0d4567Sbill 5214c0d4567Sbill case CDOL: 5224c0d4567Sbill if (*lp==0) 5234c0d4567Sbill continue; 5244c0d4567Sbill return(0); 5254c0d4567Sbill 5264c0d4567Sbill case CEOF: 5274c0d4567Sbill loc2 = lp; 5284c0d4567Sbill return(1); 5294c0d4567Sbill 5304c0d4567Sbill case CCL: 5314c0d4567Sbill c = *lp++ & 0177; 5324c0d4567Sbill if(ISTHERE(c)) { 5334c0d4567Sbill ep += 16; 5344c0d4567Sbill continue; 5354c0d4567Sbill } 5364c0d4567Sbill return(0); 5374c0d4567Sbill case CBRA: 5384c0d4567Sbill braslist[*ep++] = lp; 5394c0d4567Sbill continue; 5404c0d4567Sbill 5414c0d4567Sbill case CKET: 5424c0d4567Sbill braelist[*ep++] = lp; 5434c0d4567Sbill continue; 5444c0d4567Sbill 5454c0d4567Sbill case CCHR|RNGE: 5464c0d4567Sbill c = *ep++; 5474c0d4567Sbill getrnge(ep); 5484c0d4567Sbill while(low--) 5494c0d4567Sbill if(*lp++ != c) 5504c0d4567Sbill return(0); 5514c0d4567Sbill curlp = lp; 5524c0d4567Sbill while(size--) 5534c0d4567Sbill if(*lp++ != c) 5544c0d4567Sbill break; 5554c0d4567Sbill if(size < 0) 5564c0d4567Sbill lp++; 5574c0d4567Sbill ep += 2; 5584c0d4567Sbill goto star; 5594c0d4567Sbill 5604c0d4567Sbill case CDOT|RNGE: 5614c0d4567Sbill getrnge(ep); 5624c0d4567Sbill while(low--) 5634c0d4567Sbill if(*lp++ == '\0') 5644c0d4567Sbill return(0); 5654c0d4567Sbill curlp = lp; 5664c0d4567Sbill while(size--) 5674c0d4567Sbill if(*lp++ == '\0') 5684c0d4567Sbill break; 5694c0d4567Sbill if(size < 0) 5704c0d4567Sbill lp++; 5714c0d4567Sbill ep += 2; 5724c0d4567Sbill goto star; 5734c0d4567Sbill 5744c0d4567Sbill case CCL|RNGE: 5754c0d4567Sbill getrnge(ep + 16); 5764c0d4567Sbill while(low--) { 5774c0d4567Sbill c = *lp++ & 0177; 5784c0d4567Sbill if(!ISTHERE(c)) 5794c0d4567Sbill return(0); 5804c0d4567Sbill } 5814c0d4567Sbill curlp = lp; 5824c0d4567Sbill while(size--) { 5834c0d4567Sbill c = *lp++ & 0177; 5844c0d4567Sbill if(!ISTHERE(c)) 5854c0d4567Sbill break; 5864c0d4567Sbill } 5874c0d4567Sbill if(size < 0) 5884c0d4567Sbill lp++; 5894c0d4567Sbill ep += 18; /* 16 + 2 */ 5904c0d4567Sbill goto star; 5914c0d4567Sbill 5924c0d4567Sbill case CBACK: 5934c0d4567Sbill bbeg = braslist[*ep]; 5944c0d4567Sbill ct = braelist[*ep++] - bbeg; 5954c0d4567Sbill 5964c0d4567Sbill if(ecmp(bbeg, lp, ct)) { 5974c0d4567Sbill lp += ct; 5984c0d4567Sbill continue; 5994c0d4567Sbill } 6004c0d4567Sbill return(0); 6014c0d4567Sbill 6024c0d4567Sbill case CBACK|STAR: 6034c0d4567Sbill bbeg = braslist[*ep]; 6044c0d4567Sbill ct = braelist[*ep++] - bbeg; 6054c0d4567Sbill curlp = lp; 6064c0d4567Sbill while(ecmp(bbeg, lp, ct)) 6074c0d4567Sbill lp += ct; 6084c0d4567Sbill 6094c0d4567Sbill while(lp >= curlp) { 6104c0d4567Sbill if(advance(lp, ep)) return(1); 6114c0d4567Sbill lp -= ct; 6124c0d4567Sbill } 6134c0d4567Sbill return(0); 6144c0d4567Sbill 6154c0d4567Sbill 6164c0d4567Sbill case CDOT|STAR: 6174c0d4567Sbill curlp = lp; 6184c0d4567Sbill while (*lp++); 6194c0d4567Sbill goto star; 6204c0d4567Sbill 6214c0d4567Sbill case CCHR|STAR: 6224c0d4567Sbill curlp = lp; 6234c0d4567Sbill while (*lp++ == *ep); 6244c0d4567Sbill ep++; 6254c0d4567Sbill goto star; 6264c0d4567Sbill 6274c0d4567Sbill case CCL|STAR: 6284c0d4567Sbill curlp = lp; 6294c0d4567Sbill do { 6304c0d4567Sbill c = *lp++ & 0177; 6314c0d4567Sbill } while(ISTHERE(c)); 6324c0d4567Sbill ep += 16; 6334c0d4567Sbill goto star; 6344c0d4567Sbill 6354c0d4567Sbill star: 6364c0d4567Sbill do { 6374c0d4567Sbill if(--lp == locs) 6384c0d4567Sbill break; 6394c0d4567Sbill if (advance(lp, ep)) 6404c0d4567Sbill return(1); 6414c0d4567Sbill } while (lp > curlp); 6424c0d4567Sbill return(0); 6434c0d4567Sbill 6444c0d4567Sbill } 6454c0d4567Sbill } 6464c0d4567Sbill 6474c0d4567Sbill getrnge(str) 6484c0d4567Sbill register char *str; 6494c0d4567Sbill { 6504c0d4567Sbill low = *str++ & 0377; 651*d0e3910bSbostic size = (*str & 0377) == 255 ? 20000 : (*str & 0377) - low; 6524c0d4567Sbill } 6534c0d4567Sbill 6544c0d4567Sbill ecmp(a, b, count) 6554c0d4567Sbill register char *a, *b; 6564c0d4567Sbill register count; 6574c0d4567Sbill { 6584c0d4567Sbill if(a == b) /* should have been caught in compile() */ 6594c0d4567Sbill error(51); 6604c0d4567Sbill while(count--) 6614c0d4567Sbill if(*a++ != *b++) return(0); 6624c0d4567Sbill return(1); 6634c0d4567Sbill } 6644c0d4567Sbill 665*d0e3910bSbostic static char *sccsid = "@(#)expr.y 4.7 (Berkeley) 04/24/88"; 6664c0d4567Sbill yyerror(s) 6674c0d4567Sbill 6684c0d4567Sbill { 6694c0d4567Sbill fprintf(stderr, "%s\n", s); 6704c0d4567Sbill exit(2); 6714c0d4567Sbill } 672