三地址代码和符号表

时间:2015-06-19 07:38:41

标签: compiler-construction ocaml abstract-syntax-tree intermediate-language symbol-table

我正在研究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节点列表忽略注释。关于这一点,我有两个问题:

  1. 将类型注释的AST转换为TAC节点列表时,我该怎么做?我是否应该向TAC节点添加注释?这样我就可以稍后将高级int / char类型转换为I16 / I8等较低级别的类型。

  2. 如何处理范围界定?如果我有两个Var在不同范围内具有相同名称,该怎么办?

1 个答案:

答案 0 :(得分:1)

如何将注释传递给TAC是一个非常开放的问题,但我同意您可能希望这样做。

范围界定的一种方法是名称擦除;在解析作用域时,将每个唯一标识符替换为唯一的“名称”(或直接使用对符号表条目的引用。)(有时称为gensymming,在传统的Lisp gensym函数之后。)更正式地说,它是α-reduction,一个取自λ演算的术语。这适用于C语言,其中名称不可用于运行时。

运行时内省可以访问名称(Python,Javascript)的语言使得此过程稍微复杂一些,但您仍然可以将名称的每次使用与特定范围相关联。在范围可以是动态的语言(Perl,Lisp)中,您必须在TAC中引入名称解析操作。