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