如何在pyparsing的parseAction中获取命名解析结果字段值
问题背景
类中定义了如下pyparsing解析规则,需要在解析完成后,将匹配到的变量类型、变量名、变量值传入自定义处理函数takeval:
def takeval(type, name, value): # 自定义处理逻辑 self.variable = pp.Optional(self.let_ | self.const_ | self.var_).set_results_name('vartype') ^ self.varname ^ self.set_ ^ self.object # 期望绑定解析回调 self.variable = self.variable.setParseAction(takeval(vartype, varname, object))
取值规则要求:
vartype取self.let_、self.const_、self.var_三者中实际匹配到的结果varname取self.varname的匹配结果object取self.object的匹配结果
解析字符串const hi = "hello"时,期望传入takeval的三个参数为'const'、'hi'、'hello'。
实现方案
原写法无法生效的核心原因有两点:
- 直接调用
takeval(...)会在规则定义阶段立即执行,不会在解析完成后触发,且此时三个参数还未生成解析值 - 未给
varname、object匹配段设置结果名,解析完成后无法直接定位对应段的结果
按如下步骤修改即可:
- 给所有需要取值的匹配段设置明确的
results_name,匹配等号的self.set_如果不需要保留结果,可以直接加.suppress()跳过 - 给
setParseAction传入一个可调用的回调函数,回调接收pyparsing传入的tokens结果对象,按结果名取出对应值后再传入takeval - 原规则中使用的
^是最长匹配Or操作符,变量定义是固定顺序的语法结构,替换为按顺序匹配的+(And操作符)性能更好,也能避免不必要的匹配歧义,如果确实需要最长匹配逻辑可保留^
修改后的可运行示例代码:
import pyparsing as pp # 以下基础规则可替换为你类中已有的实际定义 self.let_ = pp.Keyword("let") self.const_ = pp.Keyword("const") self.var_ = pp.Keyword("var") # 给需要取值的段设置结果名 self.varname = pp.Word(pp.identchars, pp.identbodychars).set_results_name("varname") self.set_ = pp.Literal("=").suppress() # 等号不需要保留,直接抑制输出 self.object = pp.quotedString.add_parse_action(pp.removeQuotes).set_results_name("varvalue") def takeval(type_val, name, value): # 替换为你自己的处理逻辑 print(f"解析结果: 类型={type_val}, 变量名={name}, 值={value}") # 组装解析规则 self.variable = ( pp.Optional(self.let_ | self.const_ | self.var_).set_results_name('vartype') + self.varname + self.set_ + self.object ) # 定义解析回调 def var_parse_callback(tokens): # 未匹配到类型关键字时可自定义默认值 vartype = tokens.vartype if "vartype" in tokens else None varname = tokens.varname varvalue = tokens.varvalue takeval(vartype, varname, varvalue) # 绑定回调 self.variable = self.variable.set_parse_action(var_parse_callback) # 测试解析 self.variable.parse_string('const hi = "hello"')
运行测试代码后输出为解析结果: 类型=const, 变量名=hi, 值=hello,符合预期效果。
内容的提问来源于stack exchange,提问作者thatrandomperson
相关产品推荐
相关产品推荐

