cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit f8224f9d814b111e9841c8c3e9735046290b55a6
parent 6a00f53cd34e33c12a91942015a3dc5dbcb44bf2
Author: Michael Forney <mforney@mforney.org>
Date:   Thu, 14 Mar 2019 17:59:47 -0700

Use precedence climbing to parse binary expressions

Diffstat:
Mexpr.c | 86++++++++++++++++++++++++++++++-------------------------------------------------
1 file changed, 33 insertions(+), 53 deletions(-)

diff --git a/expr.c b/expr.c @@ -729,70 +729,50 @@ castexpr(struct scope *s) } static int -isequality(enum tokenkind t) +precedence(enum tokenkind t) { - return t == TEQL || t == TNEQ; -} - -static int -isrelational(enum tokenkind t) -{ - return t == TLESS || t == TGREATER || t == TLEQ || t == TGEQ; -} - -static int -isshift(enum tokenkind t) -{ - return t == TSHL || t == TSHR; -} - -static int -isadditive(enum tokenkind t) -{ - return t == TADD || t == TSUB; -} - -static int -ismultiplicative(enum tokenkind t) -{ - return t == TMUL || t == TDIV || t == TMOD; + switch (t) { + case TLOR: return 0; + case TLAND: return 1; + case TBOR: return 2; + case TXOR: return 3; + case TBAND: return 4; + case TEQL: + case TNEQ: return 5; + case TLESS: + case TGREATER: + case TLEQ: + case TGEQ: return 6; + case TSHL: + case TSHR: return 7; + case TADD: + case TSUB: return 8; + case TMUL: + case TDIV: + case TMOD: return 9; + } + return -1; } static struct expr * -binaryexpr(struct scope *s, size_t i) +binaryexpr(struct scope *s, struct expr *l, int i) { - static const struct { - int tok; - int (*fn)(enum tokenkind); - } prec[] = { - // XXX: bitmask? - {.tok = TLOR}, - {.tok = TLAND}, - {.tok = TBOR}, - {.tok = TXOR}, - {.tok = TBAND}, - {.fn = isequality}, - {.fn = isrelational}, - {.fn = isshift}, - {.fn = isadditive}, - {.fn = ismultiplicative}, - }; - struct expr *e, *l, *r; + struct expr *r; struct location loc; enum tokenkind op; + int j, k; - if (i >= LEN(prec)) - return castexpr(s); - l = binaryexpr(s, i + 1); - while (tok.kind == prec[i].tok || (prec[i].fn && prec[i].fn(tok.kind))) { + if (!l) + l = castexpr(s); + while ((j = precedence(tok.kind)) >= i) { op = tok.kind; loc = tok.loc; next(); - r = binaryexpr(s, i + 1); - e = mkbinaryexpr(&loc, op, l, r); - l = e; + r = castexpr(s); + while ((k = precedence(tok.kind)) > j) + r = binaryexpr(s, r, k); + l = mkbinaryexpr(&loc, op, l, r); } - return l; } @@ -813,7 +793,7 @@ condexpr(struct scope *s) struct type *t, *f; enum typequal tq; - r = binaryexpr(s, 0); + r = binaryexpr(s, NULL, 0); if (!consume(TQUESTION)) return r; e = mkexpr(EXPRCOND, NULL, 0);