大三上学期做的一个小项目

类C编译器   

源代码和测试文件地址https://github.com/zxt1995/ttbox.git

 

总体框架: 读入待编译文件->语义分析并转换为指令->按照指令进行栈操作->得出结果

 

拓展部分(个人负责内容 其他内容在代码中有注释)

完成内容

Do while循环

Switch case语句

Goto语句

循环中Breakcontinue的实现

补充基础部分的短路计算

 

词法分析(switch)

Switch语句加入关键字 SYM_SWITCH,SYM_CASE,SYM_DEFAULT ,SYM_BREAK

加入新的OPR操作 OPR_CMP 保留栈顶和次栈顶 次栈顶是switch后面的选择表达式的结果值 栈顶为1(相等) 0(不相等)

语法分析(switch)

 

switch(expression)

begin

Case num1:

0跳转 Statement(若最后无break);

Case num2:   JMP到下一个Statement开头

0跳转 Statement(若最后有break);

Case num3:

0跳转 Statement;

Default:   JMP到结束

Statement;

end;

 

代码分析(switch)

 

pl0.h中加入全局变量

statement中 加入

Switch语句正常检测对应SYM 然后做一次表达式计算即可

switch语句的最后

要判断是否出现default来给最后一个case决定跳转位置

 

 

Case部分代码如下 default类似

 

 

Break 等待回填

 

 

 

截图示例(switch)

测试样例如下

左边是测试代码 右边是步骤

下面是结果 结果只计算了一开始i的赋值和p=30  j=40满足switch的语法规则

(这里结果是每次参数赋值之后的结果 后面的测试结果类同,组内其他成员实现了print函数可以输出特定的参数结果)

 

 

 

 

 

词法分析(goto)

加入关键字SYM_GOTO

加入新的label(字符型2元数组)

 

语法分析(goto)

 

 

begin:

statement

jmp statement

goto: label1;

Statement

label2:

statement

Statement jmp

goto: label2;

statement

label1:

statement

end;

只要匹配到对应的label就无条件跳转就可以

但是由于不知道对应的label是在哪里出现 所以要在block结束后再回填跳转指令

 

代码分析(goto)

首先在statementif(getsym()==SYM_IDENTI)中加入无法辨别的id将他判别为标识符

 

 

 

然后在statementif(getsym()==SYM_GOTO)中存入另一个label

 

 

 

 

最后在main函数的block之后进行字符串匹配就行

 

 

 

截图示例(goto)

测试样例如下

 

 

 

结果满足goto语法

 

 

 

词法分析(do while)

Statement中重写SYM_DO

 

语法分析(do while)

 

do

Statement 0跳转

while(expression);

 

代码分析(do while)

基本实现方式和while循环类似

 

 

截图示例(do while)

(continue break do while共同示例)

 

 

词法分析(break continue)

 

加入关键字 SYM_BREAK

   SYM_CONTINUE

加入全局变量

 

 

每次进入循环的时候 loopfi++ 出循环的时候loopfi-- 这样就不会在回填时出现失误

(注回填指令在出循环之后马上回填)

 

语法分析(break continue)

while循环为例(begin end总体归约为一个大的statement)

 

 

 

 

 

 

 

 

While(expression)

begin

Statement  无条件跳转到expression之前

Continue

Statement

break

Statement 无条件jmp到循环结束

Statement

End

 

代码分析(break continue)

do while语句 for循环语句 while循环语句中都有修改 以while语句为例

 

 

 

添加识别sym   Breakcontinue如下

 

 

 

截图示例(break continue )

附带do while

 

 

 

结果正确

 

 

 

 

 

 

词法分析(补充bool短路)

加入全局变量如下

加入和JPC相反的指令JNP不是0跳转

 

语法分析(补充bool短路)

先以一层为例

Expression简写为expi JNP到结束

 

 

 

JPC到同层第一个||之后

   多层就存到对应层的的trur_listfalse_list然后结束代表括号之后的位置即可

 

代码分析(补充bool短路)

如下以if语句为例

 

 

 

 

修改func_orfunc_and基本同上

or为例

 

 

遇到and更新假值链

遇到or更新真值链(同时填写同层与上一层的假值出口)

遇到Not交换真值假值链内容

 

示例截图

指令序列中不再出现opr_or opr_and

 

结果正确

 

 

总结(有什么能修改的地方)

Goto语句中label的数量

支持break continue的循环层数

Swich casecasebreak的数量 都有一定上限!!

有待更好的数据结构来表述而不是二维/一维数组

 

所有代码https://github.com/zxt1995/ttbox.git

 

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!