其他分享
首页 > 其他分享> > 语法制导翻译和中间代码生成

语法制导翻译和中间代码生成

作者:互联网

本文参考《编译原理(第三版)》

目录

语义分析概述

语义分析任务

语法制导翻译

语法制导翻译(syntax-directed translation)是目前大多数编译程序采用的一种技术

语法制导翻译


注释分析树


语法制导定义

:表达式求值的语法制导定义
在这里插入图片描述

:表达类型定义的语法制导定义( L . i n L.in L.in 为继承属性)
在这里插入图片描述

属性文法


表达式文法 G [ E ] , E → T + T ∣ T     T → n ∣ b G[E], E\rightarrow T+T|T \ \ \ T\rightarrow n|b G[E],E→T+T∣T   T→n∣b;有关类型匹配的属性文法如下:
在这里插入图片描述

综合属性


一种能够完成输出表达式值的符号串翻译文法如下,右列为相应产生式的属性求值规则
① S → E ↑ q @ A N S W E R ↓ r          r = q ② E ↑ p → E ↑ q + T ↑ r                          p = q + r ③ E ↑ p → T ↑ q                                     p = q ④ T ↑ p → T ↑ q ∗ F ↑ r                            p = q ∗ r ⑤ T ↑ p → F ↑ q                                      p = q ⑥ F ↑ p → ( E ↑ q )                                  p = q ⑦ F ↑ p → N U M ↑ q                              p = q \begin{aligned}① S&→E_{↑q}@ANSWER_{↓r}\ \ \ \ \ \ \ \ r=q\\ ② E_{↑p}&→E_{↑q}+T_{↑r}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p=q+r\\ ③ E_{↑p}&→T_{↑q}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p=q\\ ④ T_{↑p}&→T_{↑q}*F_{↑r}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p=q*r\\ ⑤ T_{↑p}&→F_{↑q}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p=q\\ ⑥ F_{↑p}&→(E_{↑q})\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p=q\\ ⑦ F_{↑p}&→NUM_{↑q}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p=q\end{aligned} ①S②E↑p​③E↑p​④T↑p​⑤T↑p​⑥F↑p​⑦F↑p​​→E↑q​@ANSWER↓r​        r=q→E↑q​+T↑r​                        p=q+r→T↑q​                                   p=q→T↑q​∗F↑r​                          p=q∗r→F↑q​                                    p=q→(E↑q​)                                p=q→NUM↑q​                            p=q​

继承属性


S → E ↑ q @ A N S W E R ↓ r , r = q S→E_{↑q}@ANSWER_{↓r} , r=q S→E↑q​@ANSWER↓r​,r=q


考虑下列声明语句文法
① < 声 明 语 句 > → T Y P E     I D < 变 量 表 > ; ② < 变 量 表 > → , I D < 变 量 表 > ③ < 变 量 表 > → ε ① <声明语句>→TYPE\ \ \ ID <变量表>;\\ ② <变量表>→,ID <变量表>\\ ③ <变量表>→ε ①<声明语句>→TYPE   ID<变量表>;②<变量表>→,ID<变量表>③<变量表>→ε


如果输入符号串为 i n t   a , b ; int\ a, b; int a,b;

属性文法举例—算术表达式的翻译


S S S 属性文法的自下而上翻译


如下的算术表达式的属性文法定义是 S S S 属性文法
① S → E ↑ x ② E ↑ x → E ↑ q + T ↑ r @ A D D ↓ q , r , x                x = N W E V ③ E ↑ x → T ↑ x ④ T ↑ x → T ↑ q ∗ F ↑ r @ M U L T ↓ q , r , x                x = N W E V ⑤ T ↑ x → F ↑ x ⑥ F ↑ x → ( E ↑ x ) ⑦ F ↑ x → i ↑ x \begin{aligned}① S&→E_{↑x}\\ ② E_{↑x}&→E_{↑q}+T_{↑r}@ADD_{↓q,r,x}\ \ \ \ \ \ \ \ \ \ \ \ \ \ x=NWEV\\ ③ E_{↑x}&→T_{↑x}\\ ④ T_{↑x}&→T_{↑q}*F_{↑r}@MULT_{↓q,r,x}\ \ \ \ \ \ \ \ \ \ \ \ \ \ x=NWEV\\ ⑤ T_{↑x}&→F_{↑x}\\ ⑥ F_{↑x}&→(E_{↑x})\\ ⑦ F_{↑x}&→i_{↑x}\end{aligned} ①S②E↑x​③E↑x​④T↑x​⑤T↑x​⑥F↑x​⑦F↑x​​→E↑x​→E↑q​+T↑r​@ADD↓q,r,x​              x=NWEV→T↑x​→T↑q​∗F↑r​@MULT↓q,r,x​              x=NWEV→F↑x​→(E↑x​)→i↑x​​


