语法制导的语义计算
1.基本概念
-
属性文法:在文法G[S]的基础上,为文法符号关联有特定意义的属性,并为产生式关联相应的语义动作或条件谓语,称之为属性文法,并称文法G[S]为之的基础文法。
属性文法AG是一个四元式,即AG = (G, A, R, B):G是上下文无关文法,A是属性的有限集合,R是语义规则式的有限集合,B是样式的有限集合。
例子:
产生式 语义动作 S -> ABC {B.in_num := A .num;
C.in_num := A .num;
if (B.num=0 and (C.num=0)
then print(“Accepted!” )
else print(“Refused!” ) }A -> A1a { A.num := A1.num + 1 } A -> ε { A.num := 0 } B -> B1b { B1.in_num := B.in_num; B.num := B1.num-1 } B -> ε { B.num := B.in_num } C -> C1c { C1.in_num := C.in_num; C.num := C1.num-1 } C -> ε { C.num := C.in_num } -
两种属性:
综合属性:用于“自下而上”传递信息
对关联于产生式A -> α
的语义规则b:=f(c1, c2, …, ck)
,如果 b 是 A的某个属性, 则称 b 是 A 的一个综合属性 。继承属性: 用于“自上而下”传递信息
对关联于产生式A-> α
的语义规则b:=f(c1, c2, …, ck)
,如果 b 是产生式右部某个文法符号 X 的某个属性,则称 b 是文法符号 X 的一个继承属性。例子:
在上例的属性文法中A .num,B.num 和 C.num 是综合属性值,而B.in_num 和 C.in_num 是继承属性值。比如在产生式
C -> C1c
中,C1.in_num 是产生式右部符号C1的属性,由产生式左部符号C的in_num 属性确定,所以它是继承属性,“自上而下”的传递信息;C.num 是产生式左部符号C的属性,由产生式右部符号C1的num属性确定,所以它是综合属性,“自下而上”的传递信息。 S-属性文法:只包含综合属性的属性文法。
L-属性文法:可以包含综合属性,也可以包含继承属性。但产生式右端某文法符号的继承属性的计算只取决于该符号左边文法符号的属性(对于产生式左边文法符号,只能是继承属性)。
2.S-属性文法的语义计算
因为综合属性是“自下而上“的,所以采用自顶向下的方法。
若采用LR分析技术,可以通过扩充分析栈中的域,形成语义栈来存放综合属性的值;
计算相应产生式左部文法符号的综合属性值刚好发生在每一步归约之前的时刻。
例子:
产生式 语义动作 S -> E { print(E.val) } E -> E1 + T { E.val := E1.val + T.val } E -> T { E.val := T.val } T -> T1 * F { T.val := T1.val ´ F.val } T -> F { T.val := F.val } F -> ( E ) { F.val := E.val } F -> d { F.val := d.lexval } LR分析过程伴随算术表达式2+3*5的求值