3

我喜欢定义parseActionwith的能力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)]
4

1 回答 1

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。

于 2012-07-06T02:30:44.097 回答