pyparsing是否在分析时知道递归表达式的深度?

时间:2012-07-06 01:18:08

标签: python recursion pyparsing

我喜欢用parseAction定义pyarsing的能力,但我遇到了特定用例的障碍。取输入字符串和以下简单语法:

from pyparsing import *

line = "[[one [two [three] two [three [four]]] one] zero]"
token = Word(alphas)

# Define the simple recursive grammar
grammar = Forward()
nestedBrackets = nestedExpr('[', ']', content=grammar) 
grammar << (token | nestedBrackets)

P = grammar.parseString(line)
print P

我希望结果如下:

[('one',1), [('two',2), [('three',3)], ('two',2), [('three',3), [('four',4)]]] one], ('zero',0)]

即解析每个token并返回一个带有令牌和深度的元组。我知道这可以在解析后完成,但我想知道是否可以使用parseAction。这是我对全局变量的不正确尝试:

# Try to count the depth
counter = 0
def action_token(x):
    global counter
    counter += 1
    return (x[0],counter)
token.setParseAction(action_token)

def action_nest(x):
    global counter
    counter -= 1
    return x[0]
nestedBrackets.setParseAction(action_nest)

,并提供:

[('one', 1), ('two', 2), ('three', 3), ('two', 3), ('three', 4), ('four', 5), ('one', 3), ('zero', 3)]

1 个答案:

答案 0 :(得分:4)

这样做(剩下的就是你所拥有的):

def openB(s, l, t):
    global count
    count += 1
def closeB(s, l, t):
    global count
    count -= 1

opener = Literal("[").setParseAction(openB)
closer = Literal("]").setParseAction(closeB)

nestedBrackets = nestedExpr(opener, closer, content=grammar) 

问题在于嵌套不取决于匹配的嵌套的数量,而是取决于匹配的开括号的数量与匹配的闭括号的数量。因此,您需要在解析打开/关闭括号时调整计数,而不是在解析组时。因此,您需要在组分隔符上设置parseAction,而不是组本身。

此外,你的例子有一个级别的嵌套(至少我的眼睛)。 '零'应该是一个,因为它在括号的一个级别内,同样其他一切都应该向上移动一个。如果你真的希望最外面的“零”具有零级等等,你需要初始化count到-1。