我正在尝试递归解析一个表达式。我看了一些教程,看起来Forward()是我需要的类。然而,一些看似简单的东西却给我带来了麻烦。
这是我写的代码
from pyparsing import *
exp = Forward()
integer = Word(nums)
exp << (integer | (exp + '+' + exp))
input = "1+1"
print exp.parseString(input)
我希望它返回['1','+','1']
,但它只返回['1']
非常感谢帮助。
2条答案
按热度按时间mpgws1up1#
你现在有几个问题。按重要性升序排列:
1.如果在解析的内容之后有额外的文本,parseString将不会引发异常。
1.“|“”是MatchFirst,而不是MatchLongest。由于您的整数是第一个,因此将首先匹配该整数。然后,分析器将自动在“+”上失败。如果希望匹配最长时间,请使用“^”运算符。
1.大人物:转换为“^”后(或者重新排序表达式,把
exp + exp
放在整数前面),你会发现自己放大了最大递归深度,这是因为这个解析器有exp
的左递归定义,也就是说,要解析一个exp
,它必须解析一个exp
,它必须解析一个exp
,等等。许多已发布的BNF使用递归来描述这种重复的结构,但是pyparser并不做必要的前视/后视。尝试exp <<= integer + ZeroOrMore('+' + integer) | '(' + exp + ')'
-这个表达式是 not left-recursive,因为在解析嵌套的exp
之前,您必须越过一个左括号。编辑:对不起,我之前的建议有点太快了,下面是正确的递归表达式解析方法:
印刷品
如果你跟踪代码,你会看到递归:
exp
使用term
定义,term
使用exp
定义。fourFn.py
示例最接近这种样式;在写了这篇文章之后,我在pyparser中添加了infixNotation
方法,它允许您编写:infixNotation
在内部负责递归定义,隐式定义'(' + exp + ')'
表达式,并使实现具有运算优先级的运算符系统变得容易。rdrgkggo2#
我最近遇到了这个问题,现在PyParsing 3.0.0b2以上支持左递归,但需要显式启用,
|
操作符的操作数顺序需要调整如下。这将输出以下内容。