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