|
|
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.