英文:
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'd highly recommend using pyparsing module. It's an intermediate level between building your own parser and using regex. Like Ira Baxter mentioned, regex is not the answer since it can'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'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'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'll need to build a parser, because regular expressions can'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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论