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

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

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

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

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

再来通过一个简单的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.缩进表示该节点被前一个节点引用。

编译器开发系列--Ocelot语言1.抽象语法树的更多相关文章

  1. 编译器开发系列--Ocelot语言3.类型名称的消解

    "类型名称的消解"即类型的消解.类型名称由TypeRef 对象表示,类型由Type 对象表示.类型名称的消解就是将TypeRef 对象转换为Type 对象. TypeResolve ...

  2. 编译器开发系列--Ocelot语言2.变量引用的消解

    "变量引用的消解"是指确定具体指向哪个变量.例如变量"i"可能是全局变量i,也可能是静态变量i,还可能是局部变量i.通过这个过程来消除这样的不确定性,确定所引用 ...

  3. 编译器开发系列--Ocelot语言7.中间代码

    Ocelot的中间代码是仿照国外编译器相关图书Modern Compiler Implementation 中所使用的名为Tree 的中间代码设计的.顾名思义,Tree 是一种树形结构,其特征是简单, ...

  4. 编译器开发系列--Ocelot语言6.静态类型检查

    关于"静态类型检查",想必使用C 或Java 的各位应该非常熟悉了.在此过程中将检查表达式的类型,发现类型不正确的操作时就会报错.例如结构体之间无法用+ 进行加法运算,指针和数值之 ...

  5. 编译器开发系列--Ocelot语言5.表达式的有效性检查

    本篇将对"1=3""&5"这样无法求值的不正确的表达式进行检查. 将检查如下这些问题.●为无法赋值的表达式赋值(例:1 = 2 + 2)●使用非法的函数 ...

  6. 编译器开发系列--Ocelot语言4.类型定义的检查

    这里主要介绍一下检查循环定义的结构体.联合体.是对成员中包含自己本身的结构体.联合体进行检查.所谓"成员中包含自己本身",举例来说,就是指下面这样的定义. struct point ...

  7. javascript编写一个简单的编译器(理解抽象语法树AST)

    javascript编写一个简单的编译器(理解抽象语法树AST) 编译器 是一种接收一段代码,然后把它转成一些其他一种机制.我们现在来做一个在一张纸上画出一条线,那么我们画出一条线需要定义的条件如下: ...

  8. 从零写一个编译器(九):语义分析之构造抽象语法树(AST)

    项目的完整代码在 C2j-Compiler 前言 在上一篇完成了符号表的构建,下一步就是输出抽象语法树(Abstract Syntax Tree,AST) 抽象语法树(abstract syntax ...

  9. JavaScript的工作原理:解析、抽象语法树(AST)+ 提升编译速度5个技巧

    这是专门探索 JavaScript 及其所构建的组件的系列文章的第 14 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...

随机推荐

  1. IE6/7下空div占用空间的问题

    最近注意力没在前端上面,工作碰到这样一个问题,下意识的写了句 font-size:0;line-height:0;哪知道引发了更大的bug.后来插入数据进去的时候都不显示了..再后来百度一番找到,原来 ...

  2. Java数据库连接技术——JDBC

    大家好,今天我们学习了Java如何连接数据库.之前学过.net语言的数据库操作,感觉就是一通百通,大同小异. JDBC是Java数据库连接技术的简称,提供连接各种常用数据库的能力. JDBC API ...

  3. StatePattern(状态模式)

    /** * 状态模式 * @author TMAC-J * 状态模式和策略模式很像,其实仔细研究发现完全不一样 * 策略模式各策略之间没有任何关系,独立的 * 状态模式各状态之间接口方法都是一样的 * ...

  4. 面向对象相关知识点xmind

  5. JavaScript作用域

    JavaScript作用域 JavaScript作用域一直是前端开发的难题,现在只要用五句话就可解决. 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个 ...

  6. Dynamics CRM 之ADFS 使用 WID 的联合服务器场

    使用 WID 的联合服务器场 默认拓扑 Active Directory 联合身份验证服务 (AD FS) 是联合服务器场,使用 Windows 内部数据库 (WID). 在这种拓扑, AD FS 使 ...

  7. Atiti.大企业病与小企业病 大公司病与小公司病

    Atiti.大企业病与小企业病 大公司病与小公司病 1. 大企业病,一般会符合机构臃肿 .多重领导 .人才流失的特点.1 2. 大企业病避免方法1 3. 小企业病 1 3.1.1. 表现1 4. 如何 ...

  8. Linux实战教学笔记05:远程SSH连接服务与基本排错(新手扫盲篇)

    第五节 远程SSH连接服务与基本排错 标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 远程连接LInux系统管理 1.1 为什么要远程连接Linux系统 在实际的工作场景中,虚拟机界面或物理 ...

  9. Web应用之LAMP源码环境部署

    一.LAMP环境的介绍 1.LAMP环境的重要性 思索许久,最终还是决定写一篇详细的LAMP的源码编译安装的实验文档,一来是为了给自己一个交代,把技术进行系统的归纳,将技术以极致的形式呈现出来,做为一 ...

  10. XSS 前端防火墙 —— 无懈可击的钩子

    昨天尝试了一系列的可疑模块拦截试验,尽管最终的方案还存在着一些兼容性问题,但大体思路已经明确了: 静态模块:使用 MutationObserver 扫描. 动态模块:通过 API 钩子来拦截路径属性. ...