diff options
author | Christian Neukirchen <chneukirchen@gmail.com> | 2015-10-23 15:02:51 +0200 |
---|---|---|
committer | Christian Neukirchen <chneukirchen@gmail.com> | 2015-10-23 15:02:51 +0200 |
commit | aaf0aede377ebf96a5acfd8f12aa0b5e48445b3e (patch) | |
tree | ee3b981aad365f4324d22ed3e2e32accb7e49dba /lr.c | |
parent | 7444f77df97dcf98be62e13ff2e3fbe7aae77de1 (diff) | |
download | lr-aaf0aede377ebf96a5acfd8f12aa0b5e48445b3e.tar.gz lr-aaf0aede377ebf96a5acfd8f12aa0b5e48445b3e.tar.xz lr-aaf0aede377ebf96a5acfd8f12aa0b5e48445b3e.zip |
generic expr chaining
Diffstat (limited to 'lr.c')
-rw-r--r-- | lr.c | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/lr.c b/lr.c index 7a953f5..4bd1832 100644 --- a/lr.c +++ b/lr.c @@ -258,8 +258,10 @@ parse_inner() return e; parse_error("missing )"); return 0; - } else + } else { + parse_error("unknown expression"); return 0; + } } struct expr * @@ -429,26 +431,34 @@ parse_cmp() } struct expr * +chain(struct expr *e1, enum op op, struct expr *e2) +{ + struct expr *i, *j, *e; + for (j = 0, i = e1; i->op == op; j = i, i = i->b.expr) + ; + if (!j) { + e = mkexpr(op); + e->a.expr = e1; + e->b.expr = e2; + return e; + } else { + e = mkexpr(op); + e->a.expr = i; + e->b.expr = e2; + j->b.expr = e; + return e1; + } +} + +struct expr * parse_and() { struct expr *e1 = parse_cmp(); struct expr *r = e1; - struct expr *l = 0, *a = 0; while (token("&&")) { struct expr *e2 = parse_cmp(); - if (!l) { - l = mkexpr(EXPR_AND); - l->a.expr = e1; - l->b.expr = e2; - r = l; - } else { - a = mkexpr(EXPR_AND); - a->a.expr = l->b.expr; - a->b.expr = e2; - l->b.expr = a; - l = a; - } + r = chain(r, EXPR_AND, e2); } return r; @@ -460,22 +470,10 @@ parse_or() { struct expr *e1 = parse_and(); struct expr *r = e1; - struct expr *l = 0, *o = 0; while (token("||")) { struct expr *e2 = parse_and(); - if (!l) { - l = mkexpr(EXPR_OR); - l->a.expr = e1; - l->b.expr = e2; - r = l; - } else { - o = mkexpr(EXPR_OR); - o->a.expr = l->b.expr; - o->b.expr = e2; - l->b.expr = o; - l = o; - } + r = chain(r, EXPR_OR, e2); } return r; |