适用于类似c语言的优秀AST设计(适用于llvm)

时间:2011-09-13 12:03:05

标签: compiler-construction llvm abstract-syntax-tree

我正在尝试使用llvm来实现一种简单,愚蠢的c语言。 我一直坚持设计一个好的AST。

例如,我想知道将变量分成两种节点是一个好主意: 一个用于分配,一个用于加载。我试过了,但是遇到了一些障碍:

Foo = asd = 3; 

在这种情况下,Foo和add将是一个分配,但添加也是一个加载。 但是ast节点通过它们的code()方法连接起来。

设计ast有什么好的资源吗? (我试图找到clang的,但是从它的源文件中轻松理解它有点复杂。)

2 个答案:

答案 0 :(得分:2)

在大多数允许这种输入的语言中,将被解析为

Foo = (asd = 3);

Foo将分配表达式asd = 3的结果。这通常恰好是asd的值,但AST不需要代表那个。

AST通常不代表像“读取访问”这样的语义。它是语法的图形表示,语法只是“使用左侧变量Foo和右侧(使用左侧变量asd赋值和右侧的赋值手边整数常量3)“。

如果我正确记住了Kaleidoscope示例,您会看到它们的每个语句都返回一个值。其中大多数将在链中进一步优化,但它们是获得嵌套赋值等有用行为的最简单方法。显然,任务的左侧需要特殊处理,但没有任何难以理解或难以实现的内容。

答案 1 :(得分:1)

您可以从Go的AST包中获取灵感:http://golang.org/pkg/go/ast/

它是一种类似C的语言,虽然您的示例不适用,因为Go中的赋值是一个语句而不返回值。如果是这样,你的代码会解析为这样的东西: (这是伪Go,但希望可以被不了解它的人理解)

AssignExpr{
    Lhs: Ident{
        Name: "Foo",
    },
    Tok: token.ASSIGN
    Rhs: AssignExpr{
        Lhs: Ident{
            Name: "asd",
        },
        Rhs: BasicLit{
            Kind: token.INT,
            Value: "3",
        },
    },
}