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

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

How to create a tree structure from a logical expression?

问题

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

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

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

  1. 我需要的是将这个逻辑表达式表示为表达式树的形式。最终,我想要能够创建这个数据结构的JSON表示形式,如下所示:
  2. ```json
  3. {
  4. ...
  5. nodes: [
  6. {
  7. id: 1,
  8. operator: 'AND',
  9. operands: [
  10. 2,
  11. 3,
  12. 4
  13. ]
  14. },
  15. {
  16. id: 2,
  17. operator: 'OR',
  18. operands: [
  19. 5,
  20. 6
  21. ]
  22. },
  23. {
  24. id: 3,
  25. operator: 'OR',
  26. operands: [
  27. 7,
  28. 8,
  29. 9
  30. ]
  31. },
  32. leafs: [
  33. {
  34. id: 4,
  35. operator: '=',
  36. operands: [
  37. t,
  38. 6
  39. ]
  40. },
  41. ...
  42. }

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

  1. 请注意,代码部分已被翻译,只包括有关问题的内容。如果您需要进一步的帮助或解释,请告诉我。
  2. <details>
  3. <summary>英文:</summary>
  4. 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')

  1. 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
]
},
...
}

  1. I am aware that this is not the best representation of the data structure, but this is just an example.
  2. How do I approach this problem using packages like pyparse or re?
  3. </details>
  4. # 答案1
  5. **得分**: 1
  6. 我假设你的示例非常基础,而实际输入会包含嵌套。如果是这样的话,我强烈推荐使用pyparsing模块。它位于构建自己的解析器和使用正则表达式之间的中间级别。正如Ira Baxter所提到的,正则表达式不是答案,因为它无法真正处理嵌套/递归。
  7. 它具有良好的学习曲线,并具有一个称为infix_notation的惊人功能,可以处理运算符优先级、运算符结合性,并可以与一元/二元/三元运算符一起使用。例如,它可以正确地分组表达式,例如`a or b and c`,在大多数语言中(至少我所知道的那些语言)是`a or (b and c)`
  8. 一旦你构建了你想要的表示,然后你可以使用`set_parse_action`,它基本上是一种在解析元素被解析时转换它们的方法。使用这个功能,你可以将它转换成你想要的任何输出。
  9. 这是一本关于如何使用pyparsing的好书:
  10. https://www.oreilly.com/library/view/getting-started-with/9780596514235/
  11. <details>
  12. <summary>英文:</summary>
  13. 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.
  14. 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)`.
  15. 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.
  16. Here&#39;s a great book on how to use pyparsing:
  17. https://www.oreilly.com/library/view/getting-started-with/9780596514235/
  18. </details>
  19. # 答案2
  20. **得分**: 0
  21. 如果你的布尔表达式始终具有以下形式:A AND B AND C ...,其中ABC等始终具有以下形式:X OR Y OR Z,那么你可以通过简单地进行操作来实现:从括号中提取OR短语,提取AND项,并将OR短语粘合到顶级AND下方。你不应该需要比这更详细的信息。
  22. 如果你的布尔表达式可以是任意的(例如,A AND NOT (B OR NOT C AND D)),那么你将需要构建一个解析器,因为正则表达式无法跟踪嵌套的括号。可以查看我在Stack Overflow上评价很高的答案,了解如何轻松构建解析器的方法:https://stackoverflow.com/a/2336769/120163。这种方法可以轻松适应包括Python在内的任何编程语言。
  23. 那个答案链接到另一个答案,告诉你如何从解析操作中构建解析树。我认为这是你想要作为内部表示的内容。你可以使用递归访问器遍历解析树,以生成所需的JSON文本。
  24. <details>
  25. <summary>英文:</summary>
  26. 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.
  27. 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.
  28. 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.
  29. </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:

确定