我喜欢用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)]
答案 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。