You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用pyparsing解析存在歧义的缩进代码块?

问题

需要解析如下格式的数据:

data = """\
map=1
  sub=1
    int=99
    foo=bar
  sub=2
    foo=bar
    int=99
    bar=qux
"""

基于pyparsing的缩进语法示例编写了解析代码:

from pyparsing import *


stmt = Forward()
suite = IndentedBlock(stmt)
identifier = Word(alphas, alphanums)
key = Combine(identifier + "=" + Word(nums))
definition = key + suite

rhs = Regex(r"[a-z0-9]+")
lhs = identifier + Suppress("=") + rhs
stmt << (definition | lhs)

body = ZeroOrMore(stmt)

# 执行解析
tree = body.parse_string(input_string)
print(tree)

当前解析结果:

['map=1', ['sub=1', ['int=99', ['foo', 'bar']], 'sub=2', ['foo', 'bar', 'int=99', ['bar', 'qux']]]]

期望解析结果:

['map=1', ['sub=1', ['int', '99', 'foo', 'bar'], ['sub=2', ['foo', 'bar', 'int', '99', 'bar', 'qux']]]]

核心问题:map=1、sub=1这类带整数索引的映射定义,与int=99这类普通整数赋值语法完全一致,导致解析器误将普通整数赋值后的键值对识别为新的缩进块,如何消除该歧义?能否使用负向预查?


解决方案

要解决这个歧义,核心是明确区分“带缩进子块的映射定义”和“普通键值对”:前者后续会跟随缩进层级更深的子元素,后者则没有。以下是可行的实现方式:

方式一:用负向预查精准匹配

利用pyparsing的FollowedBy和~(负向匹配),让普通键值对仅匹配那些后续没有缩进块的场景,避免被误判为映射定义。

修改后的解析代码:

from pyparsing import *

stmt = Forward()
suite = IndentedBlock(stmt)
identifier = Word(alphas, alphanums)

# 定义带整数索引的映射键(如map=1、sub=1)
key = Combine(identifier + "=" + Word(nums))
# 映射定义:键 + 缩进子块
definition = key + suite

# 普通键值对:identifier=值(值支持字母/数字)
rhs = Regex(r"[a-z0-9]+")
# 关键:用负向匹配确保当前键值对后续没有缩进块(换行+至少1个空白符)
lhs = ~FollowedBy(LineEnd() + White(" \t", min=1)) + identifier + Suppress("=") + rhs

# 调整匹配优先级:先匹配映射定义,再匹配普通键值对
stmt << (definition | lhs)

body = ZeroOrMore(stmt)

# 测试解析
input_string = """\
map=1
  sub=1
    int=99
    foo=bar
  sub=2
    foo=bar
    int=99
    bar=qux
"""
tree = body.parse_string(input_string)
print(tree.asList())

这段代码中,~FollowedBy(LineEnd() + White(" \t", min=1))会检查当前位置之后是否是“换行+缩进”的结构,如果是,则不匹配普通键值对,确保只有真正的普通键值对(如int=99)会被lhs匹配,而带缩进子块的映射定义(如sub=1)会被definition正确识别。

方式二:通过语义动作修正结构

如果负向匹配的逻辑不好理解,也可以先按原有语法解析,再通过语义动作遍历解析树,将误判的结构修正。但这种方式需要额外的后处理步骤,不如负向匹配直接高效。


内容的提问来源于stack exchange,提问作者Soós Péter Levente

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 11:09:59