语法制导翻译的概念
输入文法和翻译文法
- 输入文法:未插入动作符号的文法。即先前在语法分析阶段使用的文法。由输入文法可以通过推导产生输入序列。
- 输入序列:仅由终结符组成的序列
- 翻译文法:插入了动作符号的文法。由翻译文法可以通过推导产生活动序列,包括输入序列和动作序列。
- 活动序列:包含终结符和动作符号的序列。执行活动序列中的动作序列,就完成了规定的翻译任务。
Example:
对于一个仅由i
,+
,*
,(
,)
组成的算术表达式,其输入文法可以是:
E
→ \rightarrow →E+T
E
→ \rightarrow →T
T
→ \rightarrow →T*F
T
→ \rightarrow →F
F
→ \rightarrow →(E)
F
→ \rightarrow →i
而其翻译为后缀波兰表达式的翻译文法可以是:
E
→ \rightarrow →E+T@+
E
→ \rightarrow →T
T
→ \rightarrow →T*F@*
T
→ \rightarrow →F
F
→ \rightarrow →(E)
F
→ \rightarrow →i@i
对于符号串
(i+i)*i
而言:
- 其输入序列即为
(i+i)*i
- 其活动序列为
(i@i+i@i@+)*i@i@*
- 其动作序列为
@i@i@+@i@*
执行动作序列,得到
ii+i*
,即完成了翻译任务。
语法制导翻译
语法制导翻译就是根据翻译文法获得翻译该符号串的动作序列,并执行该序列所规定的动作的过程。
在文法的适当位置插入语义动作符号,就将输入文法改造为了翻译文法。当按文法分析到动作符号时就调用相应的语义子程序,完成翻译任务。
属性翻译文法
属性文法是指在翻译文法的基础上,为各个符号(包括终结符、非终结符和动作符号)带上属性,并规定求值规则,能够更好的描述和实现编译过程。
属性分为两种:综合属性和继承属性
综合属性
自右向左、自底向上计算的属性。用 ↑ \uparrow ↑标记综合属性,加上综合属性常量或变量 c c c,就是综合属性符号 ↑ c \uparrow_c ↑c。
Example:
将之前的翻译文法加上综合属性,变为属性翻译文法:
E
↑ p _{\uparrow p} ↑p → \rightarrow →E
↑ q _{\uparrow q} ↑q+F
↑ r _{\uparrow r} ↑rE
↑ p _{\uparrow p} ↑p → \rightarrow →T
↑ q _{\uparrow q} ↑qT
↑ p _{\uparrow p} ↑p → \rightarrow →T
↑ q _{\uparrow q} ↑q*F
↑ r _{\uparrow r} ↑rT
↑ p _{\uparrow p} ↑p → \rightarrow →F
↑ q _{\uparrow q} ↑qF
↑ p _{\uparrow p} ↑p → \rightarrow →(E
↑ q _{\uparrow q} ↑q)
F
↑ p _{\uparrow p} ↑p → \rightarrow →i
↑ q _{\uparrow q} ↑q各条产生式对应的求值规则为:
- p p p:= q q q+ r r r
- p p p:= q q q
- p p p:= q q q* r r r
- p p p:= q q q
- p p p:= q q q
- p p p:= q q q
注:属性变量 p p p, q q q, r r r均为局部变量,作用于本产生式。
则对于输入序列
(i
↑ 3 _{\uparrow 3} ↑3+i
↑ 9 _{\uparrow 9} ↑9)*i
↑ 2 _{\uparrow 2} ↑2,
其综合属性的计算过程如下:
继承属性
自顶向下、自左向右计算的属性。用 ↓ \downarrow ↓标记继承属性。
Example:
给定声明语句的输入文法:
<声明>
→ \rightarrow →Type
id
<变量表>
<变量表>
→ \rightarrow →id
<变量表>
<变量表>
→ \rightarrow → ϵ \color{darkred}{\epsilon} ϵ为了完成填写符号表的翻译任务,将输入文法改写为属性翻译文法:
<声明>
→ \rightarrow →Type
id
@set_table
<变量表>
<变量表>
→ \rightarrow →id
@set_table
<变量表>
<变量表>
→ \rightarrow → ϵ \color{darkred}{\epsilon} ϵ仅有动作符号是不够的,要完成动作符号所规定的填表动作还需要参数,因此为动作符号带上类型和标识符两个属性,它们由
@set_table
左边的两个终结符Type
和id
得到。注意Type
和id
为底层的终结符,因此它们的属性记为综合属性:
<声明>
→ \rightarrow →Type
↑ t _{\uparrow t} ↑tid
↑ n _{\uparrow n} ↑n@set_table
↓ t 1 , n 1 _{\downarrow t_1, n_1} ↓t1,n1<变量表>
↓ t 2 _{\downarrow t_2} ↓t2<变量表>
↓ t 2 _{\downarrow t_2} ↓t2 → \rightarrow →id
↑ n _{\uparrow n} ↑n@set_table
↓ t 1 , n 1 _{\downarrow t_1, n_1} ↓t1,n1<变量表>
↓ t 3 _{\downarrow t_3} ↓t3<变量表>
↓ t 2 _{\downarrow t_2} ↓t2 → \rightarrow → ϵ \color{darkred}{\epsilon} ϵ对应的赋值规则为:
- t 1 t_1 t1, t 2 t_2 t2:= t t t; n 1 n_1 n1:= n n n
- t 1 t_1 t1, t 3 t_3 t3:= t 2 t_2 t2; n 1 n_1 n1:= n n n
应用:对于声明语句
int
A
,BC
翻译如下:
得到的动作序列为
@set_table
↓ i n t , A _{\downarrow int, A} ↓int,A@set_table
↓ i n t , B C _{\downarrow int, BC} ↓int,BC。执行该序列即可完成填符号表的翻译任务。
L属性翻译文法(L-ATG)
L-属性翻译文法定义为带有下列说明的翻译文法:
- 文法中的终结符,非终结符及动作符号都带有属性,且每个属性都有一个值域。
- 非终结符及动作符号的属性可分为继承属性和综合属性。
- 开始符号的继承属性具有指定的初始值。
- 输入符号(终结符号)的每个综合属性具有指定的初始值。
- 给定属性的求值规则。
因此,L-ATG是属性翻译文法中较简单的一种。其输入文法要求是LL(1)文法,可用自顶向下分析构造分析器。在分析过程中可进行属性求值。
简单赋值形式的L属性翻译文法(SL-ATG)
其定义为:
- 产生式右部符号的继承属性是一个常量,它等于左部符号的继承属性值或等于出现在所给符号左边符号的一个综合属性值。
- 产生式左部非终结符号的综合属性是一个常量,它等于左部符号的继承属性值或等于右部符号的综合属性值。
也就是说,SL-ATG对于综合属性或继承属性,不使用形如x:=f(y,z)的函数来计算,而是直接如x:=y一样赋值。
因此,一个SL-ATG除动作符号外,其余符号的属性求值规则的右部都是属性或是常量。即:其规则都是复写规则。