接上语义分析笔记
4.4 声明语句的翻译
- 声明语句的作用是位可执行语句提供信息,以便于其执行,主要操作为将所需要的正确信息填入符号表中对应位置。
- 变量声明和定义:一个变量的声明由两部分来完成:类型的定义和变量的声明。类型定义为编译器提供存储空间大小的信息,变量声明为变量分配存储空间。
offset
是全局变量,初值为0,代表符号表中每个条目的起始位置。- 过程
enter(name, type, offset)
表示往符号表中填入变量名为name,类型为type,起始位置为offset的条目。 - 不一定每个产生式都有语义翻译,比如
D->D;D
。 - 考法:给定文法,程序 | 给出分析树,语义翻译表,然后给出填好的符号表内容。
创建分析树时,利用产生式进行推导,从上往下构建。多个相同的终结符按照归约的顺序进行编号。
4.5 简单的算术表达式和赋值句
- 算术表达式的计算:如果最终要得到表达式的值,则只需要在归约时将属性向上综合即可,即操作的是右值;而如果需要得到三地址码,则需要操作左值(即地址)。如下简单的表达式:
- 其中,过程
emit(result ':=' arg1 'op' arg2)
产生一个三地址码(result := arg1 op arg2),过程entry(name)
用来获得符号表中的条目。newtemp
表示申请一个临时变量,在翻译方案中用ti表示,i从1开始编号。 - 由于变量有整型和实数型,因此复杂的表达式应加入变量类型转换,即加入两条三地址码指令:
T := itr E
和T := rti E
,变量间的转换原则如下:
- 考法:给定翻译方案,产生式和表达式 | 给出注释分析树,和分析过程及中间代码。
注意类型转换也要产生临时变量ti,op(+和*)的右上角应该标注i或r,表明是整型计算还是实数型。注释分析树如下所示:
4.6 布尔表达式
- 布尔表达式被用于逻辑运算或者控制语句转移的控制条件两个方面。
- 布尔表达式的计算有两种方式,一种是当做数值表示,直接计算;另一种是逻辑表示的短路计算。
- 因为布尔表达式仅有真假两种取值,且确认整个式子的真假后就不必再往后计算了,因此通常采用短路计算。
- 短路计算需要添加两种新属性,
true
表示表达式的真出口,即指向表达式为真时的转向;false
表示表达式的假出口,指向表达式为假时的转向。这两种属性是继承属性,即需要对分析树从上往下遍历来得到。 - 符号表示:
newlabel
生成标号Li
,i从1开始,LT
表示整个表达式的真出口(表达式为真),LF
表示整个表达式的假出口(表达式为假)。 - 如
E -> E1 or E2
对应语法制导翻译为:{E1.true := E.true; E1.false := newlable; E2.true := E.true; E2.false := E.false; }
,而E -> E1 and E2
对应的语法制导翻译为:{E1.false := E.false; E1.true := newlabel; E2.false := E.false; E2.true := E.true; }
这里省略了对代码序列的翻译。 - 由于可能会有多个三地址码指向同一个转向不确定的地址,在该地址转向确定后,需要一个个回填,较为麻烦,因此引入了拉链。为此,需要再新增两个属性:
tc
为真出口链,链接所有转向真出口的三地址码,fc
为假出口链,链接所有转向假出口的三地址码。一旦转向的地址被确定,可以沿着链来回填。
知识补充
- 其实加入一种新的语义,只需要在原来的翻译方案基础上,加入新的属性即可。