~kf5jwc/imp-parser

ref: 4a8b0d0c4a9b3e235854c13031f981f55fc7ece5 imp-parser/imp_parser/parser/boolean.py -rw-r--r-- 1.2 KiB View raw
4a8b0d0c — Kyle Jones More typing! 1 year, 7 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from typing import Any, Callable, Union
from ..ast import AndBexp, NotBexp, OrBexp, RelopBexp
from .arithmetic import aexp, any_operator_in_list, keyword, precedence, process_group
from .combinators import Alternate, Process, Lazy


RELOPS = ["<", "<=", ">", ">=", "=", "!="]
BEXP_PRECEDENCE_LEVELS = [["and"], ["or"]]


def process_relop(parsed) -> RelopBexp:
    ((left, op), right) = parsed
    return RelopBexp(op, left, right)


def bexp_relop() -> Process:
    return aexp() + any_operator_in_list(RELOPS) + aexp() ^ process_relop


def bexp_not() -> Process:
    return keyword("not") + Lazy(bexp_term) ^ (lambda parsed: NotBexp(parsed[1]))


def bexp_group() -> Process:
    return keyword("(") + Lazy(bexp) + keyword(")") ^ process_group


def bexp_term() -> Alternate:
    return bexp_not() | bexp_relop() | bexp_group()


def process_logic(op) -> Callable[..., Union[AndBexp, OrBexp]]:
    if op == "and":
        return lambda l, r: AndBexp(l, r)
    elif op == "or":
        return lambda l, r: OrBexp(l, r)
    else:
        raise RuntimeError(f"Unknown logic operator: {op}")


def bexp():
    return precedence(bexp_term(), BEXP_PRECEDENCE_LEVELS, process_logic)