Forward を使用して、括弧などでネストする独自の式を手作りできますが、pyparsing を使用すると、operatorPrecedence
このプロセス全体が簡素化されます。コメント付きで、以下の元のコードの更新された形式を参照してください。
from pyparsing import *
# break these up so we can represent higher precedence for 'and' over 'or'
#~ logical_operator = oneOf(['and','&','or','|'], caseless=True)
not_operator = oneOf(['not','^'], caseless=True)
and_operator = oneOf(['and','&'], caseless=True)
or_operator = oneOf(['or' ,'|'], caseless=True)
# db_keyword is okay, but you might just want to use a general 'identifier' expression,
# you won't have to keep updating as you add other terms to your query language
db_keyword = oneOf(['nucleon','b_coherent','symbol','mass'], caseless=True)
ident = Word(alphas+'_', alphanums+'_')
# these aren't really arithmetic operators, they are comparison operators
#~ arithmetic_operator = oneOf(['==','!=','>','>=','<', '<='])
comparison_operator = oneOf(['==','!=','>','>=','<', '<='])
# instead of generic 'value', define specific value types
#~ value = Word(alphanums+'_')
integer = Regex(r'[+-]?\d+').setParseAction(lambda t:int(t[0]))
float_ = Regex(r'[+-]?\d+\.\d*').setParseAction(lambda t:float(t[0]))
# use pyparsing's QuotedString class for this, it gives you quote escaping, and
# automatically strips quotes from the parsed text
#~ quote = Combine('"' + value + '"') | value
quote = QuotedString('"')
# when you are doing boolean expressions, it's always handy to add TRUE and FALSE literals
literal_true = Keyword('true', caseless=True)
literal_false = Keyword('false', caseless=True)
boolean_literal = literal_true | literal_false
# in future, you can expand comparison_operand to be its own operatorPrecedence
# term, so that you can do things like "nucleon != 1+2" - but this is fine for now
comparison_operand = quote | db_keyword | ident | float_ | integer
comparison_expr = Group(comparison_operand + comparison_operator + comparison_operand)
# all this business is taken of for you by operatorPrecedence
#~ selection = db_keyword + arithmetic_operator + (value|quote)
#~ selection = selection + ZeroOrMore(logical_operator+selection)
#~ parenthesis = Forward()
#~ parenthesis << ((selection + parenthesis) | selection)
#~ parenthesis = Combine('(' + parenthesis + ')') | selection
#~ grammar = parenthesis + lineEnd
boolean_expr = operatorPrecedence(comparison_expr | boolean_literal,
[
(not_operator, 1, opAssoc.RIGHT),
(and_operator, 2, opAssoc.LEFT),
(or_operator, 2, opAssoc.LEFT),
])
grammar = boolean_expr
res = grammar.parseString('b_Coherent == "1_2" or (symbol == 2 and nucleon != 3)', parseAll=True)
print res.asList()
版画
[[['b_coherent', '==', '1_2'], 'or', [['symbol', '==', 2], 'and', ['nucleon', '!=', 3]]]]
ここから、実際に評価できるものを作成するための次のステップをどのように行うかを検討することをお勧めします.pyparsing wikiのsimpleBool.pyの例をチェックして、.operatorPrecedence
あなたが pyparse を楽しんでいると聞いてうれしいです、ようこそ!