实验五 语法制导翻译和中间代码生成

一、实验目的

1. 学习和掌握语法制导翻译和中间代码生成

2. 实现TINY+语言的语法制导翻译及赋值语句的中间代码生成

二、实验内容与要求

  1. 实验内容

任务:实现语法制导翻译及赋值语句的中间代码生成

在前序实验中已实现了TINY+语言的词法分析及语法分析,本次实验要求基

于前序实验基础,实现TINY+语言的语法制导翻译及赋值语句的中间代码生成。

具体要求:

对于输入赋值语句a := b * c + d,应翻译成以下三地址码序列:

t1 := b * c

t2 := t1 + d

a := t2

请修改TINY+的语法分析程序,添加语义翻译代码,实现对任意TINY+赋值语句的语义翻译及中间代码的生成。

三、实验步骤与过程

1. 理解三地址码

在前序实验中,我们已实现了TINY+语言的词法分析及语法分析,本次实验要求基

于前序实验基础,实现TINY+语言的语法制导翻译及赋值语句的中间代码生成。

根据要求,中间代码的生成采用的是三地址法的形式进行,对于三地址码,是指这种代码的每条指令最多只能包含三个地址,即两个操作数地址和一个结果地址。下面我们来看一个例子,赋值语句a:=(-b)*(c+d)-(c+d)的三地址码如下图所示:

 三地址码中地址的形式包括名字、常量、编译器生成的临时变量。

2. 实现思路

对于语法制导翻译功能以及中间代码生成,我们可以添加到规约的时候进行,因为在语法树构建时,已经确定了语法树的构造,赋值语句的层级结构也已经确定,所以可以对其进行分析,每个简单式都为中间代码的产生,如a*(/)b或a+(-)b为最基本单元,即为t1,然后判断其是否为其余形式的匹配。

具体实现思路如下:

首先判断递归到的赋值语句是否为表达式,如果为表达式,则对其进行标号,从t1开始,而本次实验只要求输出,所以不对其进行进行存储,不存储其值也可以降低其内存开销。如果需要存储,可以设置四个队列,即arg1,arg2,op3,result,用来存储中间过程产生的式子。

然后判定优先级,要对exp的两个child结点均判定。由于exp的两个子节点都可以是exp,所以在输出的时候需要对其进行判定,直到进入到最底层进行输出。一般而言,乘除的优先级是高于加减的,也就是说,如果一个式子同时含有加减乘除,乘除会因为语法树在更底层,所以会优先运算。即其在最底层的子节点内,所以需要等待所有子节点进行判断,在进行输出。

具体流程如下:

  1. 判定当前输出的语法树是否为exp表达式,赋值语句后肯定跟随表达式类型。
  2. 判定表达式的child结点是否为exp
  3. 如果为exp结点,则其已经被访问过,则其应该用之间访问过后代表的ti来代表。
  4. 如果子节点不为exp,则输出其对应变量的值/name。以及对应的操作

3. 具体实现

我们在utlc.c中的printTree函数对于输出语法树的过程中,如果子节点已经完全被递归执行,则其已经到达最底层。获取exp结点的操作符,即加减乘除。

接下来对它的孩子结点的类型进行判断,执行不同的输出。其中用变量count来计数,从1开始,区分不同的ti。

最后再对赋值语句的结点进行判断,如果为赋值语句所产生的结点,则只会是两种状态形如 a:=b 或 a:=exp中其中一种,对其进行分别输出,如果a:=b则此时不会产生新的ti,则count此时等于0,输出name以及其孩子结点的name,如果count不等于0,则将最后的ti (i=count)赋值给tree->attr.name,即将其输出。

下面我们对程序进行测试:

首先对于赋值语句a:=b*c+d进行测试,得出结果如下:

可见符合给定的结果。

以下编写另一个的 TINY+ 测试程序。

\

得出结果如下:

其中复杂语句a:=a*a*c+b*d/a+b+a的翻译如下:

可见结果符合我们所预想的。

至此,我们完成了拓展语言 TINY+ 的语法制导翻译及赋值语句的中间代码生成的实现。

四、实验结论或心得体会

顺利的完成了实验,通过这次实验,我学习和掌握了语法制导翻译和中间代码生成,并根据以上知识完成了对拓展语言TINY+的语法制导翻译及赋值语句的中间代码生成。

这是本课程的最后一个实验,纵观整个学期,我们透过拓展语言TINY+实现了词法分析器、语法分析器等等的内容,对自顶向下的语法分析、自底向上的语法分析程序设计、语法制导翻译和中间代码生成有了更深入的了解,总的来说是一次不错的体验,让我学到了很多有趣的知识。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值