给定一个 S S S 属性翻译文法,如何构造翻译器?

L L L 属性文法的自上而下翻译

L L L 属性中的 L L L 表示 l e f t left left


< 声 明 语 句 > → T Y P E ↑ t I D ↑ n @ S E T _ T Y P E ↓ n 1 , t 1 < 变 量 表 ↓ t 2 > ; <声明语句>→TYPE_{↑t} ID_{↑n} @SET\_TYPE_{↓n_1,t_1} <变量表↓_{t_2} >; <声明语句>→TYPE↑t​ID↑n​@SET_TYPE↓n1​,t1​​<变量表↓t2​​>;属性求值规则: t 2 = t , t 1 = t , n 1 = n t_2=t,t_1=t ,n_1=n t2​=t,t1​=t,n1​=n

** L L L 属性文法翻译的实现——递归下降翻译

可采用递归下降法,完成 L L L 属性文法的翻译。步骤如下:

  1. 若该非终结符具有属性,那么该非终结符的分析过程就有形参,且形参的数目就是该非终结符的属性个数
  2. 对于继承属性,采用值形参的传参方式将继承属性值传入被调过程
  3. 对于综合属性,采用变量形参的传参方式以便将值回传给主调过程 (指针 / 引用)

为了进行属性翻译的程序设计,我们采用下述约定:

中间代码的形式

逆波兰表示法

三元式

间接三元式

三元式的不足:

间接三元式


X : = ( A + B ) ∗ C Y : = D ↑ ( A + B ) X:=(A+B)*C\\ Y:=D↑(A+B) X:=(A+B)∗CY:=D↑(A+B)
在这里插入图片描述

树形表示


例: A ∗ ( B + C ) / D A*(B+C)/D A∗(B+C)/D
在这里插入图片描述


四元式

四元式特点


: A : = − B ∗ ( C + D ) A:=-B*(C+D) A:=−B∗(C+D) 的四元式
( 1 ) ( @ , B , _ , T 1 ) ( 2 ) ( + , C , D , T 2 ) ( 3 ) ( ∗ , T 1 , T 2 , T 3 ) ( 4 ) ( : = , T 3 , _ , A ) (1)( @, B, \_ , T_1 )\\ (2)( +, C, D, T_2 )\\ (3)( *, T_1, T_2, T_3 )\\ (4)(:=, T_3, \_, A ) (1)(@,B,_,T1​)(2)(+,C,D,T2​)(3)(∗,T1​,T2​,T3​)(4)(:=,T3​,_,A)

: a : = b ∗ c + b ∗ d a:=b*c+b*d a:=b∗c+b∗d 的四元式
( 1 ) ( ∗ , b , c , t 1 ) ( 2 ) ( ∗ , b , d , t 2 ) ( 3 ) ( + , t 1 , t 2 , t 3 ) ( 4 ) ( : = , t 3 , _ , a ) (1)( *, b, c, t_1 )\\ (2)( *, b, d, t_2 )\\ (3)( +, t_1, t_2, t_3 )\\ (4)( :=, t_3 ,\_, a ) (1)(∗,b,c,t1​)(2)(∗,b,d,t2​)(3)(+,t1​,t2​,t3​)(4)(:=,t3​,_,a)

