expr.y revision 1.11 1 1.1 cgd %{
2 1.1 cgd /* Written by Pace Willisson (pace (at) blitz.com)
3 1.11 jtc * and placed in the public domain.
4 1.2 cgd *
5 1.11 jtc * Largely rewritten by J.T. Conklin (jtc (at) wimsey.com)
6 1.11 jtc *
7 1.11 jtc * $Header: /tank/opengrok/rsync2/NetBSD/src/bin/expr/expr.y,v 1.11 1993/08/17 16:01:23 jtc Exp $
8 1.1 cgd */
9 1.1 cgd #include <stdio.h>
10 1.4 cgd #include <stdlib.h>
11 1.4 cgd #include <string.h>
12 1.1 cgd #include <ctype.h>
13 1.11 jtc #include <err.h>
14 1.5 cgd
15 1.4 cgd enum valtype {
16 1.4 cgd integer, string
17 1.4 cgd } ;
18 1.5 cgd
19 1.1 cgd struct val {
20 1.4 cgd enum valtype type;
21 1.4 cgd union {
22 1.4 cgd char *s;
23 1.4 cgd int i;
24 1.4 cgd } u;
25 1.5 cgd } ;
26 1.1 cgd
27 1.1 cgd struct val *result;
28 1.1 cgd struct val *op_or ();
29 1.1 cgd struct val *op_and ();
30 1.1 cgd struct val *op_eq ();
31 1.1 cgd struct val *op_gt ();
32 1.1 cgd struct val *op_lt ();
33 1.1 cgd struct val *op_ge ();
34 1.1 cgd struct val *op_le ();
35 1.1 cgd struct val *op_ne ();
36 1.1 cgd struct val *op_plus ();
37 1.1 cgd struct val *op_minus ();
38 1.1 cgd struct val *op_times ();
39 1.1 cgd struct val *op_div ();
40 1.1 cgd struct val *op_rem ();
41 1.1 cgd struct val *op_colon ();
42 1.1 cgd
43 1.1 cgd char **av;
44 1.1 cgd %}
45 1.1 cgd
46 1.1 cgd %union
47 1.1 cgd {
48 1.1 cgd struct val *val;
49 1.1 cgd }
50 1.1 cgd
51 1.1 cgd %left <val> '|'
52 1.1 cgd %left <val> '&'
53 1.1 cgd %left <val> '=' '>' '<' GE LE NE
54 1.1 cgd %left <val> '+' '-'
55 1.1 cgd %left <val> '*' '/' '%'
56 1.1 cgd %left <val> ':'
57 1.1 cgd %left UNARY
58 1.1 cgd
59 1.1 cgd %token <val> TOKEN
60 1.1 cgd %type <val> start expr
61 1.1 cgd
62 1.1 cgd %%
63 1.1 cgd
64 1.1 cgd start: expr { result = $$; }
65 1.1 cgd
66 1.1 cgd expr: TOKEN
67 1.1 cgd | '(' expr ')' { $$ = $2; }
68 1.1 cgd | expr '|' expr { $$ = op_or ($1, $3); }
69 1.1 cgd | expr '&' expr { $$ = op_and ($1, $3); }
70 1.1 cgd | expr '=' expr { $$ = op_eq ($1, $3); }
71 1.1 cgd | expr '>' expr { $$ = op_gt ($1, $3); }
72 1.1 cgd | expr '<' expr { $$ = op_lt ($1, $3); }
73 1.1 cgd | expr GE expr { $$ = op_ge ($1, $3); }
74 1.1 cgd | expr LE expr { $$ = op_le ($1, $3); }
75 1.1 cgd | expr NE expr { $$ = op_ne ($1, $3); }
76 1.1 cgd | expr '+' expr { $$ = op_plus ($1, $3); }
77 1.1 cgd | expr '-' expr { $$ = op_minus ($1, $3); }
78 1.1 cgd | expr '*' expr { $$ = op_times ($1, $3); }
79 1.1 cgd | expr '/' expr { $$ = op_div ($1, $3); }
80 1.1 cgd | expr '%' expr { $$ = op_rem ($1, $3); }
81 1.1 cgd | expr ':' expr { $$ = op_colon ($1, $3); }
82 1.1 cgd | '-' expr %prec UNARY { $$ = op_minus (NULL, $2); }
83 1.1 cgd ;
84 1.1 cgd
85 1.1 cgd
86 1.1 cgd %%
87 1.1 cgd
88 1.1 cgd struct val *
89 1.4 cgd make_integer (i)
90 1.4 cgd int i;
91 1.4 cgd {
92 1.4 cgd struct val *vp;
93 1.4 cgd
94 1.5 cgd vp = (struct val *) malloc (sizeof (*vp));
95 1.4 cgd if (vp == NULL) {
96 1.11 jtc err (2, NULL);
97 1.4 cgd }
98 1.4 cgd
99 1.4 cgd vp->type = integer;
100 1.4 cgd vp->u.i = i;
101 1.4 cgd return vp;
102 1.4 cgd }
103 1.4 cgd
104 1.4 cgd struct val *
105 1.4 cgd make_str (s)
106 1.4 cgd char *s;
107 1.1 cgd {
108 1.1 cgd struct val *vp;
109 1.1 cgd
110 1.5 cgd vp = (struct val *) malloc (sizeof (*vp));
111 1.4 cgd if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
112 1.11 jtc err (2, NULL);
113 1.1 cgd }
114 1.1 cgd
115 1.4 cgd vp->type = string;
116 1.4 cgd return vp;
117 1.4 cgd }
118 1.4 cgd
119 1.4 cgd
120 1.4 cgd void
121 1.4 cgd free_value (vp)
122 1.4 cgd struct val *vp;
123 1.4 cgd {
124 1.4 cgd if (vp->type == string)
125 1.4 cgd free (vp->u.s);
126 1.4 cgd }
127 1.4 cgd
128 1.1 cgd
129 1.4 cgd int
130 1.4 cgd to_integer (vp)
131 1.4 cgd struct val *vp;
132 1.4 cgd {
133 1.4 cgd char *s;
134 1.4 cgd int neg;
135 1.4 cgd int i;
136 1.4 cgd
137 1.4 cgd if (vp->type == integer)
138 1.4 cgd return 1;
139 1.4 cgd
140 1.4 cgd s = vp->u.s;
141 1.4 cgd i = 0;
142 1.4 cgd
143 1.4 cgd neg = (*s == '-');
144 1.4 cgd if (neg)
145 1.4 cgd s++;
146 1.4 cgd
147 1.4 cgd for (;*s; s++) {
148 1.4 cgd if (!isdigit (*s))
149 1.4 cgd return 0;
150 1.4 cgd
151 1.4 cgd i *= 10;
152 1.4 cgd i += *s - '0';
153 1.1 cgd }
154 1.1 cgd
155 1.4 cgd free (vp->u.s);
156 1.4 cgd if (neg)
157 1.4 cgd i *= -1;
158 1.4 cgd
159 1.4 cgd vp->type = integer;
160 1.4 cgd vp->u.i = i;
161 1.4 cgd return 1;
162 1.1 cgd }
163 1.1 cgd
164 1.4 cgd void
165 1.4 cgd to_string (vp)
166 1.4 cgd struct val *vp;
167 1.1 cgd {
168 1.4 cgd char *tmp;
169 1.4 cgd
170 1.4 cgd if (vp->type == string)
171 1.4 cgd return;
172 1.4 cgd
173 1.4 cgd tmp = malloc (25);
174 1.4 cgd if (tmp == NULL) {
175 1.11 jtc err (2, NULL);
176 1.4 cgd }
177 1.4 cgd
178 1.4 cgd sprintf (tmp, "%d", vp->u.i);
179 1.4 cgd vp->type = string;
180 1.4 cgd vp->u.s = tmp;
181 1.4 cgd }
182 1.4 cgd
183 1.1 cgd
184 1.4 cgd int
185 1.4 cgd isstring (vp)
186 1.4 cgd struct val *vp;
187 1.4 cgd {
188 1.4 cgd return (vp->type == string);
189 1.1 cgd }
190 1.1 cgd
191 1.4 cgd
192 1.1 cgd int
193 1.1 cgd yylex ()
194 1.1 cgd {
195 1.1 cgd struct val *vp;
196 1.1 cgd char *p;
197 1.1 cgd
198 1.1 cgd if (*av == NULL)
199 1.1 cgd return (0);
200 1.1 cgd
201 1.1 cgd p = *av++;
202 1.1 cgd
203 1.1 cgd if (strlen (p) == 1) {
204 1.4 cgd if (strchr ("|&=<>+-*/%:()", *p))
205 1.1 cgd return (*p);
206 1.1 cgd } else if (strlen (p) == 2 && p[1] == '=') {
207 1.1 cgd switch (*p) {
208 1.1 cgd case '>': return (GE);
209 1.1 cgd case '<': return (LE);
210 1.1 cgd case '!': return (NE);
211 1.1 cgd }
212 1.1 cgd }
213 1.1 cgd
214 1.4 cgd yylval.val = make_str (p);
215 1.1 cgd return (TOKEN);
216 1.1 cgd }
217 1.1 cgd
218 1.1 cgd int
219 1.1 cgd is_zero_or_null (vp)
220 1.1 cgd struct val *vp;
221 1.1 cgd {
222 1.4 cgd if (vp->type == integer) {
223 1.5 cgd return (vp->u.i == 0);
224 1.4 cgd } else {
225 1.9 jtc return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
226 1.4 cgd }
227 1.5 cgd /* NOTREACHED */
228 1.1 cgd }
229 1.1 cgd
230 1.1 cgd void
231 1.1 cgd main (argc, argv)
232 1.1 cgd int argc;
233 1.1 cgd char **argv;
234 1.1 cgd {
235 1.1 cgd av = argv + 1;
236 1.1 cgd
237 1.1 cgd yyparse ();
238 1.1 cgd
239 1.4 cgd if (result->type == integer)
240 1.4 cgd printf ("%d\n", result->u.i);
241 1.1 cgd else
242 1.4 cgd printf ("%s\n", result->u.s);
243 1.1 cgd
244 1.1 cgd if (is_zero_or_null (result))
245 1.1 cgd exit (1);
246 1.1 cgd else
247 1.1 cgd exit (0);
248 1.1 cgd }
249 1.1 cgd
250 1.1 cgd int
251 1.1 cgd yyerror (s)
252 1.1 cgd char *s;
253 1.1 cgd {
254 1.11 jtc errx (2, "syntax error");
255 1.1 cgd }
256 1.1 cgd
257 1.1 cgd
258 1.1 cgd struct val *
259 1.1 cgd op_or (a, b)
260 1.1 cgd struct val *a, *b;
261 1.1 cgd {
262 1.4 cgd if (is_zero_or_null (a)) {
263 1.4 cgd free_value (a);
264 1.1 cgd return (b);
265 1.4 cgd } else {
266 1.4 cgd free_value (b);
267 1.1 cgd return (a);
268 1.4 cgd }
269 1.1 cgd }
270 1.1 cgd
271 1.1 cgd struct val *
272 1.1 cgd op_and (a, b)
273 1.1 cgd struct val *a, *b;
274 1.1 cgd {
275 1.4 cgd if (is_zero_or_null (a) || is_zero_or_null (b)) {
276 1.4 cgd free_value (a);
277 1.4 cgd free_value (b);
278 1.1 cgd return (make_integer (0));
279 1.4 cgd } else {
280 1.4 cgd free_value (b);
281 1.1 cgd return (a);
282 1.4 cgd }
283 1.1 cgd }
284 1.1 cgd
285 1.1 cgd struct val *
286 1.1 cgd op_eq (a, b)
287 1.1 cgd struct val *a, *b;
288 1.1 cgd {
289 1.4 cgd struct val *r;
290 1.4 cgd
291 1.4 cgd if (isstring (a) || isstring (b)) {
292 1.4 cgd to_string (a);
293 1.4 cgd to_string (b);
294 1.10 jtc r = make_integer (strcoll (a->u.s, b->u.s) == 0);
295 1.4 cgd } else {
296 1.4 cgd r = make_integer (a->u.i == b->u.i);
297 1.4 cgd }
298 1.4 cgd
299 1.4 cgd free_value (a);
300 1.4 cgd free_value (b);
301 1.4 cgd return r;
302 1.1 cgd }
303 1.1 cgd
304 1.1 cgd struct val *
305 1.1 cgd op_gt (a, b)
306 1.1 cgd struct val *a, *b;
307 1.1 cgd {
308 1.4 cgd struct val *r;
309 1.4 cgd
310 1.4 cgd if (isstring (a) || isstring (b)) {
311 1.4 cgd to_string (a);
312 1.4 cgd to_string (b);
313 1.10 jtc r = make_integer (strcoll (a->u.s, b->u.s) > 0);
314 1.4 cgd } else {
315 1.4 cgd r= make_integer (a->u.i > b->u.i);
316 1.4 cgd }
317 1.4 cgd
318 1.4 cgd free_value (a);
319 1.4 cgd free_value (b);
320 1.4 cgd return r;
321 1.1 cgd }
322 1.1 cgd
323 1.1 cgd struct val *
324 1.1 cgd op_lt (a, b)
325 1.1 cgd struct val *a, *b;
326 1.1 cgd {
327 1.4 cgd struct val *r;
328 1.4 cgd
329 1.4 cgd if (isstring (a) || isstring (b)) {
330 1.4 cgd to_string (a);
331 1.4 cgd to_string (b);
332 1.10 jtc r = make_integer (strcoll (a->u.s, b->u.s) < 0);
333 1.4 cgd } else {
334 1.4 cgd r = make_integer (a->u.i < b->u.i);
335 1.4 cgd }
336 1.4 cgd
337 1.4 cgd free_value (a);
338 1.4 cgd free_value (b);
339 1.4 cgd return r;
340 1.1 cgd }
341 1.1 cgd
342 1.1 cgd struct val *
343 1.1 cgd op_ge (a, b)
344 1.1 cgd struct val *a, *b;
345 1.1 cgd {
346 1.4 cgd struct val *r;
347 1.4 cgd
348 1.4 cgd if (isstring (a) || isstring (b)) {
349 1.4 cgd to_string (a);
350 1.4 cgd to_string (b);
351 1.10 jtc r = make_integer (strcoll (a->u.s, b->u.s) >= 0);
352 1.4 cgd } else {
353 1.4 cgd r = make_integer (a->u.i >= b->u.i);
354 1.4 cgd }
355 1.4 cgd
356 1.4 cgd free_value (a);
357 1.4 cgd free_value (b);
358 1.4 cgd return r;
359 1.1 cgd }
360 1.1 cgd
361 1.1 cgd struct val *
362 1.1 cgd op_le (a, b)
363 1.1 cgd struct val *a, *b;
364 1.1 cgd {
365 1.4 cgd struct val *r;
366 1.4 cgd
367 1.4 cgd if (isstring (a) || isstring (b)) {
368 1.4 cgd to_string (a);
369 1.4 cgd to_string (b);
370 1.10 jtc r = make_integer (strcoll (a->u.s, b->u.s) <= 0);
371 1.4 cgd } else {
372 1.4 cgd r = make_integer (a->u.i <= b->u.i);
373 1.4 cgd }
374 1.4 cgd
375 1.4 cgd free_value (a);
376 1.4 cgd free_value (b);
377 1.4 cgd return r;
378 1.1 cgd }
379 1.1 cgd
380 1.1 cgd struct val *
381 1.1 cgd op_ne (a, b)
382 1.1 cgd struct val *a, *b;
383 1.1 cgd {
384 1.4 cgd struct val *r;
385 1.4 cgd
386 1.4 cgd if (isstring (a) || isstring (b)) {
387 1.4 cgd to_string (a);
388 1.4 cgd to_string (b);
389 1.10 jtc r = make_integer (strcoll (a->u.s, b->u.s) != 0);
390 1.4 cgd } else {
391 1.4 cgd r = make_integer (a->u.i != b->u.i);
392 1.4 cgd }
393 1.4 cgd
394 1.4 cgd free_value (a);
395 1.4 cgd free_value (b);
396 1.4 cgd return r;
397 1.1 cgd }
398 1.1 cgd
399 1.1 cgd struct val *
400 1.1 cgd op_plus (a, b)
401 1.1 cgd struct val *a, *b;
402 1.1 cgd {
403 1.4 cgd struct val *r;
404 1.4 cgd
405 1.4 cgd if (!to_integer (a) || !to_integer (b)) {
406 1.11 jtc errx (2, "non-numeric argument");
407 1.4 cgd }
408 1.1 cgd
409 1.4 cgd r = make_integer (a->u.i + b->u.i);
410 1.4 cgd free_value (a);
411 1.4 cgd free_value (b);
412 1.4 cgd return r;
413 1.1 cgd }
414 1.1 cgd
415 1.1 cgd struct val *
416 1.1 cgd op_minus (a, b)
417 1.1 cgd struct val *a, *b;
418 1.1 cgd {
419 1.4 cgd struct val *r;
420 1.4 cgd
421 1.4 cgd if (!to_integer (a) || !to_integer (b)) {
422 1.11 jtc errx (2, "non-numeric argument");
423 1.4 cgd }
424 1.1 cgd
425 1.4 cgd r = make_integer (a->u.i - b->u.i);
426 1.4 cgd free_value (a);
427 1.4 cgd free_value (b);
428 1.4 cgd return r;
429 1.1 cgd }
430 1.1 cgd
431 1.1 cgd struct val *
432 1.1 cgd op_times (a, b)
433 1.1 cgd struct val *a, *b;
434 1.1 cgd {
435 1.4 cgd struct val *r;
436 1.1 cgd
437 1.4 cgd if (!to_integer (a) || !to_integer (b)) {
438 1.11 jtc errx (2, "non-numeric argument");
439 1.4 cgd }
440 1.4 cgd
441 1.4 cgd r = make_integer (a->u.i * b->u.i);
442 1.4 cgd free_value (a);
443 1.4 cgd free_value (b);
444 1.4 cgd return (r);
445 1.1 cgd }
446 1.1 cgd
447 1.1 cgd struct val *
448 1.1 cgd op_div (a, b)
449 1.1 cgd struct val *a, *b;
450 1.1 cgd {
451 1.4 cgd struct val *r;
452 1.4 cgd
453 1.4 cgd if (!to_integer (a) || !to_integer (b)) {
454 1.11 jtc errx (2, "non-numeric argument");
455 1.4 cgd }
456 1.4 cgd
457 1.4 cgd if (b->u.i == 0) {
458 1.11 jtc errx (2, "division by zero");
459 1.4 cgd }
460 1.1 cgd
461 1.4 cgd r = make_integer (a->u.i / b->u.i);
462 1.4 cgd free_value (a);
463 1.4 cgd free_value (b);
464 1.4 cgd return r;
465 1.1 cgd }
466 1.1 cgd
467 1.1 cgd struct val *
468 1.1 cgd op_rem (a, b)
469 1.1 cgd struct val *a, *b;
470 1.1 cgd {
471 1.4 cgd struct val *r;
472 1.4 cgd
473 1.4 cgd if (!to_integer (a) || !to_integer (b)) {
474 1.11 jtc errx (2, "non-numeric argument");
475 1.4 cgd }
476 1.4 cgd
477 1.4 cgd if (b->u.i == 0) {
478 1.11 jtc errx (2, "division by zero");
479 1.4 cgd }
480 1.1 cgd
481 1.4 cgd r = make_integer (a->u.i % b->u.i);
482 1.4 cgd free_value (a);
483 1.4 cgd free_value (b);
484 1.4 cgd return r;
485 1.1 cgd }
486 1.1 cgd
487 1.6 jtc #include <regex.h>
488 1.6 jtc #define SE_MAX 30
489 1.1 cgd
490 1.1 cgd struct val *
491 1.1 cgd op_colon (a, b)
492 1.1 cgd struct val *a, *b;
493 1.1 cgd {
494 1.6 jtc regex_t rp;
495 1.6 jtc regmatch_t rm[SE_MAX];
496 1.6 jtc char errbuf[256];
497 1.6 jtc int eval;
498 1.6 jtc struct val *v;
499 1.9 jtc char *newpat;
500 1.6 jtc
501 1.7 jtc /* coerce to both arguments to strings */
502 1.7 jtc to_string(a);
503 1.7 jtc to_string(b);
504 1.6 jtc
505 1.9 jtc /* patterns are anchored to the beginning of the line */
506 1.9 jtc newpat = malloc (strlen (b->u.s) + 2);
507 1.9 jtc strcpy (newpat, "^");
508 1.9 jtc strcat (newpat, b->u.s);
509 1.9 jtc
510 1.6 jtc /* compile regular expression */
511 1.9 jtc if ((eval = regcomp (&rp, newpat, 0)) != 0) {
512 1.6 jtc regerror (eval, &rp, errbuf, sizeof(errbuf));
513 1.11 jtc errx (2, "%s", errbuf);
514 1.6 jtc }
515 1.9 jtc free (newpat);
516 1.6 jtc
517 1.6 jtc /* compare string against pattern */
518 1.6 jtc if (regexec(&rp, a->u.s, SE_MAX, rm, 0) == 0) {
519 1.6 jtc if (rm[1].rm_so >= 0) {
520 1.11 jtc *(a->u.s + rm[1].rm_eo) = '\0';
521 1.6 jtc v = make_str (a->u.s + rm[1].rm_so);
522 1.1 cgd
523 1.1 cgd } else {
524 1.6 jtc v = make_integer (rm[0].rm_eo - rm[0].rm_so);
525 1.1 cgd }
526 1.1 cgd } else {
527 1.11 jtc if (rp.re_nsub == 0) {
528 1.11 jtc v = make_integer (0);
529 1.11 jtc } else {
530 1.11 jtc v = make_str ("");
531 1.11 jtc }
532 1.1 cgd }
533 1.6 jtc
534 1.6 jtc /* free arguments and pattern buffer */
535 1.6 jtc free_value (a);
536 1.6 jtc free_value (b);
537 1.6 jtc regfree (&rp);
538 1.5 cgd
539 1.6 jtc return v;
540 1.1 cgd }
541