编译器开发系列--Ocelot语言1.抽象语法树

时间:2024-10-31 09:33:38

从今天开始研究开发自己的编程语言Ocelot,从《自制编译器》出发,然后再自己不断完善功能并优化。

编译器前端简单,就不深入研究了,直接用现成的一款工具叫JavaCC,它可以生成抽象语法树,抽象语法树是生成中间代码的关键,而中间代码又是生成后端代码的关键。

整个编译器代码采用java语言编写,主要功能是对JavaCC生成的抽象语法树进行语义分析、优化,最后生成优化后的汇编代码,然后再用汇编器对汇编代码汇编生成机器码,最后再用命令链接生成Linux可执行文件,就可以直接在Linux上运行了。

整个编译器采用的语法基本上都是C语言的语法,去除掉一些语法成C语言简化版,而且原项目并无优化。我想做的是在原项目的基础上对其各种优化并使其支持垃圾回收。- -!有的玩了。

抽象语法树和其节点都是继承自Node类。介绍一下Node 类群的继承层次:

编译器开发系列--Ocelot语言1.抽象语法树

编译器开发系列--Ocelot语言1.抽象语法树

编译器开发系列--Ocelot语言1.抽象语法树

再来通过一个简单的helloworld小demo来查看抽象语法树的结构,demo如下所示:

int main(int argc, char **argv)
{
int i, j = 5;
if (i) {
return (j * 1 - j);
}
else {
exit(1);
}
}

编译器项目运行后生成的抽象语法树如下所示:

<<AST>> (G:\编译原理\自制编译器\源码\test\hello.cb:1)
variables:
functions:
<<DefinedFunction>> (G:\编译原理\自制编译器\源码\test\hello.cb:1)
name: "main"
isPrivate: false
params:
parameters:
<<Parameter>> (G:\编译原理\自制编译器\源码\test\hello.cb:1)
name: "argc"
typeNode: int
<<Parameter>> (G:\编译原理\自制编译器\源码\test\hello.cb:1)
name: "argv"
typeNode: char**
body:
<<BlockNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:2)
variables:
<<DefinedVariable>> (G:\编译原理\自制编译器\源码\test\hello.cb:3)
name: "i"
isPrivate: false
typeNode: int
initializer: null
<<DefinedVariable>> (G:\编译原理\自制编译器\源码\test\hello.cb:3)
name: "j"
isPrivate: false
typeNode: int
initializer:
<<IntegerLiteralNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:3)
typeNode: int
value: 5
stmts:
<<IfNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:4)
cond:
<<VariableNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:4)
name: "i"
thenBody:
<<BlockNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:4)
variables:
stmts:
<<ReturnNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:5)
expr:
<<BinaryOpNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:5)
operator: "-"
left:
<<BinaryOpNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:5)
operator: "*"
left:
<<VariableNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:5)
name: "j"
right:
<<IntegerLiteralNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:5)
typeNode: int
value: 1
right:
<<VariableNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:5)
name: "j"
elseBody:
<<BlockNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:7)
variables:
stmts:
<<ExprStmtNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:8)
expr:
<<FuncallNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:8)
expr:
<<VariableNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:8)
name: "exit"
args:
<<IntegerLiteralNode>> (G:\编译原理\自制编译器\源码\test\hello.cb:8)
typeNode: int
value: 1

1.<<AST>> 和<<DefinedFunction>> 表示节点的类名。

2.右侧所显示的(G:\编译原理\自制编译器\源码\test\hello.cb:1) 是该节点对应的语法所记载的文件名和行号。

3.缩进表示该节点被前一个节点引用。