Skip to content

重庆大学计算机学院编译原理实验代码(2019级)

License

Notifications You must be signed in to change notification settings

Aw0m/CQU-CompilationPrinciple

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CQU-CompilationPrinciple

重庆大学计算机学院编译原理实验代码(2019级)

简介

该Repository是重庆大学计算机学院编译原理四次实验的源代码,分别对应了:词法分析语法分析错误检查生成MIPS代码四部分。每一次的实验都是在上一次实验的代码的基础上修改的。

个人感觉自己的代码写得还算规范吧😭😭😭,至少前两次实验的代码还算规范,注释也认认真真写了。第三次实验的错误检查有点小摆,就没那么认真。第四次实验因为就一个测试集,所以有些情况的MIPS我没有去生成😢

如果你是后来的学弟学妹,看见了这个Rep同时对你有帮助的话点一个follow或者star吧😭😭😭😭,谢谢你🥰🥰🥰

词法分析

词法分析就很简单,有点类似于状态机那种,就是一直读,然后根据当前状态看生成哪一种。

语法分析

我使用的是递归调用的方法。最开始写这个实验的时候没有太理解这个思路,导致前面几个比如变量定义写得有点点乱,其余的就还算比较清晰了。我看我室友们写了快1500行,我也就800行样子,已经算比较精炼了。

我通过把词法分析得到的结果存到一个vector<pair<string, string>> lexRes里,然后遍历这个lexRes进行分析判断即可。

错误分析

错误分析其实也简单,稍微复杂一点的也就是如何得到<表达式>的返回结果。这里大概是通过递归调用返回得到的。大概是从 因子->项->表达式这样子递归,每次递归得到一个string,通过这个string来判断递归的结果(不过现在写完实验4了,想来这种递归似乎没必要,每次用固定的三四个变量记录似乎就够了😭)

还有就是用了一个符号表。我这里用了三个符号表,分别是全局变量表,局部变量表,函数表。变量类和函数类的定义在Symbol.h中。全局变量表和函数表,直接用一个map<string, Variable>map<string, Function>存就可以了。局部变量因为存在同名情况,所以我们没有直接用map存,而是用了一个vector存。搜索的时候判断varNamevarFunc (存的该var属于哪一个函数) 是否相同就行。因为需要存是哪一个function的变量,所以我这里有一个this->func 属性,用来保存当前是在哪一个函数,当局部变量定义的时候,我就知道我new的Variable是属于哪一个func了。

生成MIPS代码

生成MIPS代码也简单,而且我觉得我写得也比较清晰。我把主要的比如输入输出都包装到以 mips 开头的几个函数里面去了。这里简单讲一下思路。

首先是变量/常量定义:由于测试集只有一个main函数,我这里偷懒就全部写到main:里面去了。我的mipsGetReg()中,通过遍历一个register verctor,找到一个没有使用过的寄存器就行。输入和输出也很简单。如果是输出字符串,我就会先生成一个 printMsg到.data中,到时候直接输出这个就行。

稍微复杂一点点的就是<表达式>的mips怎么生成。这里跟错误分析的一样,也是递归调用。通过固定的$t0,$t1,$t2,每次都将结果写入临时寄存器然后返回,就可以完成相应的操作。

About

重庆大学计算机学院编译原理实验代码(2019级)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages