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

如何判断pyparsing中ParseResults对应的ParserElement来源?

解决方案:给pyparsing Group的ParseResults标记原始表达式

方案一:给ParseResults添加自定义标记属性(最简单)

不用自定义子类,直接给每个Group的ParseResults加属性标记对应的生成表达式,避免子类初始化的麻烦:

  1. 定义通用的parse action生成函数,用来给结果打标记:
from pyparsing import *

def mark_parser_type(parser_identifier):
    def parse_action(s, loc, tokens):
        # 给ParseResults添加自定义属性,标记对应的ParserElement或标识名
        tokens._parser_type = parser_identifier
        return tokens
    return parse_action
  1. 给每个Group绑定这个parse action,传入对应的标识(可以是字符串,也可以直接传入ParserElement对象):
# 定义带标记的Group
first_and_operator = Group(Char('ab')('first') + Char('+-')('operator')).add_parse_action(mark_parser_type("first_and_operator"))
full_expression = Group(first_and_operator + Char('cd')('second')).add_parse_action(mark_parser_type("full_expression"))

# 测试解析
result = full_expression.parse_string('a+d', parse_all=True)
print(result[0]._parser_type)  # 输出:full_expression
print(result[0][0]._parser_type)  # 输出:first_and_operator

如果要更精确关联原始ParserElement,直接传对象即可:

first_and_operator = Group(Char('ab')('first') + Char('+-')('operator'))
first_and_operator.add_parse_action(mark_parser_type(first_and_operator))

# 后续可直接判断身份
if result[0][0]._parser_type is first_and_operator:
    print("这是first_and_operator生成的结果")

方案二:正确实现自定义TypedParseResults子类

如果一定要用自定义子类,需要修正初始化逻辑,兼容pyparsing的调用方式:

  1. 定义正确的子类,兼容父类初始化参数:
class TypedParseResults(ParseResults):
    def __init__(self, *args, result_type=None, **kwargs):
        # 先调用父类初始化
        super().__init__(*args, **kwargs)
        # 设置自定义类型标记
        self.result_type = result_type
  1. 编写转换用的parse action函数:
def convert_to_typed(result_type):
    def parse_action(s, loc, tokens):
        # 将原始ParseResults转换为自定义子类实例
        typed_result = TypedParseResults(tokens, result_type=result_type)
        # 复制所有命名结果(确保原有属性不丢失)
        for name, value in tokens.named_items():
            typed_result[name] = value
        return typed_result
    return parse_action
  1. 给Group绑定这个parse action:
first_and_operator = Group(Char('ab')('first') + Char('+-')('operator')).add_parse_action(convert_to_typed("first_and_operator"))
full_expression = Group(first_and_operator + Char('cd')('second')).add_parse_action(convert_to_typed("full_expression"))

# 测试解析
result = full_expression.parse_string('a+d', parse_all=True)
print(isinstance(result[0], TypedParseResults))  # 输出:True
print(result[0].result_type)  # 输出:full_expression

关键说明

  • 两种方案都支持CST和AST解析器独立配置:同一个Group可以在CST解析器中绑定一种标记,在AST解析器中绑定另一种,互不影响。
  • 不会和自定义Expand类冲突:parse action仅对解析结果进行标记/转换,不影响原有语法结构和Expand逻辑。
  • 扩展性强:新增Group时只需添加对应的parse action,无需修改现有代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:09:59