这是一个 pyparsing 解决方案,它使用自修改语法来动态匹配正确的右大括号字符。
from pyparsing import *
data = '(gimme [some {nested, nested [lists]}])'
opening = oneOf("( { [")
nonBracePrintables = ''.join(c for c in printables if c not in '(){}[]')
closingFor = dict(zip("({[",")}]"))
closing = Forward()
# initialize closing with an expression
closing << NoMatch()
closingStack = []
def pushClosing(t):
closingStack.append(closing.expr)
closing << Literal( closingFor[t[0]] )
def popClosing():
closing << closingStack.pop()
opening.setParseAction(pushClosing)
closing.setParseAction(popClosing)
matchedNesting = nestedExpr( opening, closing, Word(alphas) | Word(nonBracePrintables) )
print matchedNesting.parseString(data).asList()
印刷:
[['gimme', ['some', ['nested', ',', 'nested', ['lists']]]]]
更新:我发布了上述解决方案,因为我实际上是在一年前写的,作为一个实验。我只是仔细查看了您的原始帖子,它让我想到了该operatorPrecedence
方法创建的递归类型定义,因此我使用您的原始方法重新编写了这个解决方案 - 更容易遵循!(虽然右输入数据可能存在左递归问题,但未经彻底测试):
from pyparsing import *
enclosed = Forward()
nestedParens = nestedExpr('(', ')', content=enclosed)
nestedBrackets = nestedExpr('[', ']', content=enclosed)
nestedCurlies = nestedExpr('{', '}', content=enclosed)
enclosed << (Word(alphas) | ',' | nestedParens | nestedBrackets | nestedCurlies)
data = '(gimme [some {nested, nested [lists]}])'
print enclosed.parseString(data).asList()
给出:
[['gimme', ['some', ['nested', ',', 'nested', ['lists']]]]]
编辑:这是更新解析器的图表,使用 pyparsing 3.0 中的铁路图表支持。