: i f if if E E E o r or or ( B < C ) (B<C) (B<C) t h e n then then S 1 S_1 S1​ e l s e else else S 2 S_2 S2​ 的四元式
( 1 ) ( j n z , E , _ , 5 ) ( 2 ) ( j , _ , _ , 3 ) ( 3 ) ( j < , B , C , 5 ) ( 4 ) ( j , _ , _ , p + 1 ) ( 5 ) 与 S 1 相 应 的 四 元 式 序 列 ( p ) ( j , _ , _ , q ) ( p + 1 ) 与 S 2 相 应 的 四 元 式 序 列 ( q ) … \begin{aligned}&(1)(jnz,E,\_,\boldsymbol5)\\ &(2)(j,\_,\_,3)\\ &(3)(j<,B, C,\boldsymbol5)\\ &(4)(j,\_,\_, p+1)\\ &(5) 与S_1相应的四元式序列\\ &(p)(j,\_, \_,q)\\ &(p+1)与 S_2 相应的四元式序列\\ &(q)…\end{aligned} ​(1)(jnz,E,_,5)(2)(j,_,_,3)(3)(j<,B,C,5)(4)(j,_,_,p+1)(5)与S1​相应的四元式序列(p)(j,_,_,q)(p+1)与S2​相应的四元式序列(q)…​

简单赋值语句的翻译

本节讨论只含整型变量的简单赋值句的翻译,其文法描述:
S → i : = E E → E + E ∣ E ∗ E ∣ − E ∣ ( E ) ∣ i S→i:=E\\ E→E+E|E*E|-E|(E)|i S→i:=EE→E+E∣E∗E∣−E∣(E)∣i


语义变量与过程函数:

语义动作描述

在这里插入图片描述
在这里插入图片描述

A : = − B ∗ ( C + D ) A := - B * ( C + D ) A:=−B∗(C+D)

类型转换

引入类型信息语义量

语义规则
{ I F   E ( 1 ) . M O D E = i n t   A N D   E ( 2 ) . M O D E = i n t T H E N   E . M O D E : = i n t E L S E   E . M O D E : = r } \{ IF\ E^{(1)}.MODE = int\ AND\ E^{(2)}.MODE = int\\ THEN\ E.MODE := int\\ ELSE\ E.MODE := r\} {IF E(1).MODE=int AND E(2).MODE=intTHEN E.MODE:=intELSE E.MODE:=r}

类型转换四元式

布尔表达式的翻译

拉链回填


布尔表达式 a < b   o r   c > = d a < b\ or\ c >= d a<b or c>=d 的四元式
在这里插入图片描述
但注意到,上面的翻译其实是不合理的,因为没有考虑短路求值的特性
在这里插入图片描述



I F   A ∨ B < D   T H E N   S 1   E L S E   S 2 IF\ A∨B<D\ THEN\ S_1\ ELSE\ S_2 IF A∨B<D THEN S1​ ELSE S2​
在这里插入图片描述

文法定义

至于为什么这么改造,看了下面的具体操作步骤就明白了;中心思想是因为在自底向上分析中,符号串归约出栈之后,它们的属性也会删除,因此需要在归约时保存相应的信息 (在这个例子中,这个信息就是 T C TC TC 和 F C FC FC)

当然,这样改造不是唯一的


在这里插入图片描述

可以看到,每个语义动作中,如果产生式右部的 T C , F C TC,FC TC,FC 属性可以填写,就直接进行回填;如果目前还不能填,就由产生式左部的属性加以保存,在之后进行回填

3 3 3 为拉链回填的结果; 1 1 1 指向真链中的上一个四元组的位置

控制结构的翻译

标号和转移语句的翻译


标号语句的产生式
S → l a b e l   S l a b e l → i : S →label\ S\\label→i: S→label Slabel→i:

条件语句的翻译

i f if if

在这里插入图片描述



i f if if a < b a<b a<b o r or or c > d c>d c>d a n d and and e > f e>f e>f t h e n then then S 1 S_1 S1​ e l s e else else S 2 S_2 S2​ 的翻译
在这里插入图片描述

w h i l e while while


将 w h i l e ( A < B ) while(A<B) while(A<B) d o do do i f if if ( C < D ) (C<D) (C<D) t h e n then then X : = Y + Z X:=Y+Z X:=Y+Z 翻译成四元式
在这里插入图片描述

