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 int yyparse(void); 73 74 main(argc, argv) char **argv; { 75 Ac = argc; 76 Argi = 1; 77 Av = argv; 78 yyparse(); 79 } 80 81 char *operator[] = { "|", "&", "+", "-", "*", "/", "%", ":", 82 "=", "==", "<", "<=", ">", ">=", "!=", 83 "match", "substr", "length", "index", "\0" }; 84 int op[] = { OR, AND, ADD, SUBT, MULT, DIV, REM, MCH, 85 EQ, EQ, LT, LEQ, GT, GEQ, NEQ, 86 MATCH, SUBSTR, LENGTH, INDEX }; 87 yylex() { 88 register char *p; 89 register i; 90 91 if(Argi >= Ac) return NOARG; 92 93 p = Av[Argi++]; 94 95 if(*p == '(' || *p == ')') 96 return (int)*p; 97 for(i = 0; *operator[i]; ++i) 98 if(EQL(operator[i], p)) 99 return op[i]; 100 101 yylval = p; 102 return A_STRING; 103 } 104 105 char *rel(op, r1, r2) register char *r1, *r2; { 106 register i; 107 108 if(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$")) 109 i = atol(r1) - atol(r2); 110 else 111 i = strcmp(r1, r2); 112 switch(op) { 113 case EQ: i = i==0; break; 114 case GT: i = i>0; break; 115 case GEQ: i = i>=0; break; 116 case LT: i = i<0; break; 117 case LEQ: i = i<=0; break; 118 case NEQ: i = i!=0; break; 119 } 120 return i? "1": "0"; 121 } 122 123 char *arith(op, r1, r2) char *r1, *r2; { 124 long i1, i2; 125 register char *rv; 126 127 if(!(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$"))) 128 yyerror("non-numeric argument"); 129 i1 = atol(r1); 130 i2 = atol(r2); 131 132 switch(op) { 133 case ADD: i1 = i1 + i2; break; 134 case SUBT: i1 = i1 - i2; break; 135 case MULT: i1 = i1 * i2; break; 136 case DIV: i1 = i1 / i2; break; 137 case REM: i1 = i1 % i2; break; 138 } 139 rv = malloc(16); 140 strcpy(rv, ltoa(i1)); 141 return rv; 142 } 143 char *conj(op, r1, r2) char *r1, *r2; { 144 register char *rv; 145 146 switch(op) { 147 148 case OR: 149 if(EQL(r1, "0") 150 || EQL(r1, "")) 151 if(EQL(r2, "0") 152 || EQL(r2, "")) 153 rv = "0"; 154 else 155 rv = r2; 156 else 157 rv = r1; 158 break; 159 case AND: 160 if(EQL(r1, "0") 161 || EQL(r1, "")) 162 rv = "0"; 163 else if(EQL(r2, "0") 164 || EQL(r2, "")) 165 rv = "0"; 166 else 167 rv = r1; 168 break; 169 } 170 return rv; 171 } 172 173 char *substr(v, s, w) char *v, *s, *w; { 174 register si, wi; 175 register char *res; 176 177 si = atol(s); 178 wi = atol(w); 179 while(--si) if(*v) ++v; 180 181 res = v; 182 183 while(wi--) if(*v) ++v; 184 185 *v = '\0'; 186 return res; 187 } 188 189 char *length(s) register char *s; { 190 register i = 0; 191 register char *rv; 192 193 while(*s++) ++i; 194 195 rv = malloc(8); 196 strcpy(rv, ltoa((long)i)); 197 return rv; 198 } 199 200 char *index(s, t) char *s, *t; { 201 register i, j; 202 register char *rv; 203 204 for(i = 0; s[i] ; ++i) 205 for(j = 0; t[j] ; ++j) 206 if(s[i]==t[j]) { 207 strcpy(rv=malloc(8), ltoa((long)++i)); 208 return rv; 209 } 210 return "0"; 211 } 212 213 char *match(s, p) 214 { 215 register char *rv; 216 217 strcpy(rv=malloc(8), ltoa((long)ematch(s, p))); 218 if(nbra) { 219 rv = malloc(strlen(Mstring[0])+1); 220 strcpy(rv, Mstring[0]); 221 } 222 return rv; 223 } 224 225 #define INIT register char *sp = instring; 226 #define GETC() (*sp++) 227 #define PEEKC() (*sp) 228 #define UNGETC(c) (--sp) 229 #define RETURN(c) return 230 #define ERROR(c) errxx(c) 231 232 233 ematch(s, p) 234 char *s; 235 register char *p; 236 { 237 static char expbuf[ESIZE]; 238 char *compile(); 239 register num; 240 extern char *braslist[], *braelist[], *loc2; 241 242 compile(p, expbuf, &expbuf[ESIZE], 0); 243 if(nbra > 1) 244 yyerror("Too many '\\('s"); 245 if(advance(s, expbuf)) { 246 if(nbra == 1) { 247 p = braslist[0]; 248 num = braelist[0] - p; 249 strncpy(Mstring[0], p, num); 250 Mstring[0][num] = '\0'; 251 } 252 return(loc2-s); 253 } 254 return(0); 255 } 256 257 errxx(c) 258 { 259 yyerror("RE error"); 260 } 261 262 #include "regexp.h" 263 yyerror(s) 264 265 { 266 write(2, "expr: ", 6); 267 prt(2, s); 268 exit(2); 269 } 270 prt(fd, s) 271 char *s; 272 { 273 write(fd, s, strlen(s)); 274 write(fd, "\n", 1); 275 } 276 char *ltoa(l) 277 long l; 278 { 279 static char str[20]; 280 register char *sp = &str[18]; 281 register i; 282 register neg = 0; 283 284 if(l < 0) 285 ++neg, l *= -1; 286 str[19] = '\0'; 287 do { 288 i = l % 10; 289 *sp-- = '0' + i; 290 l /= 10; 291 } while(l); 292 if(neg) 293 *sp-- = '-'; 294 return ++sp; 295 } 296