2周完成一个简单的编译器

一、作案动机

       由于这学期有一门《编译原理》的课程,感觉如果不写一个编译器对不起这门课,所以我便动手了。但是考虑到我的时间有限和做一个编译器的难度,于是我给自己的时间是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
C#简易编译器 namespace 编译 { public class Grammar { List<token> tokens; List<symble> symbles; public string error = ""; int i = 0; public Grammar(Morphology m) { tokens = m.tokens; symbles = m.symbles; Dispose(); } private void Next() { if (i < tokens.Count - 1) { i++; } } private void Before() { if (i > 0) { i--; } } #region 主要函数 private void Dispose() { if (tokens[i].Code == 12)//含有program { Next(); if (tokens[i].Code == 18)//是标识符 { //执行程序体 Next(); ProBody(); } else { error = "该程序program缺少方法名"; } } else { error = "该程序缺少关键字:program"; } } #endregion #region 程序体 private void ProBody() { if (tokens[i].Code == 16) { Next(); VarDef(); } else if (tokens[i].Code == 2) { Next(); ComSent(); } else { error = "程序体缺少var或begin"; } } #endregion #region 变量定义 private void VarDef() { if (IsIdlist()) { Next(); if (tokens[i].Code == 29)//: { Next(); if (tokens[i].Code == 9 || tokens[i].Code == 3 || tokens[i].Code == 13)//integer,bool,real { int j = i; j = j - 2; symbles[tokens[j].Addr].Type = tokens[i].Code; j--; while (tokens[j].Code == 28) { j--; symbles[tokens[j].Addr].Type = tokens[i].Code; } Next(); if (tokens[i].Code == 30) { Next(); if (tokens[i].Code == 2) { Next(); ComSent(); } else { VarDef(); } } else { error = "变量定义后面缺少;"; } } else { error = "变量定义缺少类型或类型定义错误"; return; } } else { error = "var后面缺少冒号"; } } else { error = "变量定义标识符出错"; } } #endregion #region 判断是不是标识符表 private bool IsIdlist() { if (tokens[i].Code == 18) { Next(); if (tokens[i].Code == 28)//, { Next(); return IsIdlist(); } else { Before(); return true; } } else { return false; } } #endregion #region 复合句 private void ComSent() { SentList(); if (error == "") { if (tokens[i].Code == 6) { return; } else { error = "复合句末尾缺少end"; } } } #endregion #region 语句表 private void SentList() { ExecSent(); if (error == "") { Next(); if (tokens[i].Code == 30) { Next(); SentList(); } } } #endregion #region 执行句 private void ExecSent() { if (tokens[i].Code == 18) { Next(); AssiSent(); } else if (tokens[i].Code == 2 || tokens[i].Code == 8 || tokens[i].Code == 17) { StructSent(); } else { Before(); } } #endregion #region 赋值句 private void AssiSent() { if (tokens[i].Code == 31)//:= { Next(); Expression(); } else { error = "赋值句变量后缺少:="; } } #endregion #region 表达式 private void Expression() { if (tokens[i].Code == 7 || tokens[i].Code == 15 || (tokens[i].Addr != -1 && symbles[tokens[i].Addr].Type == 3)) { BoolExp(); } else { AritExp(); } } #endregion #region 布尔表达式 private void BoolExp() { BoolItem(); if (error == "") { Next(); if (tokens[i].Code == 11) { Next(); BoolExp(); } else { Before(); } } else { return; } } #endregion #region 布尔项 private void BoolItem() { BoolFactor(); if (error == "") { Next(); if (tokens[i].Code == 1) { Next(); BoolItem(); } else { Before(); } } } #endregion #region 布尔因子 private void BoolFactor() { if (tokens[i].Code == 10) { Next(); BoolFactor(); } else { BoolValue(); } } #endregion #region 布尔量 private void BoolValue() { if (tokens[i].Code == 15 || tokens[i].Code == 7) { return; } else if (tokens[i].Code == 18) { Next(); if (tokens[i].Code == 34 || tokens[i].Code == 33 || tokens[i].Code == 32 || tokens[i].Code == 37 || tokens[i].Code == 36 || tokens[i].Code == 35) { Next(); if (tokens[i].Code == 18) { } else { error = "关系运算符后缺少标识符"; } } else { Before(); } } else if (tokens[i].Code == 21) { BoolExp(); //? if (tokens[i].Code == 22) { return; } else { error = "布尔量中的布尔表达式缺少一个)"; } } else { error = "布尔量出错"; } } #endregion #region 算数表达式 private void AritExp() { Item(); if (error == "") { Next(); if (tokens[i].Code == 23 || tokens[i].Code == 24) { Next(); AritExp(); } else { Before(); return; } } else { return; } } #endregion #region 项 private void Item() { Factor(); if (error == "") { Next(); if (tokens[i].Code == 25 || tokens[i].Code == 26) { Next(); Item(); } else { Before(); return; } } else { return; } } #endregion #region 因子 private void Factor() { if (tokens[i].Code == 21) { Next(); AritExp(); Next(); if (tokens[i].Code == 22) { return; } else { error = "因子中算数表达式缺少)"; } } else { CalQua(); } } #endregion #region 算数量 private void CalQua() { if (tokens[i].Code == 18 || tokens[i].Code == 19 || tokens[i].Code == 20) { return; } else { error = "算数量出错"; } } #endregion #region 结构句 private void StructSent() { if (tokens[i].Code == 2) { Next(); ComSent(); } else if (tokens[i].Code == 8) { Next(); IfSent(); } else if (tokens[i].Code == 17) { Next(); WhileSent(); } } #endregion #region if语句 private void IfSent() { BoolExp(); if (error == "") { Next(); if (tokens[i].Code == 14) { Next(); ExecSent(); Next(); if (tokens[i].Code == 5) { Next(); ExecSent(); } else { Before(); return; } } else { error = "if...then语句缺少then"; } } else { error = "if语句布尔表达式出错"; } } #endregion #region while语句 private void WhileSent() { BoolExp(); if (error == "") { Next(); if (tokens[i].Code == 4) { Next(); ExecSent(); } else { error = "while语句缺少do"; } } } #endregion } }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值