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