我正在研究OCaml中的一个业余爱好重定向C编译器,我正在自下而上构建它。到目前为止,我有一个带注释的AST类型,删节:
type 'e expr =
| Int of 'e * int
| Var of 'e * var
| Neg of 'e * 'e expr
| Add of 'e * 'e expr * 'e expr
| Sub of 'e * 'e expr * 'e expr
和三地址代码类型(再次删节):
type node = Copy of location * location
| Unary of location * unary_op * location
| Binary of location * location * binary_op * location
and location = Temp of int | Int of int | Var of string
and unary_op = Neg
and binary_op = Add | Sub
我编写的函数会将AST转换为TAC节点列表忽略注释。关于这一点,我有两个问题:
将类型注释的AST转换为TAC节点列表时,我该怎么做?我是否应该向TAC节点添加注释?这样我就可以稍后将高级int
/ char
类型转换为I16
/ I8
等较低级别的类型。
如何处理范围界定?如果我有两个Var
在不同范围内具有相同名称,该怎么办?
答案 0 :(得分:1)
如何将注释传递给TAC是一个非常开放的问题,但我同意您可能希望这样做。
范围界定的一种方法是名称擦除;在解析作用域时,将每个唯一标识符替换为唯一的“名称”(或直接使用对符号表条目的引用。)(有时称为gensymming,在传统的Lisp gensym
函数之后。)更正式地说,它是α-reduction,一个取自λ演算的术语。这适用于C语言,其中名称不可用于运行时。
运行时内省可以访问名称(Python,Javascript)的语言使得此过程稍微复杂一些,但您仍然可以将名称的每次使用与特定范围相关联。在范围可以是动态的语言(Perl,Lisp)中,您必须在TAC中引入名称解析操作。