【问题标题】:Generating branch instructions from an AST for a conditional expression从 AST 为条件表达式生成分支指令
【发布时间】:2020-09-18 03:28:29
【问题描述】:

我正在尝试为特定领域的语言编写编译器,目标是基于堆栈机器的 VM,而不是 JVM。

我已经为我的语言生成了一个解析器,并且可以很容易地生成一个我可以轻松理解的 AST。我也没有问题将我的语言的许多语句转换为该 VM 的适当指令,但是在遇到复杂条件时处理生成适当分支指令的问题时遇到了障碍,尤其是当它们与(可能嵌套)类似“and”或类似“or”的操作相结合,这些操作应在适用时使用短路分支。

我没有要求任何人为我写这篇文章。我知道我还没有开始足够详细地描述我的问题。我要的是指向有用的材料的指针,这些材料可以让我克服我面临的这个障碍。正如我所说,我已经超过了将我的语言中大约 90% 的语句转换为适用指令的地步,但让我难过的是条件处理和生成适当的流控制指令。到目前为止,我能够找到的关于从 AST 生成代码的大部分信息似乎只处理与简单的命令式语句相对应的代码生成,但条件和流程控制的处理似乎更加稀缺.

除了我已经描述的“and”和“or”之类的构造的短路/延迟评估机制之外,我不关心处理任何其他优化。

【问题讨论】:

标签: if-statement compiler-construction code-generation abstract-syntax-tree lazy-evaluation


【解决方案1】:

每个条件控制流都可以建模为流程图(或流程图),其中条件的两个分支具有不同的目标。鉴于布尔运算符短路,它们是控制流元素而不是简单的表达式,因此需要对其进行建模。

考虑这一点的一种方法是将布尔运算符重新表述为三元条件运算符的实例。因此,例如,A and B 变为 A ? B : falseA or B 变为 A ? true : B [注 1]。请注意,每个控制流程图都恰好有两个输出点。

要组合布尔表达式,只需代入图表即可。例如,这里是A AND (B OR C)

您只需交换两个流出的含义即可实现NOT

如果布尔表达式的最终使用是某种条件,例如if 语句或条件循环,您可以按原样使用控制流。如果要将布尔表达式保存到变量中或以其他方式用作值,则需要用代码填充两个流出,以创建相关常量,通常为 truefalse 布尔常量,或(在类 C 语言中)1 或 0。


注意事项:

  1. 写这个等价的另一种方式是A and B ⇒ A ? B : AA or B ⇒ A ? A : B,但这对于控制流视图的用处不大,而且还掩盖了意图只评估每个表达式一次的事实。这种形式(经过修改以重用 A 的初始计算)通常用于具有多个“假”值的语言(如 Python)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2019-06-12
    • 2021-08-26
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多