我正在尝试解析类似下面这样的复杂逻辑表达式;
x > 7 AND x < 8 OR x = 4
并将解析后的字符串作为二叉树获取。对于上述表达式,期望的解析表达式应该如下所示
[['x', '>', 7], 'AND', [['x', '<', 8], 'OR', ['x', '=', 4]]]
'OR'逻辑运算符的优先级高于'AND'运算符。括号可以覆盖默认优先级。为了更加通用,解析后的表达式应该如下所示;
'OR'逻辑运算符比'AND'运算符具有更高的优先级。使用括号可以覆盖默认优先级。为了更通用,解析后的表达式应该像这样;
<left_expr> <logical_operator> <right_expr>
另一个例子是
input_string = x > 7 AND x < 8 AND x = 4
parsed_expr = [[['x', '>', 7], 'AND', ['x', ',', 8]], 'AND', ['x', '=', 4]]
到目前为止,我想出了这个简单的解决方案,但它无法以二叉树方式生成解析表达式。在存在与先前示例中相同的逻辑运算符连续出现的情况下,operatorPrecedence似乎对我没有帮助。
import pyparsing as pp
complex_expr = pp.Forward()
operator = pp.Regex(">=|<=|!=|>|<|=").setName("operator")
logical = (pp.Keyword("AND") | pp.Keyword("OR")).setName("logical")
vars = pp.Word(pp.alphas, pp.alphanums + "_") | pp.Regex(r"[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?")
condition = (vars + operator + vars)
clause = pp.Group(condition ^ (pp.Suppress("(") + complex_expr + pp.Suppress(")") ))
expr = pp.operatorPrecedence(clause,[
("OR", 2, pp.opAssoc.LEFT, ),
("AND", 2, pp.opAssoc.LEFT, ),])
complex_expr << expr
print complex_expr.parseString("x > 7 AND x < 8 AND x = 4")
非常感谢您的意见和指导。
表达式(不包括括号)的BNF
如下:
<expr> -> <expr> | <expr> <logical> <expr>
<expr> -> <opnd> <relational> <opnd>
<opnd> -> <variable> | <numeric>
<relational> -> <'>'> | <'='> | <'>='> | <'<='> | <'!='>