【问题标题】:Boolean expression tree with predicates?带有谓词的布尔表达式树?
【发布时间】:2021-07-23 15:53:25
【问题描述】:

我正在尝试设计一个表达式树构建器,该构建器可用于构建一个表达式树,该表达式树可以使用提供的上下文(散列图)进行延迟评估。所需的运算符集是AND/OR/NOT, <,<=,>,>=,=,!=,in_range(inclusive or not)。表达式树必须支持短路(不计算超出最终结果所需的内容)。评估结果为真或假。在我的情况下,哪些节点必须是中间节点,哪些是叶子节点?我想 AND/OR/NOT 是中间的和谓词(<,<=,>,>=,=,!=,in_range?)还是每个谓词都表示为一个子树?

【问题讨论】:

    标签: design-patterns expression-trees


    【解决方案1】:

    我最近为我的雇主做了这件事。不过,我还没有和他们谈过开源它,所以我不能给你看任何代码。不过,我可以给你一些建议。

    • 如果你有幅度比较,那么一些子表达式一定不能有布尔结果:如果你写a <= b,那么a和b是数字或字符串。你可能还需要数学,所以你可以写a <= b+1等。我的解决方案是:
      • 只有原子是叶子(a、b、1 等)
      • 解析表达式或子表达式会生成一个类型化编译的表达式对象。它要么已知会产生布尔、字符串或数字结果,要么可能产生任何结果。例如,a < b 会产生布尔结果。
      • 用作谓词的表达式无效,除非已知它会产生布尔结果。
    • 由于您将采用任意哈希图作为输入,因此您需要考虑如何处理空值。我建议您按照 SQL 的方式进行操作(已经完成了艰苦的思考),并在您的语言中添加 IS NULL 和 IS NOT NULL。

    【讨论】:

    • 谢谢。你如何处理纯布尔表达式的短路?
    • 解析表达式会返回编译后的表达式(基本上是 AST)。它有一个方法asPredicate(input) 和asValue(input),它们返回在给定输入上计算表达式的函数。您也可以使用方法evaluateAsPredicate(input) 和evaluateAsValue(input)。无论哪种方式,如果您评估a and b,而a 为假,它就不会评估b。您不会短路解析,只是评估。
    • 我还有一个问题。您如何表示树中的集合操作(​​例如交集)?我想作为每个特殊类型中间节点的子树?
    • 集合从何而来?
    • 当然,您可以拥有返回集合的子表达式。在我的实现中,有 7 种子表达式按它们已知返回的类型分类——null、布尔值、数字、字符串、列表、映射或任何。
    猜你喜欢
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多