OUC编译原理实验报告 实验4:验证Yacc的使用/实验e4:从语言SUM到栈式计算机STACK的机器语言的翻译

编译原理实验报告

实验4:验证Yacc的使用

实验e4:从语言SUM到栈式计算机STACK的机器语言的翻译

中国海洋大学编译原理实验2023春
仅供同学参考思路 请勿直接抄袭 否则可能喜提0分

目录

一.实验目的

实验4:

熟悉语法分析器生成工具Yacc的使用,并学会在实验环境下使用bison工具编译Yacc文法说明文件。学习如何使用lex和yacc合作进行语法分析。

实验e4:

熟悉语言SUM 到栈式计算机STACK的机器语言的翻译过程,理解编译的一般步骤。

二.实验内容

实验4

根据给出的calculator例子(calculator0,calculator1,calculator2,calculator3)

完成下面题目:用lex和yacc写一个计算布尔表达式真值的计算器。

实验e4

sum.c是用c语言写的从sum语言到栈式计算机STACK的机器语言的编译器(省略了词法语法分析部分)。

该程序的基本功能是先构造SUM语言的某句子的抽象语法树,然后将该语法树翻译成STACK的机器语言程序,并按顺序打印出该机器语言程序的指令。

程序中有两段内容不完整(在程序中用TODO表示),请读懂并编译通过该程序,再将TODO的部分补充完整,并编译通过。

三.实验要求

实验4

输入为一个布尔表达式,以换行结束。输出为这个布尔表达式的真值(true或false)。

尝试二义文法和非二义文法两种不同的实现方式。布尔表达式二义文法为:

S –> S or S |

S and S |

not S |

(S) |

true |

false,其中优先级or < and < not,or 和 and 左结合,not 右结合。

非二义文法请参照表达式非二义文法自己写出来。

在实验环境下用flex,bison和gcc工具将实验调试通过,并写出测试例测试正确性。

实验e4
  1. 读懂程序sum.c并编译通过。(该程序可以使用gcc编译通过,其他编译环境请自行调试)

  2. 用你自己写的程序段替换程序中的TODO部分,使程序功能与实验内容的描述一致。

  3. (此要求为额外要求,供学有余力的同学自行选择。)将程序的输入改为句子1+(2+3)的抽象语法树,尝试程序能否输出正确的结果。

四.实验过程及重点内容

实验4:

本实验需要编写两个文件 一个是词法分析器的lex文件 一个是语法分析的yacc文件

二义性文法:

lex需要用到的记号

image-20230525004943517

yacc:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CC1jnclr-1687580593336)(null)]

token定义了所有终结符

left和right定义了左右结合性 从上至下代表着优先级从低到高

image-20230525005141443

定义文法boool

$$代表左侧记号属性值 %i代表右侧第i个记号的属性值

根据布尔运算的定义 右侧用C语言计算属性值

阅读yacc使用指南 对.y和.l文件进行编译链接

image-20230525005509754

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9WVwLPzH-1687580524132)(null)]

在ERYI.l中加入头文件引用

image-20230525005530418

最后使用gcc编译器 生成e4.exe

测试结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UD5RRAlg-1687580524861)(null)]

与预期结果相等 括号也可正常识别

非二义性文法:

主要修改yacc文件中的文法

优先级从低到高
S->S or T | T
T->T and F | F
F->not F | (S) | false | true

image-20230525145053953

编译运行生成的exe文件 测试用例为:

true or not true and false
false or (not true and true)
false or not (true and false)
false or not true and false

结果符合预期输出:

image-20230525145229836

实验e4:

首先读懂main函数:

image-20230525153918045

由Exp_sum_new和exp_int_new构成了一棵加法的二叉树

Exp_print函数则是分析语法树,输出语法树对应的表达式是什么

image-20230525154014399

接下来由compile函数对二叉树进行后续遍历,如果是INT结点直接入栈

如果是SUM结点则继续遍历,并把ADD入栈

最后由List_reverse_print函数输出链表的结果

compile函数

image-20230525154302571

INT结点直接将值入栈

SUM结点继续递归后序遍历 并把ADD入栈

print函数

image-20230525154357409

先对list_new函数进行分析 由分析可知链表采用的是头插法

例如1+2 链表中储存的顺序由头节点开始应为 ADD->2->1

但实验要求翻转输出 函数名也对应为reverse_print

接下来对list链表进行逆序输出:

我采取的做法是将list再次使用头插法重新插入到一个新链表中 再次输出链表则为逆序

定义新结点类型:

image-20230525161134865

使用头插法把结点插入新链表中

image-20230525161148856

直接顺序遍历新链表:

image-20230525161220822

结果如下:

image-20230525161241889

修改语法树为1+(2+3)

image-20230525161520591

结果正常输出:

image-20230525161539164

五.实验结果

实验4

二义性文法:

image-20230525005616709

非二义性文法:

image-20230525145053953

实验e4:

image-20230525161241889

image-20230525161539164

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值