语法制导的语义计算
1 基于属性文法的语义计算
1.1 属性文法
1.1.1 引子
我们在文法 G[S] 基础上,为文法符号关联有特定意义的属性,并为产生式关联相应的语义动作或条件谓词,称之为属性文法,并称文法 G[S] 是这一属性文法的基础文法
设文法符号 X 关联一个属性 a,我们用 X.a 来表示对这个属性的访问。为了明确指出一个属性值对应于当前产生式中哪个位置的文法符号,在书写同一个文法符号时,我们会用到文法符号的下标形式。
在属性文法中,每个产生式 A → α 都关联一个语义计算规则的集合,如上面例子中花括号内的部分。每个语义计算规则或者是一个语义动作,或者是一个条件谓词。语义动作 b := f(c1, c2,…, c**k),
b, c1, c2,…, c**k 对应产生式中某些文法符号的属性。f 是用于描述如何计算属性值的函数,或称为语义函数
语义动作也可以只包含一个语义函数,形如 X.a := Y.b 的语义动作称为复写规则。
1.1.2 综合属性和继承属性
对关联于产生式 A → α的语义动作 b := f(c1, c2,…, c**k),如果 b 是 A 的某个属性, 则称 b 是 A 的一个综合属性。从分析树的角度来看,由于计算综合属性是对父结点的属性赋值,所以是“自底向上”传递信息。对关联于产生式 A → α 的语义动作 b := f(c1, c2,…, c**k),如果 b 是产生式右部某个文法符号 X 的某个属性,则称 b 是文法符号 X 的一个继承属性。从分析树的角度来看,由于计算继承属性是对子结点的属性赋值,所以是“自顶向下”传递信息。
对关联于产生式 A → α的语义动作 b := f(c1, c2,…, c**k),如果 b 是 A 的某个属性, 则
称 b 是 A 的一个综合属性。从分析树的角度来看,由于计算综合属性是对父结点的属性
赋值,所以是“自底向上”传递信息。
对关联于产生式 A → α 的语义动作 b := f(c1, c2,…, c**k),如果 b 是产生式右部某个文法
符号 X 的某个属性,则称 b 是文法符号 X 的一个继承属性。从分析树的角度来看,由于
计算继承属性是对子结点的属性赋值,所以是“自顶向下”传递信息。
图中的属性是综合属性。自底向上传递信息,类似于对于树的后序遍历
B,C两个分支是先将信息向下传递,将信息传递回去,进行计算。
1.2 遍历分析树进行语义计算
基于属性文法,通过遍历分析树进行语义计算可以采取下列步骤:
• 构造输入串的语法分析树。
• 构造依赖图。
• 若该依赖图是无圈的,则按造此无圈图的一种拓扑排序对分析树进行遍历,从而计
算所有的属性值。若依赖图含有圈,则这一步骤失效。
1.3 S-属性文法和L-属性文法
只包含综合属性的属性文法称为 S-属性文法。
一个属性文法称为 L-属性文法,如果对其中每一个产生式 A → X1 X2... Xn,其每个语义动作所涉及的属性或者是综合属性,或者是某个 Xi(1≤i≤n)的继承属性,而这个继承属性只能依赖于:
(1) Xi 左边的符号 X1 X2... Xi-1 的属性;
(2) A 的继承属性。
通俗地说,L-属性文法既可以包含综合属性,也可以包含继承属性,但要求产生式右端某文法符号的继承属性的计算只取决于该符号左边符号的属性 (对于产生式左部的符号,只能是继承属性)。
容易看出,S-属性文法是 L-属性文法的一个特例。
1.4 基于S-属性文法的语义计算
由于综合属性是自底向上传递信息,因而基于 S-属性文法的语义计算通常采用自底向上的方式进行。