C# 准备语法树(ast)以轻松执行短路操作
准备包含条件的语法树的最佳方法是什么,以方便快捷地使用C# 准备语法树(ast)以轻松执行短路操作,c#,syntax,compiler-construction,abstract-syntax-tree,short-circuiting,C#,Syntax,Compiler Construction,Abstract Syntax Tree,Short Circuiting,准备包含条件的语法树的最佳方法是什么,以方便快捷地使用short curcuit 一般来说,短路的规则非常简单: 如果和块中的一个组件返回false,则整个块将返回false,可以退出执行 如果或块中的一个组件返回true,则整个块将返回true,并且可以退出执行 因此,例如,这个简单语句将按照以下语法树计算1=0和1=1: and / \ = = / \ / \ 1 0 1 1 在这种情况下很容易。执行树(
short curcuit
一般来说,短路
的规则非常简单:
和块中的一个组件返回false,则整个块将返回false,可以退出执行
或块中的一个组件返回true,则整个块将返回true,并且可以退出执行
1=0和1=1
:
and
/ \
= =
/ \ / \
1 0 1 1
在这种情况下很容易。执行树(分支)的第一部分后,
执行将退出,它只能返回false。但是如果树长得更多
复杂的是,必须有一种更有效的方法。还是这已经是最重要的
有效的方法
例如,在这种情况下,c#
编译器如何评估语法树
编辑
如果true
或false
不可能,我是否应该将所有条件写在一个简单的列表中,并分支到末尾?这样我就没有了和和或部分了
非常感谢大家 您对短路的定义与C#和其他语言的定义不太匹配。在大多数(可能是所有)具有短路的语言中,行为仅取决于左操作数的值,即:
left&&right
始终计算left
,并且仅在left
为真时计算right
left | | right
始终计算left
并且仅在left
为false时计算right
因此,语言规则保证永远不会首先尝试正确的操作数,即使编译器可能认为首先尝试正确的操作数会更有效。这样您就知道list==null | | list.IsEmpty()
永远不会抛出null指针异常
因此,为了回答您的问题,编译器不会生成比“计算左操作数,然后仅在必要时计算右操作数”更高效的代码,因为任何其他代码都会破坏语言规则
PS:理论上,如果编译器能够证明操作数没有任何副作用,那么它就有可能对操作数进行重新排序,但据我所知,这是不可能的。无论哪种方式,这都不会在AST级别发生
PPS:C#编译器不计算AST,而是从中生成代码。这是一个编译器,而不是解释器。你对短路的定义与C#和其他语言的定义不太相符。在大多数(可能是所有)具有短路的语言中,行为仅取决于左操作数的值,即:
left&&right
始终计算left
,并且仅在left
为真时计算right
left | | right
始终计算left
并且仅在left
为false时计算right
因此,语言规则保证永远不会首先尝试正确的操作数,即使编译器可能认为首先尝试正确的操作数会更有效。这样您就知道list==null | | list.IsEmpty()
永远不会抛出null指针异常
因此,为了回答您的问题,编译器不会生成比“计算左操作数,然后仅在必要时计算右操作数”更高效的代码,因为任何其他代码都会破坏语言规则
PS:理论上,如果编译器能够证明操作数没有任何副作用,那么它就有可能对操作数进行重新排序,但据我所知,这是不可能的。无论哪种方式,这都不会在AST级别发生
PPS:C#编译器不计算AST,而是从中生成代码。这是一个编译器,不是解释器。如果我没弄错的话,编译器会尝试从左到右读取您的语句。对于每个组件,它将计算为True
或False
。然后将检查下一步应该执行的操作(和/或)。根据上一个值的结果,它将选择是否评估条件的正确部分。这两部分的结果和逻辑运算符将用作下一部分的左侧部分。(我就是这样学的,所以这是最简单的方法)。C#编译器的工作原理可能会有所不同,请您回答。但是,如果“删除”树,并用一些标签、分支或某种goto将其列成一个简单的列表,这样它就只需要执行一些条件序列——跳过不需要的条件,不是更好吗?因此,执行部分不需要任何短路逻辑。例如:(分支命令)如果我没有弄错,编译器将尝试从左到右读取您的语句。对于每个组件,它将计算为True
或False
。然后将检查下一步应该执行的操作(和/或)。根据上一个值的结果,它将选择是否评估条件的正确部分。这两部分的结果和逻辑运算符将用作下一部分的左侧部分。(我就是这样学的,所以这是最简单的方法)。C#编译器的工作原理可能会有所不同,请您回答。但是,如果“删除”树,并用一些标签、分支或某种goto将其列成一个简单的列表,这样它就只需要执行一些条件序列——跳过不需要的条件,不是更好吗?因此,执行部分不需要任何短路逻辑。例如:(分支命令)谢谢你的回答。你觉得这个计划怎么样