如何从逻辑表达式创建一个树形结构?

huangapple go评论79阅读模式
英文:

How to create a tree structure from a logical expression?

问题

Sure, here's the translation of the code-related part:

我想解析类似以下的逻辑表达式

(f = '1' OR f = '2') AND (s = '3' OR s = '4' OR s = '5') AND (t = '6')


我需要的是将这个逻辑表达式表示为表达式树的形式。最终,我想要能够创建这个数据结构的JSON表示形式,如下所示:

```json
{
    ...
    nodes: [
    {
        id: 1,
        operator: 'AND',
        operands: [
            2,
            3,
            4
        ]
    },
    {
        id: 2,
        operator: 'OR',
        operands: [
            5,
            6
        ]
    },
    {
        id: 3,
        operator: 'OR',
        operands: [
            7,
            8,
            9
        ]
    },
    leafs: [
    {
        id: 4,
        operator: '=',
        operands: [
            t,
            6
        ]
    },
    ...
}

我知道这不是数据结构的最佳表示方式,但这只是一个示例。我该如何使用类似pyparse或re的包来解决这个问题?


请注意,代码部分已被翻译,只包括有关问题的内容。如果您需要进一步的帮助或解释,请告诉我。

<details>
<summary>英文:</summary>

I want to parse a logical expression like the following:

(f = '1' OR f = '2') AND (s = '3' OR s = '4' OR s = '5') AND (t = '6')

What I need, is a representation of this logical expression in the form of a expression tree. In the end I want to be able to create a JSON representation of this data structure in the form of:

{
...
nodes: [
{
id: 1,
operator: 'AND'
operands: [
2,
3,
4
]
},
{
id: 2,
operator: 'OR'
operands: [
5,
6
]
},
{
id: 3,
operator: 'OR'
operands: [
7,
8,
9
]
},
leafs: [
{
id: 4,
operator: '='
operands: [
t,
6
]
},
...
}

I am aware that this is not the best representation of the data structure, but this is just an example.
How do I approach this problem using packages like pyparse or re?

</details>


# 答案1
**得分**: 1

我假设你的示例非常基础,而实际输入会包含嵌套。如果是这样的话,我强烈推荐使用pyparsing模块。它位于构建自己的解析器和使用正则表达式之间的中间级别。正如Ira Baxter所提到的,正则表达式不是答案,因为它无法真正处理嵌套/递归。

它具有良好的学习曲线,并具有一个称为infix_notation的惊人功能,可以处理运算符优先级、运算符结合性,并可以与一元/二元/三元运算符一起使用。例如,它可以正确地分组表达式,例如`a or b and c`,在大多数语言中(至少我所知道的那些语言)是`a or (b and c)`。

一旦你构建了你想要的表示,然后你可以使用`set_parse_action`,它基本上是一种在解析元素被解析时转换它们的方法。使用这个功能,你可以将它转换成你想要的任何输出。

这是一本关于如何使用pyparsing的好书:
https://www.oreilly.com/library/view/getting-started-with/9780596514235/

<details>
<summary>英文:</summary>

I assume your example is very basic and the real input will contain nesting. If so, I&#39;d highly recommend using pyparsing module. It&#39;s an intermediate level between building your own parser and using regex. Like Ira Baxter mentioned, regex is not the answer since it can&#39;t truly handle nesting/recursion.

It has a good learning curve and has an amazing feature called infix_notation that can handle operator precedence, operator associativity and can work with unary/binary/ternary operators. For example, it can properly group expression like `a or b and c` which in most languages (at least those that I know) is `a or (b and c)`.

Once you build a representation of what you want then you can use `set_parse_action` which is basically a way to transform the parsed elements when they are parsed. Using that you can make it into whatever output you want.

Here&#39;s a great book on how to use pyparsing:
https://www.oreilly.com/library/view/getting-started-with/9780596514235/

</details>



# 答案2
**得分**: 0

如果你的布尔表达式始终具有以下形式:A AND B AND C ...,其中A、B、C等始终具有以下形式:X OR Y OR Z,那么你可以通过简单地进行操作来实现:从括号中提取OR短语,提取AND项,并将OR短语粘合到顶级AND下方。你不应该需要比这更详细的信息。

如果你的布尔表达式可以是任意的(例如,A AND NOT (B OR NOT C AND D)),那么你将需要构建一个解析器,因为正则表达式无法跟踪嵌套的括号。可以查看我在Stack Overflow上评价很高的答案,了解如何轻松构建解析器的方法:https://stackoverflow.com/a/2336769/120163。这种方法可以轻松适应包括Python在内的任何编程语言。

那个答案链接到另一个答案,告诉你如何从解析操作中构建解析树。我认为这是你想要作为内部表示的内容。你可以使用递归访问器遍历解析树,以生成所需的JSON文本。

<details>
<summary>英文:</summary>

If your boolean expression is always of the form   A AND B AND C ....  where A B C etc. are always of the form  X OR Y OR Z, then you can do this by just hacking:  pick out the OR phrases inside the parentheses, extract the and terms, and glue the or phrases under the top level and.  You shouldn&#39;t need more detail than this.

If your boolean expressions can be arbitrary  (e.g., A AND NOT (B OR NOT C AND D), then you&#39;ll need to build a parser, because regular expressions can&#39;t keep track of nested parentheses. See my highly rated SO answer on how to build a parser easily: https://stackoverflow.com/a/2336769/120163.  The method is easily adapted to any programming language including Python.

That answer has a link to another answer that tells you how to build a parse tree from the parsing actions. This is what I think you want as an internal representation.  You can walk over the parse tree with a recursive visitor to generate the JSON text you desire.

</details>



huangapple
  • 本文由 发表于 2023年5月24日 22:36:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76324695.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定