我想使用pyparsing模块来解析表达式,例如:
carbo *或oxy *或nitro *
解析后,这些表达式应转换为:
carbo(universe).select([*])|氧气(宇宙).select([*])|硝基(宇宙)。选择([*])
进一步评估。
我构建的语法仅适用于字符串中的第一个或,但不适用于后续的或。这是我的语法:
from pyparsing import *
def parse_keyword(token):
return '"%s"(universe).select' % token[0]
def parse_arguments(token):
return "(%s)" % str(token)
def operator_and(token):
token[0][1] = "&"
return " ".join(token[0])
def operator_or(token):
token[0][1] = "|"
return " ".join(token[0])
def parse_expression(self, token):
return "".join([str(t) for t in token])
expression = 'carbo * or oxy * or nitro *'
linkers = oneOf(["and","or",], caseless=True)
keyword = oneOf(['carbo','oxy','nitro'], caseless=True).setParseAction(parse_keyword)
arguments = Optional(~linkers + delimitedList(Word(printables,excludeChars=","),combine=False)).setParseAction(parse_arguments)
selector = OneOrMore((keyword+arguments))
grammar = Forward()
grammar << selector.setParseAction(parse_expression)
grammar = operatorPrecedence(grammar, [(oneOf(["and"],caseless=True), 2, opAssoc.LEFT , operator_and),
(oneOf(["or"] ,caseless=True), 2, opAssoc.LEFT , operator_or)],
lpar="(",
rpar=")")
parsedExpression = grammar.transformString(expression)
print parsedExpression
你会知道它有什么问题吗?
感谢
埃里克
答案 0 :(得分:0)
语法的问题是在运算符优先级定义中使用LEFT关联而不是RIGHT。 这是完成工作的最终语法:
from pyparsing import *
def parse_keyword(token):
return '"%s"(universe).select' % token[0]
def parse_arguments(token):
return "(%s)" % str(token)
def operator_and(token):
token[0][1] = "&"
return " ".join(token[0])
def operator_or(token):
token[0][1] = "|"
return " ".join(token[0])
def parse_expression(self, token):
return "".join([str(t) for t in token])
expression = 'carbo * or oxy * or nitro *'
linkers = oneOf(["and","or",], caseless=True)
keyword = oneOf(['carbo','oxy','nitro'], caseless=True).setParseAction(parse_keyword)
arguments = Optional(~linkers + delimitedList(Word(printables,excludeChars=","),combine=False)).setParseAction(parse_arguments)
selector = OneOrMore((keyword+arguments))
grammar = Forward()
grammar << selector.setParseAction(parse_expression)
grammar = operatorPrecedence(grammar, [(oneOf(["and"],caseless=True), 2, opAssoc.RIGHT , operator_and),
(oneOf(["or"] ,caseless=True), 2, opAssoc.RIGHT , operator_or)],
lpar="(",
rpar=")")
parsedExpression = grammar.transformString(expression)
差异很微妙(对我来说仍然有点不清楚),但它确实有效。
埃里克