Data structures 使用链式比较运算符计算二叉表达式树

Data structures 使用链式比较运算符计算二叉表达式树,data-structures,compiler-construction,tree,bison,Data Structures,Compiler Construction,Tree,Bison,我正在构建一个二进制表达式树(用于一种玩具脚本语言),到目前为止,我的算术运算运行良好(即4*(5+6));现在我想添加对比较运算符的支持。这对于像0

我正在构建一个二进制表达式树(用于一种玩具脚本语言),到目前为止,我的算术运算运行良好(即
4*(5+6)
);现在我想添加对比较运算符的支持。这对于像
0<1
这样的简单二进制比较非常容易做到,但是当我将它们链接在一起时,我遇到了问题。例如,此表达式:

0 < 1 < 2
0<1<2
当前生成以下二进制表达式树:

    <
   / \
  <   2
 / \
0   1
<
/ \
<   2
/ \
0   1
我使用递归遍历树到叶节点并返回返回值,因此
0<1
首先得到处理,它(正确地)返回一个True。问题是下一个级别将比较
True<2
,而它应该比较
True&(1<2)

解决这个问题的最好方法是什么?我在想,我可能最终不得不以不同的方式构建我的树。i、 e

       &&
      /  \
     /    \
    <      <
   / \    / \
  0   1  1   2
&&
/  \
/    \
<      <
/ \    / \
0   1  1   2

但我希望在我的bison解析器解决方案中实现一个更优雅/稍微不复杂的方法。

本质上,一系列链式比较是一个单独的运算符,而不是一系列二进制运算符。将
a
分解为
(a
是不精确的,因为它计算
b
两次。所以,如果AST允许的话,您可以将其解压缩到一个n元运算符

如果您有一个区分的并集类型,您还可以使它与一系列二进制运算符一起工作。在这种情况下,一个非常简单的歧视性联盟就足够了

T
为值为
false
或任意整数的类型。(此处,
false
不同于任何整数,因此它与
0
不同)


现在,我们定义
您真的想要这个吗?因为用户可能会依赖它类似于C++等的工作(例如,你的缩写会打断其他事情)@ DeavangFe:可能用户认为它与Python类似。这个问题与C++有关?@斯拉瓦:我把它包含进去了,因为我的项目是用C++编写的。不过,你可能是对的,这与问题无关——我将删除标记。这与使布尔值成为可以比较的第一类类型有着不好的交互作用——类似于
(a<5)==(b>3)
变得很难计算…@chrisdd:除了链式比较,在任何上下文中都有必要将T转换为布尔值。但这与任何其他隐性胁迫都没有区别。与python一样,
(a<5)==(b<3)
a<5==b<3
integer a < integer b ==> T
  if a is less than b, then b; otherwise false

T a < integer b ==> T
  if a is false, then false; otherwise a < b (as above)
a < b == c < d      # Chained comparison
(a < b) == (c < d)  # Comparison of two booleans