pyparsing的indentedBlock递归使用示例

10 投票
1 回答
1102 浏览
提问于 2025-04-17 19:08

我正在尝试使用 indentedBlock 这个功能,它在 pyparsing 中看起来非常不错,来处理一些嵌套的缩进问题。不过,我在理解它的 API 参考文档时遇到了一些困难,尤其是那些具体的例子,比如在 http://pyparsing.wikispaces.com 或者在 如何用 pyparsing 解析缩进和去缩进? 这篇文章中提到的内容。

有人能给我指个明路,或者在这里提供一个简单的演示,教我如何递归使用 indentedBlock 吗?比如,我们如何把一些类似 YAML 的内容...

- a1_el
    - b1_el
        x1_attr: 1
        x2_attr: 2
    - b2_el
        - c1_el # I am a comment
    - b3_el
        x1_attr: 1 

...转换成一些 XML 表示形式,比如...

<a1_el>
    <b1_el x1_attr="1" x2_attr="2"/>
    <b2_el>
        <c1_el/><!-- I am a comment -->
    </b2_el>
    <b3_el x1_attr="1"/>
</a1_el>

...使用 indentedBlock 来实现?(还有:在什么实际情况下我需要 indentStack 参数的不同选项?)非常感谢!

1 个回答

6

这段内容有点老旧,不过我来给你简单说一下:

from pyparsing import *

COMMENT   = pythonStyleComment
OPCOMMENT = Optional(COMMENT)
IDENT     = Word(alphas, alphanums + '_')

attribute    = IDENT + Suppress(':') + Word(alphanums) + OPCOMMENT
element      = Suppress('-') + IDENT + OPCOMMENT
elementBlock = Forward()
blockContent = attribute|elementBlock|COMMENT
elementBlock << element + Optional(indentedBlock(blockContent, [1]))

我假设元素可以包含属性和其他元素,而且顺序可以随意。elementBlock 会解析整个树状结构。

这里展示了如何使用 indentedBlock,简单来说,它不允许在树外写注释,并且只接受一个根元素(对于XML来说这没问题...)

关于 indentStack:它记录了当前缩进的层级数量,列表中的最后一个元素表示当前的缩进列。文档提到,所有使用缩进的嵌套块的语法都应该共享同一个列表。因为只有一个,所以我直接在调用 indentedBlock 时创建了它。

把结果转换成XML的部分就留给你自己练习啦 :-P

撰写回答