一、作案动机
由于这学期有一门《编译原理》的课程,感觉如果不写一个编译器对不起这门课,所以我便动手了。但是考虑到我的时间有限和做一个编译器的难度,于是我给自己的时间是2周,太多有点浪费,太少挑战又有点大,2周刚好。
二、被捕感言
2周已经过去了,我也实现了一个编译器。我感觉写一个编译器最大的挑战在于如何起步,也就是说一个小白如何快速的搭建出一个编译器的整个流程。我所说的这个流程是大概的框架而不是完全知道细节,细节只有在慢慢实现时才可以慢慢完善。框架包括什么内容呢?包括:你设计的语言的文法是什么(我的语言叫Cf语言,和C语言类似)?有哪些关键字?有哪些数据结构?有多少功能(比如函数调用、类、结构体等等)?语法分析用什么(比如LL1、LR1等等)?大概需要哪些数据结构(比如变量表、函数表)?编译的目标代码是什么(汇编还是机器指令)?中间代码用什么?(四元式、树等等)大概就这些吧。
就是这些家伙花了我4天,开始的4天我主要查看不同的书籍去弄出整体框架。最好不要只看课本,因为不好找到总体方向。不要以为看个目录就算知道整体流程,我们的目标是:干出一个编译器而不是考个试。我主要看了2本书:课本《编译原理教程(第四版)》胡元义写、《编译器设计之路》裘巍。我的数据结构的设计主要参考第二本书,但是我只看他的数据结构设计而不看他的代码,因为我看了头有点晕(((φ(◎ロ◎;)φ)))。弄出框架以后的日子,我依次实现了词法分析器、语法分析器、在语法分析的过程中加上语义程序得到中间代码、把中间代码转成汇编。可能有人发现了我没加优化,确实我没有加上优化,原因很简单:降低难度。其实我是想过加上优化的,但是我扳了扳手指发现时间不够于是放弃了,可能我会在课程设计时加上优化的。补充说明:纯手工,不用lex等工具。
三、作案过程
首先最重要的,我要介绍一下我的Cf语言的结构:
- 数据结构:int整型、int[]整型数组、string字符串和string[]字符串数组。
补充说明:我的int必须>=0,占16位。
- 控制结构:if语句和while语句。
补充说明:我的if只有if没有else,但是不影响功能因为if else 可以用2个if实现只是傻了点。
- 关键字:int string def printf if while
补充说明:def 用于函数定义 printf是我的内置函数便于打印结果
总体的代码结构:
数据定义(就像这样)
int a;
int b[5];
string c;
string d[6];
函数申明(就像这样)
def gogo(){
a=3;
b[2]=3;
b[a]=a;
b[3]=a;
b[a]=4;
c="Test";
d[a]=c;
d[5]="TEST2";
d[a]="TEST1";
d[0]="HELLO";
d[a]=d[0];
}
def cfmain(){
gogo();
printf("TEST",1);
}
补充说明:我的语言的入口函数叫cfmain不能少。整个代码必须按照上面的结构,即先定义变量,这些变量就是全局变量,我这里没有局部变量。在函数里面申明不了变量的,要用的变量都放开头,申明中不能赋值。然后是函数申明,我的函数不能有参数,所有操作对象都是数据区的数据。
下面我放上文法大家就知道了。首先说明:我是用LL1进行语法分析的,所以文法需要进行消除左递归和提取公因子,导致下面的文法可读性不好,下面T开头的非终结符都是中间产生的。
终结符:
{ "i","n","s",",",";","(",")","[","]","{","}","<",">","=","!=","==","+","-","*","/","int",
"string","de