Compiler construction 三个地址代码和符号表

Compiler construction 三个地址代码和符号表,compiler-construction,ocaml,abstract-syntax-tree,intermediate-language,symbol-table,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 *

我正在用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
    s在不同的作用域中具有相同的名称,该怎么办


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

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


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

    非常感谢。因此,我不会在TAC中使用单独的Temp和Var节点,而是将它们设置为单个符号节点,包含指向符号表中某个条目的指针?@jamestn:有很多方法。这当然是一种方法。你还需要考虑静态与自动的生命周期。我认为静态与自动更像是一个类型问题,不是吗?