Python 使用pyparsing将列表与已解析的逻辑表达式进行比较

Python 使用pyparsing将列表与已解析的逻辑表达式进行比较,python,pyparsing,Python,Pyparsing,我试图使用pyparsing来解析逻辑表达式,然后将输入列表与该表达式进行比较 表达式匹配对象上的标记(单词)组。因此,表达形式如下: 这个和那个或现在 (这个或那个)那里或这里和(现在或那时) 我能够将表达式解析为中缀列表: import pyparsing as pp identifier = pp.Word(pp.alphanums + "_" + "-" + "'") expr = pp.infixNotation(identifier, [ ("AND", 2, p

我试图使用pyparsing来解析逻辑表达式,然后将输入列表与该表达式进行比较

表达式匹配对象上的标记(单词)组。因此,表达形式如下:

  • 这个和那个或现在
  • (这个或那个)那里或这里和(现在或那时)
我能够将表达式解析为中缀列表:

import pyparsing as pp   

identifier = pp.Word(pp.alphanums + "_" + "-" + "'")
expr = pp.infixNotation(identifier, [
    ("AND", 2, pp.opAssoc.LEFT,),
    ("OR", 2, pp.opAssoc.LEFT,),
])
result = expr.parseString(expression)
这将导致以下结果(对于给出的第二个示例):

此时,我想比较标记列表,并确定需要将哪些标记添加到我的标记列表中才能使表达式有效

因此,对于第二个示例,如果我的标记列表是
['this','now']
,我需要计算出
'there'
'here'
需要添加到列表中才能使表达式有效

我不知道从哪里开始。我想我需要某种递归函数来遍历这些项,同时跟踪什么是OR项,什么是and项,因为这会影响从列表中找出缺少什么的逻辑

编辑:更新

根据到目前为止的反馈,我已经为AND或terms设置了一些解析操作。这适用于像
(This或that)和there
这样的简单情况,但无法处理更复杂的表达式,因为对于这些表达式,有不同的标记组可以满足表达式(即,表达式的一个或在其基础上),如
(This或that)和there或here和there(now或then)
。有人能帮我扩展这些解析操作来满足这个需求吗

def test(expression, tags):

    required_tags = []
    optional_tags = []

    def parse_and(tokens):
        args = tokens[0][0::2]
        extend_list = filter(lambda x: isinstance(x, str) and x not in tags, args)
        required_tags.extend(extend_list)

    def parse_or(tokens):
        args = tokens[0][0::2]
        append_list = filter(lambda x: isinstance(x, str) and x not in tags, args)
        if append_list == args:
            optional_tags.append(tuple(append_list))

    identifier = Word(alphanums + "_" + "-" + "'")

    expr = infixNotation(identifier, [
        ("AND", 2, opAssoc.LEFT, parse_and),
        ("OR", 2, opAssoc.LEFT, parse_or),
    ])

    expr.parseString(expression)

    return required_tags, optional_tags

与其直接浏览and和or的嵌套结构,不如让pyparsing构建一个可评估类的结构——请参见pyparsing wiki()上的simpleBool.py示例中的操作方法。这些实例将用于跟踪and和or。然后将逻辑添加到这些类中,根据给定的操作数列表解析使用的操作数,返回缺少的项列表(在And和Not的情况下)或替代项列表(在or的情况下)。最后,编写代码,智能地合并这些返回值(并非微不足道)。@PaulMcGuire谢谢。我已经构建了一些基本的解析操作,这些操作涵盖了一些简单的表达式案例。不过,我就是不知道从这里该做什么。先做简单的部分——先忘掉OR,然后开始工作。如果您解析
“x、y和z”
,那么您将得到一个
parse_和
节点,告诉您“x”、“y”和“z”都应该在您的输入列表中。因此,求值函数应该获取给定标记的列表,然后查看and中引用的所有标记是否都存在。然后分析
“x和(y和z)”
,并查看括号如何影响您的设计。然后,考虑<代码>“X或Y”< /代码>。根据您在和方面的经验,仔细考虑如何处理此案例。使用
“x和y或z”
,事情会变得棘手,但首先要向其他人学习。哦,
parse_和
parse_和
parse_或
可能会更好,因为类
ParseAnd和
ParseOr
,有一个
\uuu init\uu
方法,它会接受匹配的标记。然后可以将适当的方法附加到这些类。这太多了,不可能在每一个级别都放在一个单独的解析操作中。
def test(expression, tags):

    required_tags = []
    optional_tags = []

    def parse_and(tokens):
        args = tokens[0][0::2]
        extend_list = filter(lambda x: isinstance(x, str) and x not in tags, args)
        required_tags.extend(extend_list)

    def parse_or(tokens):
        args = tokens[0][0::2]
        append_list = filter(lambda x: isinstance(x, str) and x not in tags, args)
        if append_list == args:
            optional_tags.append(tuple(append_list))

    identifier = Word(alphanums + "_" + "-" + "'")

    expr = infixNotation(identifier, [
        ("AND", 2, opAssoc.LEFT, parse_and),
        ("OR", 2, opAssoc.LEFT, parse_or),
    ])

    expr.parseString(expression)

    return required_tags, optional_tags