基于扩展C0文法的编译器设计(Part2)
来源:互联网 发布:c语言头文件有哪些 编辑:程序博客网 时间:2024/05/12 02:09
2.类/方法/函数功能
词法分析部分:
中间代码生成:
目标程序生成:
由于笔者选择mips作为最终的目标代码,因此对文法分析后判断需要实现的mips指令表如下:
由上表可以得到一部分汇编相关的函数:
错误处理:
优化部分:
3.调用依赖关系
4.符号表管理
为了便于实现,这里采用无序符号表的组织方式。
具体的符号表数据结构如下:
5.存储分配方案
原计划寄存器分配采用启发式图着色算法。采用该方法的主要目的是为了避免因引用计数法带来的全局寄存器前中后期分配不均问题。具体实现时,采用了固定寄存器分配(只使用t1,t2两个临时寄存器,随用随取)。
运行栈设计采用课本介绍的经典动态存储分配方式,图示如下:
6. 解释执行程序
本程序不采用解释执行程序,而是编译执行。
7. 四元式设计
对于整个文法而言,可能出现的有关数据的操作和对应的四元式设计如下表:
8. 目标代码生成方案
目标代码生成的主要任务包括:从中间代码到目标代码的转换过程中进行指令选择,目标代码地址空间的划分,目标体系结构上寄存器和内存单元的分配和指派,目标代码序列的生成等。在这一过程中,主要考虑:
1. 如何为中间代码选择语义等价且运行效率高的目标指令;
2. 为目标代码、局部变量、全局变量、静态变量、临时变量、常量等指定和划分地址空间;
3. 由于源程序和中间代码中的变量和数据结构的显示定义都将消失,取而代之的是具体的寄存器编号和内存空间地址等,因此需要准确合理的将这些寄存器和内存单元分配给不同类型和结构的变量;
4. 生成和输出目标代码序列到文件。在这一过程中,目标代码的序列和输入的中间代码序列在顺序上可以一致,也可以不一致,在保证语义不变的前提下,尽量选择更高执行效率或者更小存储空间的代码序列。
9. 优化方案
1.窥孔优化(未实现)
在采用中间代码到目标代码逐条生成的过程中,目标代码中经常会出现代码的冗余或者低效率的指令,为了消除这种指令,我们采用窥孔优化的方式处理。窥孔优化关注在目标指令的一个较短序列上,通过删除冗余代码或者替换更高效和简洁的代码来使得最终得到的目标代码是高质量的。
2.常数合并
如果在编译的时候,对于某些表达式的部分或者全部操作数的值,则此表达式就会被优化,将已知值的操作数进行可以进行的运算后再与变量进行运算。
3.常量替换
在编译之初就将所有常量替换为值,不在对常量进行取址等操作。
4.消除公共子表达式(未实现)
10. 出错处理
错误处理方案:
#define FILEOPEN_ERROR -1 //file open failed
#define ZEROSTART_ERROR 0 //
#define UNDEFFUNC_ERROR 1
#define UNDEFCHAR_ERROR 2 //undefined IDEN
#define UNMATCHSQ_ERROR 3 //unmatched singal quoto
#define UNMATCHDQ_ERROR 4 // unmatched double quoto
#define OUTOFTABINDEXX_ERROR 5 // out of table max length
#define FUNCNAMECOMPLICT_ERROR 6 // function name conplict
#define VARNAMECOMPLICT_ERROR 7 //variable name complict
#define NAMECOMPLICTGLOBAL_ERROR 8 //name can not complict with global
#define DELHEAD_IDMIS_ERROR 9 // id missed in delcare head part
#define AFTERASS_NOTIDEN_ERROR 10 // after a assign symbol should be a dientifier symbol
#define CONSTDEF_ASSMIS_ERROR 11 // in a const defination assign symbol missed
#define CONSTDEF_TYPE_ERROR 12 // const defination have only two type
#define SEMICSYMMIS_ERROR 13 // ; missed
#define VARDEF_ARRAYINDEX_ERROR 14 //an array index should be number in variable defination
#define VARDEF_TYPE_ERROR 15 // in a vardefine, identifier type error
#define MAINSYM_ERROR 16 // in a main function, name must be ”
#define LPARENSYMMIS_ERROR 17 // main ( missed
#define RPARENSYMMIS_ERROR 18 // main ) missed
#define LBPARENSYMMIS_ERROR 19 // mian {
#define RBPARENSYMMIS_ERROR 20 // main }
#define RMPARENSYMMIS_ERROR 21 // ] missed
#define AFTEROP_NUMMIS_ERROR 22 // -56 ok, -b not accepted
#define FACTOR_ERROR 23 // factor type error
#define ASSIGNSTATUS_ERROR 24 // assign status error
#define STATUS_ERROR 25 // status error
#define CONDITIONOP_ERROR 26 // condition status error
#define WHILESYMMIS_ERROR 27 // while symbol missed
#define IDSYMMIS_ERROR 28 // in a for loop, identifier missed in initial
#define FORASSIGNMIS_ERROR 29 // int a for loop initial, assign symbol must appeare
#define VARTYPE_ERROR 30 // in a for loop, loop variable should not be a const
#define FOROPMIS_ERROR 31 // in for loop step part, op(+/-) missed
#define FORDIGSYM_ERROR 32 // in for loop step part, digital missed
#define VOIDSYMMIS_ERROR 33 // in main function, void symbol missed
#define PARANUM_ERROR 34 // paramenter number error
#define UNEXCEPTRETURNVAL_ERROR 35 // void function return value
#define READARRAY_ERROR 36 // read an array name
错误处理方式:
1.递归子程序发现错误立即调用error()并传递出错信号;
2.error函数通过接收到的出错信号打印出出错信息和位置信息;
3.通过出错类型型号和位置判断应该如何进行跳读;
4.继续编译,直到文件结束。
三.操作说明
1.运行环境
运行环境为32位Win7系统,运行软件为CodeBlocks13.12版本。
2.操作步骤
打开final.cbp文件,输入目标文件所在位置(绝对位置或者相对位置均可)。
四.测试
内容略,已经过集成测试
- 基于扩展C0文法的编译器设计(Part2)
- 基于扩展C0文法的编译器设计(Part1)
- 基于扩展C0文法的编译器设计(Part3)
- 编译器学习--文法的类型
- 编译器设计:文法与LL(1)
- 编译器之简单的类C文法
- 一个基于LL(1)文法的语法分析程序
- 基于LL(1)文法实现的简单计算器
- PL/0编译器设计扩展
- 编译器_文法分类
- 编译器的三个扩展
- 基于Predictive Parsing的ABNF语法分析器(十一)——AbnfParser文法解析器之重复文法(repetition)
- UTF-8 C0 控制与基本的 Latin(拉丁字母)
- 浅谈基于常用设计模式的扩展 。
- 基于文法分析的简单计算器实现
- 自己动手开发编译器(六)上下文无关语言和文法
- SPIR-V 研究:编译器基本原理(三) - Chomsky文法分类
- 自己设计的文法及其select集
- 页面满屏效果JS代码
- ng-model,ng-value,ng-bind,{{}}----angularJS数据绑定
- Android进阶学习之路
- Mac环境下Android Studio的部分快捷键整理
- redis数据结构HyperLogLog
- 基于扩展C0文法的编译器设计(Part2)
- EIRP/ERP(有效辐射功率)基本概念
- Linux内核启动过程和Bootloader(总述)
- 在windows系统中设置JVM(Java虚拟机)的内存
- PySNMP--GET command
- [数据库]数据库触发器
- case when then else end
- Android JNI入门第四篇——jni头文件分析
- VS Code --第二大React Native 编辑器