北理BIT 2024 编译原理 Lab. 2 二代编译器实验
题目要求
见文档,大致来说就是在词法分析的基础上进行简单的语义处理,并生成汇编代码
代码结构
为避免查重,此处仅给出部分关键代码架构
词法分析
可以选择手动实现或者采用flex词法分析器实现,博主采用的是flex词法分析器实现,以下为flex的部分代码
DIGIT [0-9]
LETTER [a-zA-Z]
UNDERLINE [_]
VARIABLE_NAME ({LETTER}|{UNDERLINE})({LETTER}|{DIGIT}|{UNDERLINE})*
WHITESPACE [ \t\n]
ws {WHITESPACE}+
INTERGER ({DIGIT}+)
上述定义了C语言常见的一些类型
下面对可能出现的字符进行完备的定义需要特别注意:
空格和缩进都是可以不识别并直接略过的
“,”是非常容易忽略的一个字符(e09如果查不出错看看是不是“,”没处理)
其余就没有太多可以分析的了大致分以下几类:属性随便设个不是0的int就行,因为
int yylex()可以视为读入下一个词
类型 属性 变量和 VAR 关键字(不含main) KEYWORD 括号 BRACKET 分号 LINE 等号(赋值) EQUAL 双目算符 OPERATER
传递逻辑
博主使用的sstream实现,维护一个公有的字符流,每次词法识别就向流中输入识别到的单词,返回该单词的属性,主函数在另一个文件通过这个流进行读取。
eg:
stream<<yytext;
return(OPERATER);
调用
主函数通过include编译出来的cpp文件,读取输入的文件名,将file*指向该文件(同lab1)
yyin=file*将文件内容传递给词法分析器,通过yylex()读取词法分析结果
我的方法是存成类或者结构,会方便一些
计算
计算其实没有太多可以说的,因为和lab1大差不差,需要注意几个小问题
- print和return都是可以以常数为值或者变量的,如果是用字符串存的值,要注意-a或者–a的bug
- 对关键词的识别要严格判断,不能用包含识别,同时“main”不是KEYWORD
- 在算中缀转后缀的时候要考虑最后栈形如-,3的情况,单独讨论
- 一点小技巧:可以维护变量的堆栈,当出现算式时,利用变量表直接将变量表达式替换为常量表达式