expr.y revision 295
14Srgrimes%{ 24Srgrimes/* Written by Pace Willisson (pace@blitz.com) 3295Sjtc * and placed in the public domain. 44Srgrimes * 5295Sjtc * Largely rewritten by J.T. Conklin (jtc@wimsey.com) 6295Sjtc * 7295Sjtc * $Header: /b/source/CVS/src/bin/expr/expr.y,v 1.11 1993/08/17 16:01:23 jtc Exp $ 84Srgrimes */ 94Srgrimes#include <stdio.h> 104Srgrimes#include <stdlib.h> 114Srgrimes#include <string.h> 124Srgrimes#include <ctype.h> 13295Sjtc#include <err.h> 1431Salm 154Srgrimesenum valtype { 164Srgrimes integer, string 174Srgrimes} ; 1831Salm 194Srgrimesstruct val { 204Srgrimes enum valtype type; 214Srgrimes union { 224Srgrimes char *s; 234Srgrimes int i; 244Srgrimes } u; 2531Salm} ; 264Srgrimes 274Srgrimesstruct val *result; 284Srgrimesstruct val *op_or (); 294Srgrimesstruct val *op_and (); 304Srgrimesstruct val *op_eq (); 314Srgrimesstruct val *op_gt (); 324Srgrimesstruct val *op_lt (); 334Srgrimesstruct val *op_ge (); 344Srgrimesstruct val *op_le (); 354Srgrimesstruct val *op_ne (); 364Srgrimesstruct val *op_plus (); 374Srgrimesstruct val *op_minus (); 384Srgrimesstruct val *op_times (); 394Srgrimesstruct val *op_div (); 404Srgrimesstruct val *op_rem (); 414Srgrimesstruct val *op_colon (); 424Srgrimes 434Srgrimeschar **av; 444Srgrimes%} 454Srgrimes 464Srgrimes%union 474Srgrimes{ 484Srgrimes struct val *val; 494Srgrimes} 504Srgrimes 514Srgrimes%left <val> '|' 524Srgrimes%left <val> '&' 534Srgrimes%left <val> '=' '>' '<' GE LE NE 544Srgrimes%left <val> '+' '-' 554Srgrimes%left <val> '*' '/' '%' 564Srgrimes%left <val> ':' 574Srgrimes%left UNARY 584Srgrimes 594Srgrimes%token <val> TOKEN 604Srgrimes%type <val> start expr 614Srgrimes 624Srgrimes%% 634Srgrimes 644Srgrimesstart: expr { result = $$; } 654Srgrimes 664Srgrimesexpr: TOKEN 674Srgrimes | '(' expr ')' { $$ = $2; } 684Srgrimes | expr '|' expr { $$ = op_or ($1, $3); } 694Srgrimes | expr '&' expr { $$ = op_and ($1, $3); } 704Srgrimes | expr '=' expr { $$ = op_eq ($1, $3); } 714Srgrimes | expr '>' expr { $$ = op_gt ($1, $3); } 724Srgrimes | expr '<' expr { $$ = op_lt ($1, $3); } 734Srgrimes | expr GE expr { $$ = op_ge ($1, $3); } 744Srgrimes | expr LE expr { $$ = op_le ($1, $3); } 754Srgrimes | expr NE expr { $$ = op_ne ($1, $3); } 764Srgrimes | expr '+' expr { $$ = op_plus ($1, $3); } 774Srgrimes | expr '-' expr { $$ = op_minus ($1, $3); } 784Srgrimes | expr '*' expr { $$ = op_times ($1, $3); } 794Srgrimes | expr '/' expr { $$ = op_div ($1, $3); } 804Srgrimes | expr '%' expr { $$ = op_rem ($1, $3); } 814Srgrimes | expr ':' expr { $$ = op_colon ($1, $3); } 824Srgrimes | '-' expr %prec UNARY { $$ = op_minus (NULL, $2); } 834Srgrimes ; 844Srgrimes 854Srgrimes 864Srgrimes%% 874Srgrimes 884Srgrimesstruct val * 894Srgrimesmake_integer (i) 904Srgrimesint i; 914Srgrimes{ 924Srgrimes struct val *vp; 934Srgrimes 944Srgrimes vp = (struct val *) malloc (sizeof (*vp)); 954Srgrimes if (vp == NULL) { 96295Sjtc err (2, NULL); 974Srgrimes } 984Srgrimes 994Srgrimes vp->type = integer; 1004Srgrimes vp->u.i = i; 1014Srgrimes return vp; 1024Srgrimes} 1034Srgrimes 1044Srgrimesstruct val * 1054Srgrimesmake_str (s) 1064Srgrimeschar *s; 1074Srgrimes{ 1084Srgrimes struct val *vp; 1094Srgrimes 1104Srgrimes vp = (struct val *) malloc (sizeof (*vp)); 1114Srgrimes if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) { 112295Sjtc err (2, NULL); 1134Srgrimes } 1144Srgrimes 1154Srgrimes vp->type = string; 1164Srgrimes return vp; 1174Srgrimes} 1184Srgrimes 1194Srgrimes 1204Srgrimesvoid 1214Srgrimesfree_value (vp) 1224Srgrimesstruct val *vp; 1234Srgrimes{ 1244Srgrimes if (vp->type == string) 1254Srgrimes free (vp->u.s); 1264Srgrimes} 1274Srgrimes 1284Srgrimes 1294Srgrimesint 1304Srgrimesto_integer (vp) 1314Srgrimesstruct val *vp; 1324Srgrimes{ 1334Srgrimes char *s; 1344Srgrimes int neg; 1354Srgrimes int i; 1364Srgrimes 1374Srgrimes if (vp->type == integer) 1384Srgrimes return 1; 1394Srgrimes 1404Srgrimes s = vp->u.s; 1414Srgrimes i = 0; 1424Srgrimes 1434Srgrimes neg = (*s == '-'); 1444Srgrimes if (neg) 1454Srgrimes s++; 1464Srgrimes 1474Srgrimes for (;*s; s++) { 1484Srgrimes if (!isdigit (*s)) 1494Srgrimes return 0; 1504Srgrimes 1514Srgrimes i *= 10; 1524Srgrimes i += *s - '0'; 1534Srgrimes } 1544Srgrimes 1554Srgrimes free (vp->u.s); 1564Srgrimes if (neg) 1574Srgrimes i *= -1; 1584Srgrimes 1594Srgrimes vp->type = integer; 1604Srgrimes vp->u.i = i; 1614Srgrimes return 1; 1624Srgrimes} 1634Srgrimes 1644Srgrimesvoid 1654Srgrimesto_string (vp) 1664Srgrimesstruct val *vp; 1674Srgrimes{ 1684Srgrimes char *tmp; 1694Srgrimes 1704Srgrimes if (vp->type == string) 1714Srgrimes return; 1724Srgrimes 1734Srgrimes tmp = malloc (25); 1744Srgrimes if (tmp == NULL) { 175295Sjtc err (2, NULL); 1764Srgrimes } 1774Srgrimes 1784Srgrimes sprintf (tmp, "%d", vp->u.i); 1794Srgrimes vp->type = string; 1804Srgrimes vp->u.s = tmp; 1814Srgrimes} 1824Srgrimes 1834Srgrimes 1844Srgrimesint 1854Srgrimesisstring (vp) 1864Srgrimesstruct val *vp; 1874Srgrimes{ 1884Srgrimes return (vp->type == string); 1894Srgrimes} 1904Srgrimes 1914Srgrimes 1924Srgrimesint 1934Srgrimesyylex () 1944Srgrimes{ 1954Srgrimes struct val *vp; 1964Srgrimes char *p; 1974Srgrimes 1984Srgrimes if (*av == NULL) 1994Srgrimes return (0); 2004Srgrimes 2014Srgrimes p = *av++; 2024Srgrimes 2034Srgrimes if (strlen (p) == 1) { 2044Srgrimes if (strchr ("|&=<>+-*/%:()", *p)) 2054Srgrimes return (*p); 2064Srgrimes } else if (strlen (p) == 2 && p[1] == '=') { 2074Srgrimes switch (*p) { 2084Srgrimes case '>': return (GE); 2094Srgrimes case '<': return (LE); 2104Srgrimes case '!': return (NE); 2114Srgrimes } 2124Srgrimes } 2134Srgrimes 2144Srgrimes yylval.val = make_str (p); 2154Srgrimes return (TOKEN); 2164Srgrimes} 2174Srgrimes 2184Srgrimesint 2194Srgrimesis_zero_or_null (vp) 2204Srgrimesstruct val *vp; 2214Srgrimes{ 2224Srgrimes if (vp->type == integer) { 2234Srgrimes return (vp->u.i == 0); 2244Srgrimes } else { 225181Sconklin return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0)); 2264Srgrimes } 2274Srgrimes /* NOTREACHED */ 2284Srgrimes} 2294Srgrimes 2304Srgrimesvoid 2314Srgrimesmain (argc, argv) 2324Srgrimesint argc; 2334Srgrimeschar **argv; 2344Srgrimes{ 2354Srgrimes av = argv + 1; 2364Srgrimes 2374Srgrimes yyparse (); 2384Srgrimes 2394Srgrimes if (result->type == integer) 2404Srgrimes printf ("%d\n", result->u.i); 2414Srgrimes else 2424Srgrimes printf ("%s\n", result->u.s); 2434Srgrimes 2444Srgrimes if (is_zero_or_null (result)) 2454Srgrimes exit (1); 2464Srgrimes else 2474Srgrimes exit (0); 2484Srgrimes} 2494Srgrimes 2504Srgrimesint 2514Srgrimesyyerror (s) 2524Srgrimeschar *s; 2534Srgrimes{ 254295Sjtc errx (2, "syntax error"); 2554Srgrimes} 2564Srgrimes 2574Srgrimes 2584Srgrimesstruct val * 2594Srgrimesop_or (a, b) 2604Srgrimesstruct val *a, *b; 2614Srgrimes{ 2624Srgrimes if (is_zero_or_null (a)) { 2634Srgrimes free_value (a); 2644Srgrimes return (b); 2654Srgrimes } else { 2664Srgrimes free_value (b); 2674Srgrimes return (a); 2684Srgrimes } 2694Srgrimes} 2704Srgrimes 2714Srgrimesstruct val * 2724Srgrimesop_and (a, b) 2734Srgrimesstruct val *a, *b; 2744Srgrimes{ 2754Srgrimes if (is_zero_or_null (a) || is_zero_or_null (b)) { 2764Srgrimes free_value (a); 2774Srgrimes free_value (b); 2784Srgrimes return (make_integer (0)); 2794Srgrimes } else { 2804Srgrimes free_value (b); 2814Srgrimes return (a); 2824Srgrimes } 2834Srgrimes} 2844Srgrimes 2854Srgrimesstruct val * 2864Srgrimesop_eq (a, b) 2874Srgrimesstruct val *a, *b; 2884Srgrimes{ 2894Srgrimes struct val *r; 2904Srgrimes 2914Srgrimes if (isstring (a) || isstring (b)) { 2924Srgrimes to_string (a); 2934Srgrimes to_string (b); 294295Sjtc r = make_integer (strcoll (a->u.s, b->u.s) == 0); 2954Srgrimes } else { 2964Srgrimes r = make_integer (a->u.i == b->u.i); 2974Srgrimes } 2984Srgrimes 2994Srgrimes free_value (a); 3004Srgrimes free_value (b); 3014Srgrimes return r; 3024Srgrimes} 3034Srgrimes 3044Srgrimesstruct val * 3054Srgrimesop_gt (a, b) 3064Srgrimesstruct val *a, *b; 3074Srgrimes{ 3084Srgrimes struct val *r; 3094Srgrimes 3104Srgrimes if (isstring (a) || isstring (b)) { 3114Srgrimes to_string (a); 3124Srgrimes to_string (b); 313295Sjtc r = make_integer (strcoll (a->u.s, b->u.s) > 0); 3144Srgrimes } else { 3154Srgrimes r= make_integer (a->u.i > b->u.i); 3164Srgrimes } 3174Srgrimes 3184Srgrimes free_value (a); 3194Srgrimes free_value (b); 3204Srgrimes return r; 3214Srgrimes} 3224Srgrimes 3234Srgrimesstruct val * 3244Srgrimesop_lt (a, b) 3254Srgrimesstruct val *a, *b; 3264Srgrimes{ 3274Srgrimes struct val *r; 3284Srgrimes 3294Srgrimes if (isstring (a) || isstring (b)) { 3304Srgrimes to_string (a); 3314Srgrimes to_string (b); 332295Sjtc r = make_integer (strcoll (a->u.s, b->u.s) < 0); 3334Srgrimes } else { 3344Srgrimes r = make_integer (a->u.i < b->u.i); 3354Srgrimes } 3364Srgrimes 3374Srgrimes free_value (a); 3384Srgrimes free_value (b); 3394Srgrimes return r; 3404Srgrimes} 3414Srgrimes 3424Srgrimesstruct val * 3434Srgrimesop_ge (a, b) 3444Srgrimesstruct val *a, *b; 3454Srgrimes{ 3464Srgrimes struct val *r; 3474Srgrimes 3484Srgrimes if (isstring (a) || isstring (b)) { 3494Srgrimes to_string (a); 3504Srgrimes to_string (b); 351295Sjtc r = make_integer (strcoll (a->u.s, b->u.s) >= 0); 3524Srgrimes } else { 3534Srgrimes r = make_integer (a->u.i >= b->u.i); 3544Srgrimes } 3554Srgrimes 3564Srgrimes free_value (a); 3574Srgrimes free_value (b); 3584Srgrimes return r; 3594Srgrimes} 3604Srgrimes 3614Srgrimesstruct val * 3624Srgrimesop_le (a, b) 3634Srgrimesstruct val *a, *b; 3644Srgrimes{ 3654Srgrimes struct val *r; 3664Srgrimes 3674Srgrimes if (isstring (a) || isstring (b)) { 3684Srgrimes to_string (a); 3694Srgrimes to_string (b); 370295Sjtc r = make_integer (strcoll (a->u.s, b->u.s) <= 0); 3714Srgrimes } else { 3724Srgrimes r = make_integer (a->u.i <= b->u.i); 3734Srgrimes } 3744Srgrimes 3754Srgrimes free_value (a); 3764Srgrimes free_value (b); 3774Srgrimes return r; 3784Srgrimes} 3794Srgrimes 3804Srgrimesstruct val * 3814Srgrimesop_ne (a, b) 3824Srgrimesstruct val *a, *b; 3834Srgrimes{ 3844Srgrimes struct val *r; 3854Srgrimes 3864Srgrimes if (isstring (a) || isstring (b)) { 3874Srgrimes to_string (a); 3884Srgrimes to_string (b); 389295Sjtc r = make_integer (strcoll (a->u.s, b->u.s) != 0); 3904Srgrimes } else { 3914Srgrimes r = make_integer (a->u.i != b->u.i); 3924Srgrimes } 3934Srgrimes 3944Srgrimes free_value (a); 3954Srgrimes free_value (b); 3964Srgrimes return r; 3974Srgrimes} 3984Srgrimes 3994Srgrimesstruct val * 4004Srgrimesop_plus (a, b) 4014Srgrimesstruct val *a, *b; 4024Srgrimes{ 4034Srgrimes struct val *r; 4044Srgrimes 4054Srgrimes if (!to_integer (a) || !to_integer (b)) { 406295Sjtc errx (2, "non-numeric argument"); 4074Srgrimes } 4084Srgrimes 4094Srgrimes r = make_integer (a->u.i + b->u.i); 4104Srgrimes free_value (a); 4114Srgrimes free_value (b); 4124Srgrimes return r; 4134Srgrimes} 4144Srgrimes 4154Srgrimesstruct val * 4164Srgrimesop_minus (a, b) 4174Srgrimesstruct val *a, *b; 4184Srgrimes{ 4194Srgrimes struct val *r; 4204Srgrimes 4214Srgrimes if (!to_integer (a) || !to_integer (b)) { 422295Sjtc errx (2, "non-numeric argument"); 4234Srgrimes } 4244Srgrimes 4254Srgrimes r = make_integer (a->u.i - b->u.i); 4264Srgrimes free_value (a); 4274Srgrimes free_value (b); 4284Srgrimes return r; 4294Srgrimes} 4304Srgrimes 4314Srgrimesstruct val * 4324Srgrimesop_times (a, b) 4334Srgrimesstruct val *a, *b; 4344Srgrimes{ 4354Srgrimes struct val *r; 4364Srgrimes 4374Srgrimes if (!to_integer (a) || !to_integer (b)) { 438295Sjtc errx (2, "non-numeric argument"); 4394Srgrimes } 4404Srgrimes 4414Srgrimes r = make_integer (a->u.i * b->u.i); 4424Srgrimes free_value (a); 4434Srgrimes free_value (b); 4444Srgrimes return (r); 4454Srgrimes} 4464Srgrimes 4474Srgrimesstruct val * 4484Srgrimesop_div (a, b) 4494Srgrimesstruct val *a, *b; 4504Srgrimes{ 4514Srgrimes struct val *r; 4524Srgrimes 4534Srgrimes if (!to_integer (a) || !to_integer (b)) { 454295Sjtc errx (2, "non-numeric argument"); 4554Srgrimes } 4564Srgrimes 4574Srgrimes if (b->u.i == 0) { 458295Sjtc errx (2, "division by zero"); 4594Srgrimes } 4604Srgrimes 4614Srgrimes r = make_integer (a->u.i / b->u.i); 4624Srgrimes free_value (a); 4634Srgrimes free_value (b); 4644Srgrimes return r; 4654Srgrimes} 4664Srgrimes 4674Srgrimesstruct val * 4684Srgrimesop_rem (a, b) 4694Srgrimesstruct val *a, *b; 4704Srgrimes{ 4714Srgrimes struct val *r; 4724Srgrimes 4734Srgrimes if (!to_integer (a) || !to_integer (b)) { 474295Sjtc errx (2, "non-numeric argument"); 4754Srgrimes } 4764Srgrimes 4774Srgrimes if (b->u.i == 0) { 478295Sjtc errx (2, "division by zero"); 4794Srgrimes } 4804Srgrimes 4814Srgrimes r = make_integer (a->u.i % b->u.i); 4824Srgrimes free_value (a); 4834Srgrimes free_value (b); 4844Srgrimes return r; 4854Srgrimes} 4864Srgrimes 48731Salm#include <regex.h> 48831Salm#define SE_MAX 30 4894Srgrimes 4904Srgrimesstruct val * 4914Srgrimesop_colon (a, b) 4924Srgrimesstruct val *a, *b; 4934Srgrimes{ 49431Salm regex_t rp; 49531Salm regmatch_t rm[SE_MAX]; 49631Salm char errbuf[256]; 49731Salm int eval; 498181Sconklin struct val *v; 49931Salm char *newpat; 5004Srgrimes 501181Sconklin /* coerce to both arguments to strings */ 502181Sconklin to_string(a); 503181Sconklin to_string(b); 504181Sconklin 50531Salm /* patterns are anchored to the beginning of the line */ 50631Salm newpat = malloc (strlen (b->u.s) + 2); 50731Salm strcpy (newpat, "^"); 50831Salm strcat (newpat, b->u.s); 5094Srgrimes 51031Salm /* compile regular expression */ 51131Salm if ((eval = regcomp (&rp, newpat, 0)) != 0) { 51231Salm regerror (eval, &rp, errbuf, sizeof(errbuf)); 513295Sjtc errx (2, "%s", errbuf); 5144Srgrimes } 51531Salm free (newpat); 5164Srgrimes 51731Salm /* compare string against pattern */ 51831Salm if (regexec(&rp, a->u.s, SE_MAX, rm, 0) == 0) { 51931Salm if (rm[1].rm_so >= 0) { 520295Sjtc *(a->u.s + rm[1].rm_eo) = '\0'; 52131Salm v = make_str (a->u.s + rm[1].rm_so); 52231Salm 5234Srgrimes } else { 52431Salm v = make_integer (rm[0].rm_eo - rm[0].rm_so); 5254Srgrimes } 5264Srgrimes } else { 527295Sjtc if (rp.re_nsub == 0) { 528295Sjtc v = make_integer (0); 529295Sjtc } else { 530295Sjtc v = make_str (""); 531295Sjtc } 5324Srgrimes } 5334Srgrimes 53431Salm /* free arguments and pattern buffer */ 53531Salm free_value (a); 53631Salm free_value (b); 53731Salm regfree (&rp); 53831Salm 53931Salm return v; 5404Srgrimes} 541