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

如何访问TatSu解析器的parserinfo对象?

如何获取TatSu中parseinfo=True生成的解析细节

嘿,很高兴看到你已经用TatSu成功解析COBOL代码片段了!关于启用parseinfo=True后如何获取解析细节,我来给你演示几个实用的示例,帮你把这些信息用起来。

当你在调用parse()时设置parseinfo=True,TatSu会给生成的AST(抽象语法树)中的每个节点添加一个parseinfo属性,里面包含了这个节点对应的原始文本位置、匹配的规则名称、原始文本内容等关键信息。

改造你的代码来提取解析信息

我基于你的代码做了扩展,展示如何访问和打印这些解析细节:

from tatsu import parse, compile

# 更安全的文件读取方式(用with语句自动关闭文件)
with open("cobfd.bnf", "r") as cobbnf_file:
    cobbnf = cobbnf_file.read()
with open("test.cob", "r") as cobtest_file:
    cobtest = cobtest_file.read()

# 编译语法并开启解析信息收集
model = compile(cobbnf, "cobol")
ast = model.parse(cobtest, parseinfo=True, trace=False)

# 示例1:直接访问单个AST节点的解析信息
# 注意:这里的节点名称(比如'identification_division')需要和你的BNF规则对应
if hasattr(ast, 'identification_division'):
    div_parseinfo = ast.identification_division.parseinfo
    print("=== 单个节点解析信息 ===")
    print(f"匹配的规则名称: {div_parseinfo.rule}")
    print(f"起始位置: 第{div_parseinfo.start[0]}行,第{div_parseinfo.start[1]}列")
    print(f"结束位置: 第{div_parseinfo.end[0]}行,第{div_parseinfo.end[1]}列")
    print(f"匹配的原始文本:\n{div_parseinfo.text}\n")

# 示例2:递归遍历所有AST节点,打印所有解析信息
def traverse_parseinfo(node, indent=0):
    indent_str = "  " * indent
    # 检查当前节点是否有解析信息
    if hasattr(node, 'parseinfo'):
        info = node.parseinfo
        print(f"{indent_str}▶️ 规则: {info.rule}")
        print(f"{indent_str}  位置: {info.start} → {info.end}")
        print(f"{indent_str}  文本片段:\n{indent_str}    {info.text.strip().replace('\n', f'\n{indent_str}    ')}")
        print(f"{indent_str}------------------------")
    
    # 递归遍历子节点(处理对象和列表类型的子节点)
    for attr_name in dir(node):
        # 跳过私有属性和方法
        if attr_name.startswith('_'):
            continue
        attr_value = getattr(node, attr_name)
        # 如果是列表/元组,遍历每个元素
        if isinstance(attr_value, (list, tuple)):
            for item in attr_value:
                if hasattr(item, '__dict__'):  # 判断是否是TatSu生成的AST节点
                    traverse_parseinfo(item, indent + 1)
        # 如果是单个对象节点
        elif hasattr(attr_value, '__dict__'):
            traverse_parseinfo(attr_value, indent + 1)

# 调用遍历函数
print("=== 所有AST节点的解析信息 ===")
traverse_parseinfo(ast)

关键说明

  1. 节点名称对应:示例中的identification_division是COBOL常见的规则节点,你需要根据自己的cobfd.bnf中的规则名称来替换这个节点名,否则会找不到对应的属性。
  2. parseinfo的属性:每个parseinfo对象包含这些核心字段:
    • rule: 匹配当前节点的BNF规则名称
    • start: 元组(行号, 列号),对应原始文本中节点的起始位置
    • end: 元组(行号, 列号),对应原始文本中节点的结束位置
    • text: 匹配当前节点的原始文本内容
  3. 递归遍历:示例中的traverse_parseinfo函数可以帮你遍历整个AST结构,不管你的BNF嵌套多深,都能打印出所有带解析信息的节点。

如果你的BNF中有一些匿名规则或者用了skip指令,这些部分不会生成带parseinfo的节点,这是正常的,只有那些生成AST节点的规则才会包含解析信息。

内容的提问来源于stack exchange,提问作者dreamer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 00:02:45