把 D 语言的语法规则改写成 ANTLR 的语法脚本后,大概有30多K,编译的时候,出了很多的错误,最后内存溢出了。想一想,也是,一来我对 ANTLR 还不熟,二来,Digit Mars 上的 D 语言语法介绍,很多左递归,有几个没有定义的过程,两个拼写错误,一个同名不同义的过程等等。在这种情况下,30多K的语法脚本想要很快的就编译通过,是很困难的。
所以,还是决定用 ANTLR 实现一下 Z 编译器。这一次,把 Z 作为 D 的一个子集,语法定义大部分直接从 D 的语法脚本中复制,一来可以熟悉 ANTLR,二来,完成的语法文件,对于 D 来说也是有用的。
作为 D 的子集,现在 Z 也支持一些 D 的风格的语法,比如三种注释方式:
// 行注释
/* 注释 */
/+ 嵌套注释 +/
另外,也支持 D 中的带有“_”的数字格式:
int a = 123_456_789;
这个版本中增加支持了 bool 类型:
bool b = true;
b = 30 > 10;
也支持 D 语言中的自动类型推导:
auto a = 1;
auto b = true;
if(b) write(a);
其它的一般都是 C 和 D 公有的,比如十六进制数字、八进制数字:
int a = 0x83_af; // 十六进制数字
int b = 067; // 八进制数字
连等赋值:
a = b = c = 2;
++、--、+=、-=、*=、/= (++、--只支持左操作符方式):
int n = 10;
int a *= ++n;
也增加了 for、while、do-while 循环:
// 1 到 100 的和
// for 循环
int n = 0;
for(int i=1; i<=100; ++i)
n += i;
write(n);
// while 循环
i = 0; n = 0;
while( i < 100 )
n += ++i;
write(n);
// do-while 循环
i = 0; n = 0;
do
n += ++i;
while( i < 100 )
write(n);
另外,因为语法文件大部分从 D 复制,所以,运算符优先级也和 C/D 一样了(就是上次说的“&&”的优先级高于“||”之类的问题)。负号现在也遵照这种方式放入表达式中,所以,不只没有上一版中必须加空格的问题,而且支持对变量求负:
int a = 10;
int b=5-3; // 5 - 3
b=5--3; // 5 - (-3);
b=7*-a; // 7 * (-a);
虽然可以在定义变量的时候使用逗号,但是普通表达式还不支持逗号方式。另外,Z 还是有一个和 D 比较大的不同,就是 bool 类型和 int 类型之间不允许互相转换,否则会引发编译时错误,而 if for while do-while 的条件表达式也必须最终为 bool 类型才可以:
int n = 1;
bool a = n == 0;
a = a && n > 10 || n != 3;
bool b = n; // error
if(b) write(1);
if(n) write(2); // error
ANTLR 确实对于语法的细节控制能力更强,而且,生成 AST 的能力也很突出。ANTLRWorks 虽然有时候不工作,有时候和实际代码效果有出入,总体来说还是帮助很大。从 AST 生成代码也比上一版中更方便。不过,在我的实现代码里很多异常都是直接用断言实现的,没有打印行号。另外,因为 ANTLR 有很强的错误恢复能力,目前还不知道怎么判断代码分析中是否出现错误……
下面是可执行程序和源代码:
- ZLan4a.zip (190.1 KB)
- 描述: 可执行程序、源代码和几个例子。需要.net fx 2.0
- 下载次数: 42
分享到:
相关推荐
编译原理实习:实习内容为实现可编译Pascal语言子集的编译器
实现了一个C语言简单子集的编译器点段部分 可以将文法定义的合法的源代码转化为四元式 实现了词法分析、语法分析、语义分析部分 进行文件的输入输出,从文件读取文法、源代码、将四元式输出到文件
一个C语言子集的编译器,借助于 Flex 和 Bison 工具,使用 C 语言编写;用于编译原理课程设计。.zip一个C语言子集的编译器,借助于 Flex 和 Bison 工具,使用 C 语言编写;用于编译原理课程设计。.zip一个C语言子集...
通过所设计的C语言子集编译器能够对用户所输入的C语言子集程序代码进行词法分析、语法分析和语义分析,能将源代码编译成汇编指令(伪指令)。在进行编译的过程中,能过滤去 “//”或“/* */”形式的文字注释,具备...
编译原理课程设计:PASCAL子集语言编译器.zip
本程序经过修改调试,成功运行通过!欢迎学习研究
c++实现c语言子集编译器,共有三种数据类型INT,BOOL,ARRAY;三种控制结构IF-ELSE、WHILE、FOR,产生四个表,词法分析parser.out、action.out、goto.out、四元式parser.out。
运行程序可将 C 语言编译为三地址码,以及将三地址码翻译为 MIPS32 汇编代码, 并在 SPIM 模拟器上运行,通过了所有测试。 可以在 ubuntu 下终端中执行 readme.txt 中的命令完成编译运行,并将tests/test.c 文件转化...
课程目标是构造一个高级语言的子集的编译器,目标代码是汇编语言。通过简单自定义语言编译器的完整实现,掌握编译原理理论知识,提高灵活运用理论知识以解决实际问题的能力;提高系统软件编写能力。 采用简化的 C ...
单词是MiniC语言中具有独立意义的最小单位,可分为 5 大类:关键字(保留字)、运算符、界符、常量和标识符。 C语言中的关键字(它们都是保留字)包括:基本类型关键字 int、float、char,分支与循环语句涉及的 if、...
编译原理实践项目,一个C语言子集的编译器,包括词法分析器和语法分析器,由Java语言实现
这是一个关于C语言的一个子集的编译器,其中包括了一个编译器所包含的全部,有词法分析,语法分析,及token表的生成与显示,中间代码(三元式)及目标代码(汇编指令)的生成与显示。采用C++,MFC编译实现的可视化...
课程设计题目:一个PASCAL语言子集(PL/0)编译器的设计与实现。有源程序和报告。
小型pascal子集编译器,实验报告,c++语言实现
C语言子集的编译器,编译原理大作业+源代码+文档说明 一个C语言子集的编译器,可生成自己定义的中间代码和mips汇编代码,并运行在spim上。 过程中会生成将语法树可视化的json文件,可使用Vue的树形组件将其可视化,...
《编译原理》课程实践项目,一个C语言子集的编译器,包括词法分析器和语法分析器,由Java语言实现。.zip
本程序能实现C语言子集的编译,能实现的主要功能包括: (1)、实现编译的词法分析 (2)、语法分析 (3)、语义分析功能 (4)、错误处理能力,并给出总的出错报告 (5)、编译最终形成四元式的中间代码形式