条件语句的文法

S → i f   E   t h e n   S ∣ i f   E   t h e n   S   e l s e   S ∣ w h i l e   E   d o   S ∣ b e g i n   L   e n d ∣ A L → L ; S ∣ S \begin{aligned} S \rightarrow& if\ E\ then\ S\\ &|if\ E\ then\ S\ else\ S \\ &|while\ E\ do\ S\\ &|begin\ L\ end\\ &|A\\ L\rightarrow& L; S\\ &|S\end{aligned} S→L→​if E then S∣if E then S else S∣while E do S∣begin L end∣AL;S∣S​


条件语句的语义动作

C → i f   E   t h e n { B A C K P A T C H ( E . T C , N X Q ) ; C . C H A I N : = E . F C } S → C   S ( 1 ) { S . C H A I N : = M E R G ( C . C H A I N , S ( 1 ) . C H A I N ) } T P → C   S ( 1 )   e l s e { q : = N X Q ; G E N ( j , _ , _ , 0 ) ; B A C K P A T C H ( C . C H A I N , N X Q ) ; T P . C H A I N : = M E R G E ( S ( 1 ) . C H A I N , q ) } \begin{aligned} C \rightarrow&if\ E\ then\\ \{ &BACKPATCH (E.TC, NXQ);\\ &C.CHAIN := E.FC \}\\ S \rightarrow&C\ S^{(1)}\\ \{&S.CHAIN := MERG(C.CHAIN, S^{(1)}.CHAIN)\}\\ T^P \rightarrow&C\ S^{(1)}\ else\\ \{ &q := NXQ;\\ &GEN(j, \_, \_, 0);\\ &BACKPATCH(C.CHAIN,NXQ);\\ &T^P.CHAIN := MERGE(S^{(1)}.CHAIN,q)\}\\\end{aligned} C→{S→{TP→{​if E thenBACKPATCH(E.TC,NXQ);C.CHAIN:=E.FC}C S(1)S.CHAIN:=MERG(C.CHAIN,S(1).CHAIN)}C S(1) elseq:=NXQ;GEN(j,_,_,0);BACKPATCH(C.CHAIN,NXQ);TP.CHAIN:=MERGE(S(1).CHAIN,q)}​

注意,上面的 q q q 为 G E N ( j , _ , _ , 0 ) GEN(j, \_, \_, 0) GEN(j,_,_,0) 的位置;而第三行的 N X Q NXQ NXQ 指的是 G E N ( j , _ , _ , 0 ) GEN(j, \_, \_, 0) GEN(j,_,_,0) 的下一个四元式的地址

S → T P   S ( 2 ) { S . C H I A N : = M E R G ( T P . C H I A N , S ( 2 ) . C H I A N ) } \begin{aligned} S\rightarrow&T^P\ S^{(2)}\\ \{ &S.CHIAN := MERG(T^P.CHIAN, S^{(2)}.CHIAN)\}\end{aligned} S→{​TP S(2)S.CHIAN:=MERG(TP.CHIAN,S(2).CHIAN)}​


W → w h i l e { W . Q U A D : = N X Q } \begin{aligned} W \rightarrow&while\\ \{ &W.QUAD := NXQ \}\end{aligned} W→{​whileW.QUAD:=NXQ}​

w h i l e while while 归约为 W W W 是因为要记录 d o do do 中循环体做完之后的跳回位置; W . Q U A D W.QUAD W.QUAD 即为循环体做完判断 E E E 的地方

W d → W   E   d o { B A C K P A T C H ( E . T C , N X Q ) ; W d . C H A I N : = E . F C ; W d . Q U A D : = W . Q U A D } S → W d S ( 1 ) { B A C H P A T C H ( S ( 1 ) . C H A I N , W d . Q U A D ) ; G E N ( j , _ , _ , W d . Q U A D ) ; S . C H A I N : = W d . C H A I N } \begin{aligned} W^d \rightarrow&W\ E\ do\\ \{ &BACKPATCH (E.TC,NXQ);\\ &W^d.CHAIN := E.FC;\\ &W^d.QUAD := W.QUAD \}\\ S \rightarrow&W^d S^{(1)}\\ \{ &BACHPATCH(S^{(1)}.CHAIN,W^d.QUAD);\\ &GEN(j,\_,\_, W^d.QUAD); \\ &S.CHAIN := W^d.CHAIN\}\end{aligned} Wd→{S→{​W E doBACKPATCH(E.TC,NXQ);Wd.CHAIN:=E.FC;Wd.QUAD:=W.QUAD}WdS(1)BACHPATCH(S(1).CHAIN,Wd.QUAD);GEN(j,_,_,Wd.QUAD);S.CHAIN:=Wd.CHAIN}​


