8 Expr = Or | Or '?' Expr ':' Expr
10 And = Eq | And '&&' Eq
11 Eq = Rel | Eq '==' Rel | Eq '!=' Rel
12 Rel = Add | Rel '<=' Add | Rel '>=' Add | Rel '<' Add | Rel '>' Add
13 Add = Mul | Add '+' Mul | Add '-' Mul
14 Mul = Term | Mul '*' Term | Mul '/' Term | Mul '%' Term
15 Term = '(' Expr ')' | '!' Term | decimal | 'n'
19 recursive descent expression evaluator with stack depth limit.
20 eval* functions return the value of the subexpression and set
21 the current string pointer to the next non-space char.
30 static const char *skipspace(const char *s)
32 while (isspace(*s)) s++;
36 static unsigned long evalconst(struct st *st)
40 n = strtoul(st->s, &e, 10);
41 if (!isdigit(*st->s) || e == st->s || n == -1)
47 static unsigned long evalexpr(struct st *st, int d);
49 static unsigned long evalterm(struct st *st, int d)
56 st->s = skipspace(st->s);
59 return !evalterm(st, d-1);
63 a = evalexpr(st, d-1);
68 st->s = skipspace(st->s + 1);
72 st->s = skipspace(st->s + 1);
78 static unsigned long evalmul(struct st *st, int d)
80 unsigned long b, a = evalterm(st, d-1);
84 if (op != '*' && op != '/' && op != '%')
87 b = evalterm(st, d-1);
93 } else if (op == '%') {
101 static unsigned long evaladd(struct st *st, int d)
106 a += (add?1:-1) * evalmul(st, d-1);
107 if (*st->s != '+' && *st->s != '-')
114 static unsigned long evalrel(struct st *st, int d)
116 unsigned long b, a = evaladd(st, d-1);
119 if (*st->s != '<' && *st->s != '>')
121 less = st->s[0] == '<';
122 eq = st->s[1] == '=';
124 b = evaladd(st, d-1);
125 a = (less ? a < b : a > b) || (eq && a == b);
129 static unsigned long evaleq(struct st *st, int d)
131 unsigned long a = evalrel(st, d-1);
134 if ((st->s[0] != '=' && st->s[0] != '!') || st->s[1] != '=')
136 neg = st->s[0] == '!';
138 a = evalrel(st, d-1) == a;
143 static unsigned long evaland(struct st *st, int d)
145 unsigned long a = evaleq(st, d-1);
147 if (st->s[0] != '&' || st->s[1] != '&')
150 a = evaleq(st, d-1) && a;
154 static unsigned long evalor(struct st *st, int d)
156 unsigned long a = evaland(st, d-1);
158 if (st->s[0] != '|' || st->s[1] != '|')
161 a = evaland(st, d-1) || a;
165 static unsigned long evalexpr(struct st *st, int d)
167 unsigned long a1, a2, a3;
172 a1 = evalor(st, d-1);
176 a2 = evalexpr(st, d-1);
182 a3 = evalexpr(st, d-1);
186 unsigned long __pleval(const char *s, unsigned long n)
193 a = evalexpr(&st, 100);
194 if (st.err || *st.s != ';')