审查每一个语法结构的静态语义,即验证语法正确的结构是否有意义。
语义分析的范围:确定类型、类型检查、识别含义、控制流检查、一致性检查、相关名字检查。
1、后缀式(逆波兰表示法):运算符在后
2、图表示法
(1)抽象语法树:后缀式实际上是抽象语法树的线性表示形式(后序表示)。
(2)无循环有向图(DAG):对表达式中的每个子表达式,DAG中都有一个结点。一个内部结点表示一个操作符,它的孩子表示操作数。
区别:在一个DAG中代表公共子表达式的结点具有多个父结点,而在一棵抽象语法树中公共子表达式被表示为重复的子树。
3、三地址代码
由x:=y op z形式的语句构成的序列。通常有三种表示方法:
(1)四元式:带有四个域op,arg1,arg2及result的记录结构,实际上就是一条三地址的指令
(2)三元式:由三个部分组成:算符OP、第一运算分量ARG1、第二运算分量:ARG2
(3)间接三元式:在三元式的基础上附加一张指示器表─间接码表,按运算的先后顺序列出有关三元式在三元式表中的位置
1、赋值语句的翻译
2、布尔表达式的翻译
作为条件的布尔表达式,把它设计成两个出口:E.true 和 E.false
3、数组元素的表达式和赋值句的翻译
一般编译程序对数组说明的处理是把数组的有关信息汇集在一个叫“内情向量”的表格中。
若数组A的元素存放在一片连续单元里,假定数组的每个元素的宽度为w,则一维数组A[i] 这个元素的起始地址为:base + (i – low)*w,可整理为:i*w + (base –low*w)
其中low为数组下标的下界,base是分配给数组的相对地址,即base为A的第一个元素A[low]的相对地址。
(1) i*w 是随数组下标变量而变化的部分,记为VARPART
(2)(base – low*w)是在数组中不变化的常数记为CONSPART
若二维数组A按行存放,则A[i1,i2]的相对地址:base + (( i1 – l1)*d2 + i2 – l2) *w
一组是计算VARPART,并将计算结果放入临时变量T1,
另一组是计算CONSPART,并将计算结果放入临时变量T2,用T2[T1]表示数组元素的地址。
4、控制语句的翻译
仿照算术表达式的翻译来进行,对于控制语句中的条件表达式,必须结合控制语句作进一步的分析。
可以把作为控制条件的任何布尔表达式表示成仅含下列三种形式的四元式的序列:
(jnz,a,--,p) 表示 if a goto p
(jrop,x,y,p) 表示 if x rop y goto p
(j,--,--,p) 表示 goto p
while a<b do
if c<d then
x:= y+z
else
x:=y-z
根据前面所述,生成代码为:
L1 :if a<b goto L2
goto Lnext
L2 :if c<d goto L3
goto L4
L3 :t1 := y+z
x:=t1
goto L1
L4 :t2:=y-z
x:=t2
goto L1
Lnext:
第七章感觉是这些章节里面难度最小的一章了,比较容易掌握,知识脉络也很清晰。重点就是掌握中间语言的各种表示方法和基于语法制导的翻译,如赋值语句的翻译、布尔表达式的翻译、数组的翻译以及控制语句的翻译。