Reputation: 1362
i am trying parse logical operators, query string see below
code!=720 AND first_name=abc OR last_name=def AND status_code=OK
and get the parsed string as a binary tree. For the above expression the expected parsed expression should look like
[[['code', '!=', '720'], 'AND', ['first_name', '=', 'abc']], 'OR', [['last_name', '=', 'def'], 'AND', ['status_code', '=', 'OK']]]
i tried to do this code but i do not get the desired output
operator = pp.Regex(">=|<=|!=|>|<|=").setName("operator")
number = pp.Regex(r'[+-]?\w+(:?\.\w*)?(:?[eE][+-]?\w+)?')
word = pp.Word(pp.alphas, pp.alphanums + "_-*(1234567890 ,)")
term = word | number
condition = pp.Group(term + operator + term)
expr = pp.operatorPrecedence(condition,
[('NOT', 1, pp.opAssoc.RIGHT,),
('AND', 2, pp.opAssoc.LEFT,),
('OR', 2, pp.opAssoc.LEFT,)])
example
query_string = 'code!=720 AND first_name=abc OR last_name=def AND status_code=OK'
print(expr.parseString(query_string)[0])
and output is wrong
[['code', '!=', '720'], 'AND', ['first_name', '=', 'abc OR last_name']]
can you help me write the correct condition?
Upvotes: 5
Views: 1718
Reputation: 63762
All comments above incorporated in this code:
import pyparsing as pp
operator = pp.oneOf(">= <= != > < =").setName("operator")
number = pp.pyparsing_common.number()
# there is no space character in this pp.Word expression
word = pp.Word(pp.alphas, pp.alphanums + "_-*(1234567890,)")
term = word | number | pp.quotedString
condition = pp.Group(term + operator + term)
expr = pp.operatorPrecedence(condition,
[('NOT', 1, pp.opAssoc.RIGHT,),
('AND', 2, pp.opAssoc.LEFT,),
('OR', 2, pp.opAssoc.LEFT,)])
query_string = 'code!=720 AND first_name=abc OR last_name=def AND status_code=OK'
print(expr.parseString(query_string, parseAll=True)[0])
which gives this output:
[[['code', '!=', 720], 'AND', ['first_name', '=', 'abc']], 'OR', [['last_name', '=', 'def'], 'AND', ['status_code', '=', 'OK']]]
Upvotes: 6