Tôi đang cố gắng phân tích biểu thức logic phức tạp như biểu thức dưới đây;phân tích cú pháp một biểu thức logic phức tạp trong pyparsing theo kiểu cây nhị phân
x > 7 AND x < 8 OR x = 4
và nhận chuỗi được phân tích cú pháp dưới dạng cây nhị phân. Đối với biểu thức ở trên, biểu thức được phân tích cú pháp được mong đợi sẽ trông giống như
[['x', '>', 7], 'AND', [['x', '<', 8], 'OR', ['x', '=', 4]]]
Toán tử logic 'OR' có ưu tiên cao hơn toán tử 'AND'. Dấu ngoặc đơn có thể ghi đè quyền ưu tiên mặc định. Nói chung hơn, biểu thức được phân tích cú pháp sẽ trông giống như;
<left_expr> <logical_operator> <right_expr>
Một ví dụ khác sẽ
input_string = x > 7 AND x < 8 AND x = 4
parsed_expr = [[['x', '>', 7], 'AND', ['x', ',', 8]], 'AND', ['x', '=', 4]]
Cho đến nay tôi đã đưa ra giải pháp này đơn giản mà thật đáng buồn không thể tạo biểu phân tích cú pháp theo kiểu cây nhị phân. operatorPrecedence dường như không giúp tôi ở đây, nơi có cùng một toán tử lô-gic liên tiếp như trong ví dụ trước.
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")
Mọi đề xuất hoặc hướng dẫn đều được đánh giá cao.
BNF
cho biểu thức (không có dấu ngoặc đơn) có thể là
<expr> -> <expr> | <expr> <logical> <expr>
<expr> -> <opnd> <relational> <opnd>
<opnd> -> <variable> | <numeric>
<relational> -> <'>'> | <'='> | <'>='> | <'<='> | <'!='>
Mã của bạn là một chút khó khăn để làm theo, bạn có thể đăng bài ngữ pháp trong BNF? – georg
chỉ cần thêm BNF ... tôi không chắc chắn nếu nó rõ ràng hay không. – consumer