编译器开发系列--Ocelot语言1.抽象语法树
从今天开始研究开发自己的编程语言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.抽象语法树的更多相关文章
- 编译器开发系列--Ocelot语言3.类型名称的消解
"类型名称的消解"即类型的消解.类型名称由TypeRef 对象表示,类型由Type 对象表示.类型名称的消解就是将TypeRef 对象转换为Type 对象. TypeResolve ...
- 编译器开发系列--Ocelot语言2.变量引用的消解
"变量引用的消解"是指确定具体指向哪个变量.例如变量"i"可能是全局变量i,也可能是静态变量i,还可能是局部变量i.通过这个过程来消除这样的不确定性,确定所引用 ...
- 编译器开发系列--Ocelot语言7.中间代码
Ocelot的中间代码是仿照国外编译器相关图书Modern Compiler Implementation 中所使用的名为Tree 的中间代码设计的.顾名思义,Tree 是一种树形结构,其特征是简单, ...
- 编译器开发系列--Ocelot语言6.静态类型检查
关于"静态类型检查",想必使用C 或Java 的各位应该非常熟悉了.在此过程中将检查表达式的类型,发现类型不正确的操作时就会报错.例如结构体之间无法用+ 进行加法运算,指针和数值之 ...
- 编译器开发系列--Ocelot语言5.表达式的有效性检查
本篇将对"1=3""&5"这样无法求值的不正确的表达式进行检查. 将检查如下这些问题.●为无法赋值的表达式赋值(例:1 = 2 + 2)●使用非法的函数 ...
- 编译器开发系列--Ocelot语言4.类型定义的检查
这里主要介绍一下检查循环定义的结构体.联合体.是对成员中包含自己本身的结构体.联合体进行检查.所谓"成员中包含自己本身",举例来说,就是指下面这样的定义. struct point ...
- javascript编写一个简单的编译器(理解抽象语法树AST)
javascript编写一个简单的编译器(理解抽象语法树AST) 编译器 是一种接收一段代码,然后把它转成一些其他一种机制.我们现在来做一个在一张纸上画出一条线,那么我们画出一条线需要定义的条件如下: ...
- 从零写一个编译器(九):语义分析之构造抽象语法树(AST)
项目的完整代码在 C2j-Compiler 前言 在上一篇完成了符号表的构建,下一步就是输出抽象语法树(Abstract Syntax Tree,AST) 抽象语法树(abstract syntax ...
- JavaScript的工作原理:解析、抽象语法树(AST)+ 提升编译速度5个技巧
这是专门探索 JavaScript 及其所构建的组件的系列文章的第 14 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...
随机推荐
- Javascript 的执行环境(execution context)和作用域(scope)及垃圾回收
执行环境有全局执行环境和函数执行环境之分,每次进入一个新执行环境,都会创建一个搜索变量和函数的作用域链.函数的局部环境不仅有权访问函数作用于中的变量,而且可以访问其外部环境,直到全局环境.全局执行环境 ...
- Java多线程基础学习(二)
9. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...
- 前端学HTTP之安全HTTP
前面的话 HTTP的主要不足包括通信使用明文(不加密),内容可能会被窃听:不验证通信方的身份,有可能遭遇伪装:无法证明报文的完整性,有可能被篡改 基本认证和摘要认证能够使得用户识别后较安全的访问服务器 ...
- ES6之变量常量字符串数值
ECMAScript 6 是 JavaScript 语言的最新一代标准,当前标准已于 2015 年 6 月正式发布,故又称 ECMAScript 2015. ES6对数据类型进行了一些扩展 在js中使 ...
- linux下mono播放PCM音频
测试环境: Ubuntu 14 MonoDevelop CodeBlocks 1.建立一个共享库(shared library) 这里用到了linux下的音频播放库,alsa-lib. al ...
- 【腾讯Bugly干货分享】JSPatch 成长之路
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/579efa7083355a9a57a1ac5b Dev Club 是一个交流移动 ...
- subline text3 使用总结
安装:http://www.sublimetext.com/3 插件扩展: 安装package control组件 按Ctrl+`调出console(注:安装有QQ输入法的这个快捷键会有冲突的,输入 ...
- 在 Linux 中使用 Git 及其 和 Eclipse 的集成
##参考资料## 我是通过阅读<Pro Git>这本书学习 Git 的,我读的时候还是第一版的英文版,现在已经出第二版了,而且英文版和中文版都有.英文第二版的地址是 [https://gi ...
- 新手如何在gdb中存活
网络上已经有很多gdb调试的文章了,为什么我还要写这篇文章呢,因为本文是写给gdb新手的,目的就是通过一个简单的例子来让新手很快上手.一旦上手入门了,其他的问题就可以自己去搜索搞定了.右边是gdb的L ...
- SQL Server 索引和表体系结构(聚集索引)
聚集索引 概述 关于索引和表体系结构的概念一直都是讨论比较多的话题,其中表的各种存储形式是讨论的重点,在各个网站上面也有很多关于这方面写的不错的文章,我写这篇文章的目的也是为了将所有的知识点尽可能的组 ...