L → S { L . C H A I N : = S . C H A I N } L S → L ; { B A C K P A T C H ( L . C H A I N , N X Q ) } L → L S   S ( 1 ) { L . C H A I N : = S ( 1 ) . C H A I N } S → b e g i n   L   e n d { S . C H A I N : = L . C H A I N } S → A { S . C H A I N : = 0 } 空 链 \begin{aligned} L \rightarrow&S\\ \{ &L.CHAIN := S.CHAIN\}\\ L^S \rightarrow&L;\\ \{ &BACKPATCH(L.CHAIN,NXQ) \} \\ L \rightarrow&L^S\ S^{(1)}\\ \{ &L.CHAIN := S^{(1)}.CHAIN\}\\ S\rightarrow&begin\ L\ end\\ \{ &S.CHAIN := L.CHAIN\}\\ S \rightarrow&A\\ \{ &S.CHAIN := 0\} 空链\end{aligned} L→{LS→{L→{S→{S→{​SL.CHAIN:=S.CHAIN}L;BACKPATCH(L.CHAIN,NXQ)}LS S(1)L.CHAIN:=S(1).CHAIN}begin L endS.CHAIN:=L.CHAIN}AS.CHAIN:=0}空链​


在这里插入图片描述

在这里插入图片描述

上图中省略了 W H I L E WHILE WHILE 归约为 W W W,保存 W . Q U A D W.QUAD W.QUAD 的过程


在这里插入图片描述

**分叉语句的翻译

// E 是一个整型表达式
// Ci 为常数
// Si 是语句
case E of 
	C1: 
		S1
	C2: 
		S2
	…
	Cn-1: 
		Sn-1 
otherwise: 
	Sn 
end
T := E;

L1: 
IF T≠C1 GOTO L2
S1;
GOTO NEXT 

L2: 
IF T≠C2 GOTO L3
S2;
GOTO NEXT;

L3: ......

Ln-1: 
IF T≠Cn-1 
GOTO Ln
Sn-1;
GOTO NEXT; 

Ln: Sn;
NEXT:
T := E 的中间码
Goto TEST

L1: 关于S1的中间码
Goto NEXT

L2: 关于S2的中间码
Goto NEXT

…

Ln-1: 关于Sn-1的中间码
Goto NEXT

Ln:  关于Sn的中间码
Goto NEXT

TEST:  
IF T=C1 GOTO L1;
IF T=C2 TOTO L2;…
IF T=Cn-1 GOTO Ln-1
Goto Ln
NEXT:

过程调用的翻译

语义动作

常用方案


S → C A L L   i ( a r g l i s t ) { F O R   队 列 a r g l i s t . Q U E U E 的 每 一 项 P   D O         G E N ( p a r , _ , _ , p ) ; G E N ( c a l l , _ , _ , E N T R Y ( i ) ) } a r g l i s t → a r g l i s t ( 1 ) , E { 把 E . P L A C E 排 在 a r g l i s t ( 1 ) . Q U E U E 的 末 端 ; a r g l i s t . Q U E U E : = a r g l i s t ( 1 ) . Q U E U E } a r g l i s t → E { 建 立 一 个 a r g l i s t . Q U E U E , 它 只 包 含 一 项 E . P L A C E } \begin{aligned}S \rightarrow&CALL\ i(arglist)\\ \{&FOR\ 队列arglist.QUEUE的每一项P\ DO\\ &\ \ \ \ \ \ \ GEN ( par,\_,\_,p);\\ &GEN (call,\_,\_,ENTRY(i))\}\\ arglist \rightarrow&arglist^{(1)},E\\ \{ &把E.PLACE排在arglist^{(1)}.QUEUE的末端;\\ &arglist.QUEUE := arglist^{(1)}.QUEUE\}\\ arglist \rightarrow&E\\ \{ &建立一个arglist.QUEUE,它只包含一项E.PLACE\}\end{aligned} S→{arglist→{arglist→{​CALL i(arglist)FOR 队列arglist.QUEUE的每一项P DO       GEN(par,_,_,p);GEN(call,_,_,ENTRY(i))}arglist(1),E把E.PLACE排在arglist(1).QUEUE的末端;arglist.QUEUE:=arglist(1).QUEUE}E建立一个arglist.QUEUE,它只包含一项E.PLACE}​



