我试图以递归方式解析表达式。我按照了几个教程,看起来像Forward()是我需要的类。然而,看似简单的事情给我带来了麻烦。
这是我写的代码
from pyparsing import *
exp = Forward()
integer = Word(nums)
exp << (integer | (exp + '+' + exp))
input = "1+1"
print exp.parseString(input)
我希望它返回['1','+','1']
但它只返回['1']
非常感谢帮助。
答案 0 :(得分:0)
这里有几个问题。按重要性递增顺序:
exp.parseString(input, parseAll=True)
exp + exp
首先放在整数之前),你会发现自己炸掉了最大的递归深度。那是因为这个解析器具有exp
的左递归定义。也就是说,要解析exp
,它必须解析exp
,它必须解析exp
等。通常,许多已发布的BNF使用递归来描述这种类型重复结构,但pyparsing没有做必要的前瞻/回溯工作。试试exp <<= integer + ZeroOrMore('+' + integer) | '(' + exp + ')'
- 这个表达式不是左递归的,因为在解析嵌套的exp
之前你必须经过一个左括号。编辑: 对不起,我之前的建议有点太快了,这是进行递归表达式解析的正确方法:
from pyparsing import *
exp = Forward()
LPAR, RPAR = map(Suppress, "()")
integer = Word(nums)
term = integer | Group(LPAR + exp + RPAR)
exp << term + ZeroOrMore('+' + term)
input = "(1+1) + 1"
print(exp.parseString(input))
打印
[['1', '+', '1'], '+', '1']
如果您浏览代码,则会看到递归:exp
使用term
定义,term
使用exp
定义。 fourFn.py
示例最接近此样式;自写这篇文章以来,我已经将infixNotation
方法添加到pyparsing中,这将允许你写:
exp = infixNotation(integer, [
('+', 2, opAssoc.LEFT),
])
infixNotation
在内部处理递归定义,隐式定义'(' + exp + ')'
表达式,并且可以轻松实现具有操作优先级的运算符系统。