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

如何用pyparsing库解析含隐式AND的可选运算符?

解析含隐式AND的布尔表达式问题

需要解析类似alpha OR beta gamma的字符串,其中相邻术语(如beta和gamma)之间的缺失运算符为隐式AND。现有代码使用pyparsing实现,但无法识别隐式AND,当前输入alpha OR beta gamma的输出仅为[BinaryOp(OR, Term(alpha), Term(beta))],遗漏了gamma和隐式AND。

原有代码:

import pyparsing as pp


class Term:
    def __init__(self, tokens: pp.ParseResults):
        self.value = str(tokens[0])

    def __repr__(self) -> str:
        return f"Term({self.value})"


class BinaryOp:
    def __init__(self, tokens: pp.ParseResults) -> None:
        self.op = tokens[0][1]
        self.left = tokens[0][0]
        self.right = tokens[0][2]

    def __repr__(self) -> str:
        return f"BinaryOp({self.op}, {self.left}, {self.right})"


and_ = pp.Keyword("AND")
or_ = pp.Keyword("OR")
word = (~(and_ | or_) + pp.Word(pp.alphanums + pp.alphas8bit + "_")).set_parse_action(Term)

expression = pp.infix_notation(
    word,
    [
        (pp.Optional(and_), 2, pp.opAssoc.LEFT, BinaryOp),
        (or_, 2, pp.opAssoc.LEFT, BinaryOp),
    ],
)

input_string = "alpha OR beta gamma"
parsed_result = expression.parseString(input_string)
print(parsed_result.asList())

解决方案

问题核心是pp.Optional(and_)无法匹配无显式运算符的相邻术语,需要调整运算符定义,用pp.Empty()表示隐式AND,同时明确运算符优先级(AND优先级高于OR)。

修改后的代码:

import pyparsing as pp


class Term:
    def __init__(self, tokens: pp.ParseResults):
        self.value = str(tokens[0])

    def __repr__(self) -> str:
        return f"Term({self.value})"


class BinaryOp:
    def __init__(self, tokens: pp.ParseResults) -> None:
        # 处理隐式AND:无显式运算符时默认设为"AND"
        tokens_list = tokens[0]
        if len(tokens_list) == 2:
            self.op = "AND"
            self.left = tokens_list[0]
            self.right = tokens_list[1]
        else:
            self.op = tokens_list[1]
            self.left = tokens_list[0]
            self.right = tokens_list[2]

    def __repr__(self) -> str:
        return f"BinaryOp({self.op}, {self.left}, {self.right})"


and_ = pp.Keyword("AND")
or_ = pp.Keyword("OR")
word = (~(and_ | or_) + pp.Word(pp.alphanums + pp.alphas8bit + "_")).set_parse_action(Term)

expression = pp.infix_notation(
    word,
    [
        # 先处理显式AND和隐式AND(用pp.Empty()匹配无运算符的相邻术语)
        ((and_ | pp.Empty()), 2, pp.opAssoc.LEFT, BinaryOp),
        # OR优先级低于AND,后处理
        (or_, 2, pp.opAssoc.LEFT, BinaryOp),
    ],
)

input_string = "alpha OR beta gamma"
parsed_result = expression.parseString(input_string)
print(parsed_result.asList())

关键改动说明

  1. BinaryOp逻辑调整:增加对隐式AND的判断,当解析结果只有左右两个Term时,自动将运算符设为AND;
  2. 运算符优先级排序:将AND类运算符(显式+隐式)放在OR前面,符合布尔表达式的运算优先级规则;
  3. 隐式AND匹配:用pp.Empty()匹配两个Term直接相连的场景,触发BinaryOp解析。

运行修改后的代码,输入alpha OR beta gamma的输出为:
[BinaryOp(OR, Term(alpha), BinaryOp(AND, Term(beta), Term(gamma)))],完全符合预期。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 08:24:59