'python calculating parsed logical expression (without eval)

I'm looking for the best way of calculating a string expression that holds a logical expression like: x and not y or (z or w) or a json logic like: {"and": {"x": "true", "y": "false"}, "or": {"or": {"z": "true", "w": "True"}}}

I decide how to config file should look like so the format could be changed, it's just an example.

I saw a way to parse the first string using pyparse to something like: ['x', 'AND', 'y', 'OR', ['z', 'OR', 'W']] but I don't know how to get the value of the expression after I parsed it.

About the json logic format I saw the package json-logic tried it but it seems like the code is broken since I can't run any of their examples so if there is something else I think that would be great.

x = True
y = False
z = False
w = False
calc_string_as_bool('x and not y or (z or w)') -> True

Thanks for the help.



Solution 1:[1]

It sounds to me like what you're after is eval, even though you say without eval.

In [1]: True and True
Out[1]: True

In [2]: e = "True and True"

In [3]: eval(e)
Out[3]: True

In [4]: el = ["True", "and", "True"]

In [5]: eval(" ".join(el))
Out[5]: True

Maybe you can clarify why using eval to do what eval does isn't an option.


Adding example, based on sample in question:

def eval_recurse(ops, replacements):
    evaluated = []
    for op in ops:
        if type(op) is list:
            evaluated.append(str(eval_recurse(op, replacements)))
            continue
        if str(op).lower() in ["and", "not", "or"]:
            op = op.lower()
        if op in replacements:
            op = str(replacements[op])
        evaluated.append(op)
    return eval(" ".join(evaluated))


if __name__ == "__main__":
    replacements = {"x": True, "y": False, "z": False, "w": False}
    print(eval_recurse(["x", "AND", "NOT", "y", "OR", ["z", "OR", "w"]], replacements))

This yields True. This may not be helpful since you don't want to use eval, but I figured I'd provide it in case.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1