我想用pyparsing制作一个表达式求值器,如下所示:
要解析的字符串应该是使用〜&|组合的常用表达式具有特定格式的字符串的符号(对于not和or,例如,此优先顺序)(假设现在仅单个字母,从a到z),其中每个字母通过自定义函数求值为布尔值列表(假设f),并且〜&|对每个布尔列表的操作应逐点应用。
即
a=[True, False] -> a=[True, False]
a=[True, False] -> ~a=[False, True]
a=[True, False] -> ~~a=[True, False]
a=[True, False] -> (((a)))=[True, False]
a=[True, False], b=[False,False], c=[True, True] -> ((a|b)&(~c))=[False, False]
到任何嵌套级别。
任何建议都值得赞赏。
编辑: 阅读评论以及评论作者发表的电子书“ Pyparsing入门”(O'Reilly)之后,我到了这里:
class UnaryOperation(object):
def __init__(self, tokens):
self.operator, self.operand = tokens[0]
class BinaryOperation(object):
def __init__(self, tokens):
self.operator = tokens[0][1]
self.operands = tokens[0][0::2]
class SearchNot(UnaryOperation):
def generateExpression(self):
return u'~{}'.format(self.operand.generateExpression())
class SearchAnd(BinaryOperation):
def generateExpression(self):
return u'({})'.format('&'.join(op.generateExpression() for op in self.operands))
class SearchOr(BinaryOperation):
def generateExpression(self):
return u'({})'.format('|'.join(op.generateExpression() for op in self.operands))
class ConditionString(object):
def __init__(self, tokens):
self.term = tokens[0]
def generateExpression(self):
return str(mapper(self.term))
def mapper(input_string):
p = True
q = False
r = True
d = {u'b_1':[p,q,r],
u'a_1':[r,q,q],
u'c2':[p,p,r],
u'a1':[q,q,r],
u'a':[r,r,p],
u'd1':[q,p,p]}
return d[input_string] if input_string in d.keys() else 3*[True]
qname = Word(alphas+u'_', alphanums+u'_')
expression = operatorPrecedence(qname.setParseAction(ConditionString),
[(u'~', 1, opAssoc.RIGHT, SearchNot),
(u'&', 2, opAssoc.LEFT, SearchAnd),
(u'|', 2, opAssoc.LEFT, SearchOr)])
tests = [
u'b_1',
u'~a_1',
u'b_1&~c2',
u'~a1|(a&(((c2|d_1))))',
u'a&a1&b_1|c2'
]
for t in tests:
try:
evalStack = (expression + stringEnd).parseString(t)[0]
except ParseException, pe:
print "Invalid search string"
continue
evalExpr = evalStack.generateExpression()
print "Eval expr: ", evalExpr
将打印出来
Eval expr: [True, False, True]
Eval expr: ~[True, False, False]
Eval expr: ([True, False, True]&~[True, True, True])
Eval expr: (~[False, False, True]|([True, True, True]&([True, True, True]|[True, True, True])))
Eval expr: (([True, True, True]&[False, False, True]&[True, False, True])|[True, True, True])
这与第59-60页中的示例类似,但是如何使用此处的eval()(但用于集合)以类似的方式从这里开始呢?
答案 0 :(得分:1)
要添加评估,请向您的每个类添加eval()
方法。每个eval()方法都会对您的布尔列表执行相应的操作:
list_wise_op(op, operands):
return [op(a_b) for a_b in zip(operands)]
# ConditionString
def eval(self):
return mapper(self.term)
#SearchNot
def eval(self):
return [not x for x in self.operand.eval()]
# SearchAnd
def eval(self):
return list_wise_op(all, [op.eval() for op in self.operands])
# SearchOr
def eval(self):
return list_wise_op(any, [op.eval() for op in self.operands])
现在您应该可以致电evalstack.eval()
。