Complete a compiler of cool language.
- PA2 lexer /done
- PA3 parser /done
- PA4 semant analyse /done
- PA5 code generation /done
记录自己的学习
-
词法分析,在这里用的是flex这个工具
-
编程语言是由代码和注释构成的,而代码里一定包含了各种关键字等,这些东西被称为token
-
词法分析器就是将整个源文件拆分成一个一个token,输出到parser中来构建AST(抽象语法树)
-
flex是用正则表达式来对源代码进行词法分析的,这些正则表达式就不在这里赘述,可以去看flex的手册
-
自动机是实现词法分析的一个重点
-
自动机当接受到特定输入的时候就会从一个状态跳到另一个状态
-
一个词法分析中的例子:
- 当匹配到//开头的文本的时候,会切到匹配注释的模式,直到匹配到换行。
- 当匹配到' " '的时候,切换到匹配字符串的模式,直到匹配另一个' " '
-
吞掉注释
-
将源代码拆分成token
- 数字常量,字符串常量
- 变量名称
- 函数名称
- 系统关键字
-
准确性:在遇到unexpected的情况时,可以处理,不会进行错误的匹配
-
代码已上传至PA2的文件夹.
-
语法分析,将词法分析器的结果构建成AST
-
用了bison这个工具
-
bison需要手写文法来构建AST
-
需要规定运算符的优先级来对表达式进行AST的构建
- 在cool的手册里有写,这里不多赘述
- bison采用了自底向上的规约方法来分析
- 代码已上传至PA3
- 语义分析,对AST进行一些检查,对不合规范的代码抛出异常
- 类,会对类进行一系列检查,包括属性,方法的检查
-
继承图,包含了父类和子类之间的继承关系
-
会对继承关系的合法性进行检查,例如
- 父类是否是可继承的
- 父类是否定义
-
作用域
-
每个变量都有自己的一个作用域,因为有可能两个变量有相同的名字
-
在规定了作用域后,变量名发生冲突时就可以按照变量的作用域选择对应变量
-
在规定作用域后,在对变量进行使用的时候就会检查是否在它的域内,如果没有则会抛出错误
-
对类型进行检查
- 对类型定义了一个比较的运算,这是为了方便进行类型转换
- 查找这个类型是否被定义
- 变量的值是否符合定义的类型
-
类的属性检查:
- 是否定义了属性的类型
- 属性的类型和初始化方法里的类型是否相同或者可以转换
-
类的方法检查:
- 是否定义了属性的类型
- 类的返回值类型是否和返回类型相同或者可以转换
-
对参数类型的进行检查
- 参数的类型是否定义
- 类型是否是self,参数类型不可以是self
- 是否多次重复定义参数。
-
代码已上传至PA4
- 生成MIPS汇编代码
- 由于是抄的代码,当时状态也很差,没有很好的思考
- MIPS拥有的寄存器还是很多的,但是这个实验运用的机器模型只用很少的寄存器
- 每次计算的结果保存在ACC寄存器里。
- 在进行二元运算的时候,会引入t1这个寄存器,然后将操作数分别load到a0和t1进行运算
- 结果保存在ACC中
- stack是用来保存临时变量和函数调用现场以及参数的。
- 由高地址向低地址生长。
- 在调用函数的时候:
- 参数从右到左依次入栈,
- 保存caller的栈桢
- 保存caller的寄存器
- 为函数所需要的临时变量开辟空间
- 代码已上传至PA5