嗨,我知道如何解析表达式(包括括号)。 但通常解析表达式假定为“操作数运算符操作数”。 F.E. :
5 + 12
( 5 * 6 ) + 11
( 3 + 4 ) + ( 5 * 2)
正如您所看到的,值总是两个。 我正在寻找的是机制(语法),而不是将类似运算符的链解析为单个项,即贪婪 F.E.假设我有以下表达式:
5 + 4 + 2 + 7 * 6 * 2
=> sum(5 + 4 + 2)
+
=> mult(7 * 6 * 2)
我希望解析器将总和作为单个“动作”吞噬,对于乘法也是如此。
以下是非工作语法的一个示例,但也许您可以了解我想要做的事情(python - LEPL模块):
def build_grammar2(self):
spaces = Token('[ \t]+')[:]
plus = Token('\+')
left_bracket = Token('\(')
right_bracket = Token('\)')
mult = Token('\*')
bit_var = Token('[a-zA-Z0-9_!\?]+')
# with Separator(~spaces):
expr, group2 = Delayed(), Delayed()
mul_node = bit_var & (~mult & bit_var)[1:] > Node
add_node = bit_var & (~plus & bit_var)[1:] > Node
node = mul_node | add_node
parens = ~left_bracket & expr & ~right_bracket
group1 = parens | node
add = group1 & ~plus & group2 > Node
group2 += group1 | add
mul = group2 & ~mult & expr > Node
expr += group2 | mul
self.grammar = expr
答案 0 :(得分:0)
这几乎是你通过pyparsing得到的:
import pyparsing as pp
add_op = pp.oneOf("+ -")
mul_op = pp.oneOf("* /")
operand = pp.pyparsing_common.number | pp.pyparsing_common.identifier
arith = pp.infixNotation(operand,
[
("-", 1, pp.opAssoc.RIGHT),
(mul_op, 2, pp.opAssoc.LEFT),
(add_op, 2, pp.opAssoc.LEFT),
])
print(arith.parseString("1+2-3+X*-7*6+Y*(3+2)").asList())
打印
[[1, '+', 2, '-', 3, '+', ['X', '*', ['-', 7], '*', 6], '+', ['Y', '*', [3, '+', 2]]]]
如果您只是解析数字,您可以通过向每个优先级别添加解析操作来使解析器也执行解析时间eval(pp.pyparsing_common.number
自动将数字字符串转换为int或float):
operand = pp.pyparsing_common.number
op_fn = {
'*': lambda a,b: a*b,
'/': lambda a,b: a/b,
'+': lambda a,b: a+b,
'-': lambda a,b: a-b,
}.get
def binop(t):
t_iter = iter(t[0])
ret = next(t_iter)
for op, val in zip(t_iter, t_iter):
ret = op_fn(op)(ret, val)
return ret
arith = pp.infixNotation(operand,
[
("-", 1, pp.opAssoc.RIGHT, lambda t: -t[1]),
(mul_op, 2, pp.opAssoc.LEFT, binop),
(add_op, 2, pp.opAssoc.LEFT, binop),
])
print(arith.parseString("1+2-3+8*-7*6+4*(3+2)"))
打印:
[-316]