在编译器中生成中间代码处理条件时是否总是需要AST或分析树?

问题描述

| 我正在上一个编译器设计类,我们必须在其中实现自己的编译器(使用flex和bison)。我有解析的经验(编写EBNF和递归下降解析器),但这是我第一次编写编译器。 语言设计是开放式的(教授把它留给了我们)。上课时,教授结束了生成中间代码的工作。他说,我们在解析时不必构造抽象语法树或解析树,并且我们可以在进行过程中生成中间代码。 我发现这令人困惑,原因有两个: 如果在定义函数之前调用函数怎么办?如何解决分支目标?我猜您将必须成为一个规则,即必须在使用函数之前定义函数,或者可能要预先定义函数(如C一样?) 您将如何处理有条件的?如果您有一个
if-else
甚至是一个
if
,那么当条件为
false
时(如果您正在生成代码)如何解决resolve1ѭ的分支目标? 我计划生成一个AST,然后在创建它之后遍历树,以解析功能和分支目标的地址。这是正确的还是我错过了什么?     

解决方法

        解决这两个问题的一般方法是保留一个需要“修补”的地址列表。生成代码并为缺少的地址或偏移量留空。在编译单元的末尾,您将浏览孔列表并进行填充。 在FORTH中,补丁的“列表”保留在控制堆栈中,并在每个控制结构终止时解开。见第四尺寸 轶事:早期的Lisp编译器(我相信它是Lisp)生成了符号格式的机器代码指令列表,并带有对条件语句每个分支的机器代码列表的正向引用。然后,它生成了将列表向后移动的二进制代码。这样,当需要发出分支指令时,就可以知道所有前向分支的代码位置。     ,        Crenshaw教程是不使用任何AST的具体示例。它构建了一个可工作的编译器(显然包括条件编译器),并且可以针对m68k汇编立即生成代码。 您可以在一个下午通读该文档,这是值得的。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...