开发者

A good AST design for a c-like language (for llvm)

开发者 https://www.devze.com 2023-04-04 07:51 出处:网络
I am trying to use llvm to implement a simple, du开发者_JAVA技巧mb c-like language. And i\'m stucked at designing a good AST.

I am trying to use llvm to implement a simple, du开发者_JAVA技巧mb c-like language. And i'm stucked at designing a good AST.

For example i'm wondering if separating a variable into two kind of nodes is a good idea: one for allocating and one for loading it. I tried that, but i got into some obstacles:

Foo = asd = 3; 

At this case Foo and add would be an allocating, but add would be a loading as well. But the ast nodes are joined at their code() methods.

Is there any good resources on designing ast? (I tried to find clang's but it's kinda complex to easily comprehend from it's source files.)


In most languages that allow this kind of input, that would be parsed as

Foo = (asd = 3);

and Foo would be assigned the result of the expression asd = 3. Which usually happens to be the value of asd, but the AST doesn't need to represent that.

The AST usually does not represent semantics like “read access” anyway. It's a graph representation of the syntax, and the syntax is just “assignment with left hand side variable Foo and right hand side (assignment with left hand side variable asd and right hand side integer constant 3)”.

If I remember the Kaleidoscope example correctly, you'll see they have every statement return a value. Most of those will be optimized away further down the chain, but they are the easiest way of getting useful behavior for nested assignments and the like. The left hand side of an assignment, obviously, needs special treatment, but nothing that is difficult to understand or hard to implement.


You might be able to take some inspiration from Go's AST package: http://golang.org/pkg/go/ast/

It's a C-like language, although your example doesn't apply since assignment in Go is a statement and doesn't return a value. If it did, your code would parse to something like this: (this is pseudo-Go, but will hopefully be understandable by people who don't know it)

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

精彩评论

暂无评论...
验证码 换一张
取 消