C A L L   S ( A + B , Z ) CALL\ S(A+B,Z) CALL S(A+B,Z)
( + , E N T R Y ( A ) , E N T R Y ( B ) , T ) ( p a r , _ , _ , T ) ( p a r , _ , _ , Z ) ( C a l l , _ , _ , E N T R Y ( S ) ) \begin{aligned} &(+,ENTRY(A),ENTRY(B),T)\\ &(par, \_, \_, T)\\ &(par, \_, \_, Z)\\ &(Call,\_, \_, ENTRY(S))\end{aligned} ​(+,ENTRY(A),ENTRY(B),T)(par,_,_,T)(par,_,_,Z)(Call,_,_,ENTRY(S))​

写法二义性

X : = A ( I , J ) X := A(I,J) X:=A(I,J)

声明语句的翻译

Integer L, M, N;
ARRAY A;

声明语句文法, G [ D ] G[D] G[D]
D → i n t e g e r   n a m e l i s t   ∣   r e a l   n a m e l i s t n a m e l i s t → n a m e l i s t , i   ∣   i \begin{aligned}D \rightarrow&integer\ namelist\ |\ real\ namelist\\ namelist \rightarrow&namelist,i\ |\ i\end{aligned} D→namelist→​integer namelist ∣ real namelistnamelist,i ∣ i​

改造文法, G [ D ] G[D] G[D]
D → D , i   ∣   i n t e g e r   i   ∣   r e a l   i D \rightarrow D,i\ |\ integer\ i\ |\ real\ i D→D,i ∣ integer i ∣ real i

D → i n t e g e r   i { F I L L ( E N T R Y ( i ) , i n t ) ; D . A T T : = i n t } D → r e a l   i { F I L L ( E N T R Y ( i ) , r e a l ) ; D . A T T : = r e a l } D → D ( 1 ) , i { F I L L ( E N T R Y ( i ) , D ( 1 ) . A T T ) ; D . A T T : = D ( 1 ) . A T T } \begin{aligned}D \rightarrow& integer\ i\\ \{&FILL(ENTRY(i),int);D.ATT := int\}\\ D \rightarrow&real\ i\\ \{&FILL(ENTRY(i),real);D.ATT := real\}\\ D \rightarrow&D^{(1)},i\\ \{&FILL(ENTRY(i),D^{(1)}.ATT);D.ATT := D^{(1)}.ATT \}\end{aligned} D→{D→{D→{​integer iFILL(ENTRY(i),int);D.ATT:=int}real iFILL(ENTRY(i),real);D.ATT:=real}D(1),iFILL(ENTRY(i),D(1).ATT);D.ATT:=D(1).ATT}​


数组说明


数组声明需要完成的工作:填向量申请空间计算下标地址

可变数组分配子程序

BEGIN
	i:=1; N:=1; C:=0; 
	WHILE i ≤ n  DO
	BEGIN
		di := ui –li +1; 
		N:=  N * di;
		C := C * di + li;
		把 li,ui 和 di 填入内情向量表区中;
		i := i + 1
	END;
申请 N 个单元的数组空间,令这片空间的首地址为 a;
把 n 和 C,以及 type 和 a 填入内情向量区中
END;

标签:代码生成,文法,CHAIN,语义,翻译,语法,制导,ID,属性
来源: https://blog.csdn.net/weixin_42437114/article/details/110916173