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