|
|
1.1 ! root 1: /* Yacc productions for "expr" command: */ ! 2: ! 3: %token OR AND ADD SUBT MULT DIV REM EQ GT GEQ LT LEQ NEQ ! 4: %token A_STRING SUBSTR LENGTH INDEX NOARG MATCH ! 5: ! 6: /* operators listed below in increasing precedence: */ ! 7: %left OR ! 8: %left AND ! 9: %left EQ LT GT GEQ LEQ NEQ ! 10: %left ADD SUBT ! 11: %left MULT DIV REM ! 12: %left MCH ! 13: %left MATCH ! 14: %left SUBSTR ! 15: %left LENGTH INDEX ! 16: ! 17: %{ ! 18: #define YYSTYPE charp ! 19: ! 20: typedef char *charp; ! 21: %} ! 22: ! 23: %% ! 24: ! 25: /* a single `expression' is evaluated and printed: */ ! 26: ! 27: expression: expr NOARG = { ! 28: prt(1, $1); ! 29: exit((!strcmp($1,"0")||!strcmp($1,"\0"))? 1: 0); ! 30: } ! 31: ; ! 32: ! 33: ! 34: expr: '(' expr ')' = { $$ = $2; } ! 35: | expr OR expr = { $$ = conj(OR, $1, $3); } ! 36: | expr AND expr = { $$ = conj(AND, $1, $3); } ! 37: | expr EQ expr = { $$ = rel(EQ, $1, $3); } ! 38: | expr GT expr = { $$ = rel(GT, $1, $3); } ! 39: | expr GEQ expr = { $$ = rel(GEQ, $1, $3); } ! 40: | expr LT expr = { $$ = rel(LT, $1, $3); } ! 41: | expr LEQ expr = { $$ = rel(LEQ, $1, $3); } ! 42: | expr NEQ expr = { $$ = rel(NEQ, $1, $3); } ! 43: | expr ADD expr = { $$ = arith(ADD, $1, $3); } ! 44: | expr SUBT expr = { $$ = arith(SUBT, $1, $3); } ! 45: | expr MULT expr = { $$ = arith(MULT, $1, $3); } ! 46: | expr DIV expr = { $$ = arith(DIV, $1, $3); } ! 47: | expr REM expr = { $$ = arith(REM, $1, $3); } ! 48: | expr MCH expr = { $$ = match($1, $3); } ! 49: | MATCH expr expr = { $$ = match($2, $3); } ! 50: | SUBSTR expr expr expr = { $$ = substr($2, $3, $4); } ! 51: | LENGTH expr = { $$ = length($2); } ! 52: | INDEX expr expr = { $$ = index($2, $3); } ! 53: | A_STRING ! 54: ; ! 55: %% ! 56: /* expression command */ ! 57: #include <stdio.h> ! 58: /* get rid of yacc debug printf's */ ! 59: #define printf ! 60: #define ESIZE 512 ! 61: #define error(c) errxx(c) ! 62: #define EQL(x,y) !strcmp(x,y) ! 63: long atol(); ! 64: char *ltoa(); ! 65: char **Av; ! 66: int Ac; ! 67: int Argi; ! 68: ! 69: char Mstring[1][128]; ! 70: char *malloc(); ! 71: extern int nbra; ! 72: ! 73: main(argc, argv) char **argv; { ! 74: Ac = argc; ! 75: Argi = 1; ! 76: Av = argv; ! 77: yyparse(); ! 78: } ! 79: ! 80: char *operator[] = { "|", "&", "+", "-", "*", "/", "%", ":", ! 81: "=", "==", "<", "<=", ">", ">=", "!=", ! 82: "match", "substr", "length", "index", "\0" }; ! 83: int op[] = { OR, AND, ADD, SUBT, MULT, DIV, REM, MCH, ! 84: EQ, EQ, LT, LEQ, GT, GEQ, NEQ, ! 85: MATCH, SUBSTR, LENGTH, INDEX }; ! 86: yylex() { ! 87: register char *p; ! 88: register i; ! 89: ! 90: if(Argi >= Ac) return NOARG; ! 91: ! 92: p = Av[Argi++]; ! 93: ! 94: if(*p == '(' || *p == ')') ! 95: return (int)*p; ! 96: for(i = 0; *operator[i]; ++i) ! 97: if(EQL(operator[i], p)) ! 98: return op[i]; ! 99: ! 100: yylval = p; ! 101: return A_STRING; ! 102: } ! 103: ! 104: char *rel(op, r1, r2) register char *r1, *r2; { ! 105: register i; ! 106: ! 107: if(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$")) ! 108: i = atol(r1) - atol(r2); ! 109: else ! 110: i = strcmp(r1, r2); ! 111: switch(op) { ! 112: case EQ: i = i==0; break; ! 113: case GT: i = i>0; break; ! 114: case GEQ: i = i>=0; break; ! 115: case LT: i = i<0; break; ! 116: case LEQ: i = i<=0; break; ! 117: case NEQ: i = i!=0; break; ! 118: } ! 119: return i? "1": "0"; ! 120: } ! 121: ! 122: char *arith(op, r1, r2) char *r1, *r2; { ! 123: long i1, i2; ! 124: register char *rv; ! 125: ! 126: if(!(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$"))) ! 127: yyerror("non-numeric argument"); ! 128: i1 = atol(r1); ! 129: i2 = atol(r2); ! 130: ! 131: switch(op) { ! 132: case ADD: i1 = i1 + i2; break; ! 133: case SUBT: i1 = i1 - i2; break; ! 134: case MULT: i1 = i1 * i2; break; ! 135: case DIV: i1 = i1 / i2; break; ! 136: case REM: i1 = i1 % i2; break; ! 137: } ! 138: rv = malloc(16); ! 139: strcpy(rv, ltoa(i1)); ! 140: return rv; ! 141: } ! 142: char *conj(op, r1, r2) char *r1, *r2; { ! 143: register char *rv; ! 144: ! 145: switch(op) { ! 146: ! 147: case OR: ! 148: if(EQL(r1, "0") ! 149: || EQL(r1, "")) ! 150: if(EQL(r2, "0") ! 151: || EQL(r2, "")) ! 152: rv = "0"; ! 153: else ! 154: rv = r2; ! 155: else ! 156: rv = r1; ! 157: break; ! 158: case AND: ! 159: if(EQL(r1, "0") ! 160: || EQL(r1, "")) ! 161: rv = "0"; ! 162: else if(EQL(r2, "0") ! 163: || EQL(r2, "")) ! 164: rv = "0"; ! 165: else ! 166: rv = r1; ! 167: break; ! 168: } ! 169: return rv; ! 170: } ! 171: ! 172: char *substr(v, s, w) char *v, *s, *w; { ! 173: register si, wi; ! 174: register char *res; ! 175: ! 176: si = atol(s); ! 177: wi = atol(w); ! 178: while(--si) if(*v) ++v; ! 179: ! 180: res = v; ! 181: ! 182: while(wi--) if(*v) ++v; ! 183: ! 184: *v = '\0'; ! 185: return res; ! 186: } ! 187: ! 188: char *length(s) register char *s; { ! 189: register i = 0; ! 190: register char *rv; ! 191: ! 192: while(*s++) ++i; ! 193: ! 194: rv = malloc(8); ! 195: strcpy(rv, ltoa((long)i)); ! 196: return rv; ! 197: } ! 198: ! 199: char *index(s, t) char *s, *t; { ! 200: register i, j; ! 201: register char *rv; ! 202: ! 203: for(i = 0; s[i] ; ++i) ! 204: for(j = 0; t[j] ; ++j) ! 205: if(s[i]==t[j]) { ! 206: strcpy(rv=malloc(8), ltoa((long)++i)); ! 207: return rv; ! 208: } ! 209: return "0"; ! 210: } ! 211: ! 212: char *match(s, p) ! 213: { ! 214: register char *rv; ! 215: ! 216: strcpy(rv=malloc(8), ltoa((long)ematch(s, p))); ! 217: if(nbra) { ! 218: rv = malloc(strlen(Mstring[0])+1); ! 219: strcpy(rv, Mstring[0]); ! 220: } ! 221: return rv; ! 222: } ! 223: ! 224: #define INIT register char *sp = instring; ! 225: #define GETC() (*sp++) ! 226: #define PEEKC() (*sp) ! 227: #define UNGETC(c) (--sp) ! 228: #define RETURN(c) return ! 229: #define ERROR(c) errxx(c) ! 230: ! 231: ! 232: ematch(s, p) ! 233: char *s; ! 234: register char *p; ! 235: { ! 236: static char expbuf[ESIZE]; ! 237: char *compile(); ! 238: register num; ! 239: extern char *braslist[], *braelist[], *loc2; ! 240: ! 241: compile(p, expbuf, &expbuf[ESIZE], 0); ! 242: if(nbra > 1) ! 243: yyerror("Too many '\\('s"); ! 244: if(advance(s, expbuf)) { ! 245: if(nbra == 1) { ! 246: p = braslist[0]; ! 247: num = braelist[0] - p; ! 248: strncpy(Mstring[0], p, num); ! 249: Mstring[0][num] = '\0'; ! 250: } ! 251: return(loc2-s); ! 252: } ! 253: return(0); ! 254: } ! 255: ! 256: errxx(c) ! 257: { ! 258: yyerror("RE error"); ! 259: } ! 260: ! 261: #include "regexp.h" ! 262: yyerror(s) ! 263: ! 264: { ! 265: write(2, "expr: ", 6); ! 266: prt(2, s); ! 267: exit(2); ! 268: } ! 269: prt(fd, s) ! 270: char *s; ! 271: { ! 272: write(fd, s, strlen(s)); ! 273: write(fd, "\n", 1); ! 274: } ! 275: char *ltoa(l) ! 276: long l; ! 277: { ! 278: static char str[20]; ! 279: register char *sp = &str[18]; ! 280: register i; ! 281: register neg = 0; ! 282: ! 283: if(l < 0) ! 284: ++neg, l *= -1; ! 285: str[19] = '\0'; ! 286: do { ! 287: i = l % 10; ! 288: *sp-- = '0' + i; ! 289: l /= 10; ! 290: } while(l); ! 291: if(neg) ! 292: *sp-- = '-'; ! 293: return ++sp; ! 294: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.