第5章 自顶向下语法分析方法

51
编编编编 编编编编 第 5 第 第第第第第第第第第第 第第第第第第第第第第第 LL(1) 第第第第第 第第第 LL(1) 第第第 LL(1) 第第第第 第第第 第第第第第第第第第第第第 第第第第第第第第第第第 第第第第

Upload: luella

Post on 05-Feb-2016

87 views

Category:

Documents


0 download

DESCRIPTION

确定的自顶向下分析思想 LL(1) 文法的判别 某些非 LL(1) 文法到 LL(1) 文法的等 价变换 不确定的自顶向下分析思想 确定的自顶向下分析方法. 第5章 自顶向下语法分析方法. 返回目录. 文法 G1[S]: S→pA S→qB A→cAd A→a B→dB B→b. 确定的自顶向下分析思想. W=pccadd 自顶向下的推导过程: S  pA  pcAd  pccAdd  pccadd. 语法树:. S. S. S. S. p. A. p. A. p. A. p. A. c. A. d. c. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第5章 自顶向下语法分析方法

编译原理编译原理

第 5 章 自顶向下语法分析方法

确定的自顶向下分析思想 LL(1) 文法的判别 某些非 LL(1) 文法到 LL(1) 文法的等

价变换 不确定的自顶向下分析思想 确定的自顶向下分析方法

返回目录

Page 2: 第5章 自顶向下语法分析方法

编译原理编译原理

确定的自顶向下分析思想

• 文法G1[S]:S→pAS→qBA→cAdA→aB→dBB→b

W=pccadd 自顶向下的推导过程:

S pA pcAd pccAdd pccadd

语法树:

S

p A

S

p A

c A d

S

p A

c A d

c A d

S

p A

c A d

c A d

a

Page 3: 第5章 自顶向下语法分析方法

编译原理编译原理

这个文法的特点:1. 每个产生式的右部都由终终

结符号结符号开始。2. 如果两个产生式有相同的

左部,那么它们的右部由不同的不同的终结符开始。

• 文法 G1[S]:S→pAS→qBA→cAdA→aB→dBB→b

Page 4: 第5章 自顶向下语法分析方法

编译原理编译原理

• 文法G2[S]:S→ApS→BqA→aA→cAB→bB→dB

W=ccap 自顶向下的推导过程:

S Ap cAp ccAp ccap

语法树:

S

A p

S

A p

c A

S

A p

c A

c A

S

A p

c A

c A

a

Page 5: 第5章 自顶向下语法分析方法

编译原理编译原理

这个文法的特点:1. 每个产生式的右部不全是

由终结符号终结符号开始。2. 如果两个产生式有相同的

左部,那么它们的右部由不同的不同的终结符或非终结符开始。

3. 文法中无空产生式。

• 文法 G1[S]:S→ApS→BqA→aA→cAB→bB→dB

Page 6: 第5章 自顶向下语法分析方法

编译原理编译原理

定义: 设 G = (VT ,VN , S , P) 是上下文无关文法,

FIRST(α)FIRST(α) = {a|α α aaββ,a V∈ T,α V∈ +, β V*,}∈

若 α ε ,则规定 ε FIRST(α)∈

***

调用返回

Page 7: 第5章 自顶向下语法分析方法

编译原理编译原理

• FIRST(Ap)={a,c}

• FIRST(Bq)={b,d}

• 文法 G2[S]:S→ApS→BqA→aA→cAB→bB→dB

Page 8: 第5章 自顶向下语法分析方法

编译原理编译原理

• 文法 G3[S]:S→aAS→dA→bASA→ε

W=abd 试图推导的过程:

S aA abAS abS abd

Page 9: 第5章 自顶向下语法分析方法

编译原理编译原理

定义:设 G = (VT ,VN , S , P) 是上下文无关文法, A V∈ N , S 是开始符号。 FOLLOW(FOLLOW(AA)) = {a|S A 且 a∈FRIST(),

∈VT*,∈V+

} 若 S A, 且 ε ,则规定 # FOLLOW(A)∈

即: FOLLOW(A)={a|S …FOLLOW(A)={a|S …AaAa… ,a… ,a∈V∈VTT}}若 S …A ,则规定 # FOLLOW(A)∈# 作为输入串的结束符,或称为句子括号,如:# 输入串 #

*

* ***

*

调用返回

Page 10: 第5章 自顶向下语法分析方法

编译原理编译原理

对 A→α , A→β 其中 A V∈ N , α, β V∈ N* ,当α 和 β 不同时推导出空时(设 α 不推导出空,β 推导出空),则当FIRST(α)∩(FIRST(β) FOLLOW(A))=∪ Φ 时,对于非终结符 A 的替换仍可唯一地确定候选。

Page 11: 第5章 自顶向下语法分析方法

编译原理编译原理

定义:给定上下文无关文法的产生式A→α , A∈VN , α V*∈ ,若 α ε ,则 SELECT(A→SELECT(A→α)α)=FIRST(α)如果 α ε ,则SELECT(A→α)SELECT(A→α)=FIRST(α) FOLLOW(A)∪

**

调用返回

Page 12: 第5章 自顶向下语法分析方法

编译原理编译原理

定义:一个上下文无关文法是 LL(1)LL(1) 文文法法的充要条件是:对每个非终结符 A 的两个不同产生式A→α 和 A→β ,满足SELECT(A→α)∩SELECT(A→β)=Φ其中 α,β 不同时能 ε 。

*

Page 13: 第5章 自顶向下语法分析方法

编译原理编译原理

LL(1) 文法的含义:

第一个 LL 表示:自顶向下分析是从左向右扫描从左向右扫描输入串输入串。第二个 LL 表示:分析过程中将用最左推导最左推导。 11 表示:只需向右看一个符号向右看一个符号便可决定如何推导(即选择哪个产生式进行推导)。类似也可以有 LL(K)LL(K) 文法:需向前查看 K 个符号才可确定选用哪个产生式。

Page 14: 第5章 自顶向下语法分析方法

编译原理编译原理

• 文法 G[S] 是否是 LL(1) 文法 :S→aAS→dA→bASA→ε SELECT(S→aA) ={a}SELECT(S→d) ={d}SELECT(A→bAS) ={b}SELECT(A→ε) ={a,d,#,ε}

SELECT(S→aA) ∩ SELECT(S→d)={a}∩{d}=ΦSELECT(A→bAS)∩SELECT(A→ε)={b}∩{a,d,#, ε}=Φ

所以该文法是 LL(1) 文法。

Page 15: 第5章 自顶向下语法分析方法

编译原理编译原理

• 设文法 G[S] 为 :S→aASS→bA→bAA→ε

SELECT(S→aAS) ={a}SELECT(S→b) ={b}SELECT(A→bA) ={b}SELECT(A→ε) ={a,b,ε}

SELECT(S→aAS) ∩ SELECT(S→b)={a}∩{b}=ΦSELECT(A→bA)∩SELECT(A→ε)={b}∩{a,b,ε}≠Φ

所以该文法不是 LL(1) 文法。

Page 16: 第5章 自顶向下语法分析方法

编译原理编译原理

G[S]:S→aASS→bA→bAA→ε

对输入串 W=ab 进行推导:

S aAS abAS abS 出错

S aAS aS ab

Page 17: 第5章 自顶向下语法分析方法

编译原理编译原理

LL(1) 文法的判别

1. 求出能推出 ε 的非终结符2. 计算 FIRST 集3. 计算 FOLLOW 集4. 计算 SELECT 集5. 判别是否是 LL(1) 文法

Page 18: 第5章 自顶向下语法分析方法

编译原理编译原理• 例:设文法 G[S] 为 :

S→ABS→bCA→εA→bB→εB→aDC→ADC→bD→aSD→c判断它是否是 LL(1) 文法。

Page 19: 第5章 自顶向下语法分析方法

编译原理编译原理

1. 求出能推出 ε 的非终结符

S→ABS→bCA→εA→bB→εB→aDC→ADC→bD→aSD→c

非终结符 S A B C D

初值 未定 未定 未定 未定 未定第一次扫描 是 是 否第二次扫描 是 否

Page 20: 第5章 自顶向下语法分析方法

编译原理编译原理2. 计算 FIRST 集• 1. 若 XXVV, 则 FIRST(X)={X}• 2. 若 XVN, 且有产生式 XXa…a… ,则

a∈FIRST(X);若 XX 也是一条产生式 , 则∈ FIRST(X).

• 3. 若 XXY…Y… 是一个产生式且 YVN, 则把FIRST(Y) 中的所有非元素都加到 FIRST(X)中 ; 若 X X Y Y11YY22…Y…YKK 是一个产生式 ,Y1,Y2,…,Y(i-1) 都是非终结符 , 而且 , 对于任何 j,1≤j ≤i-1,FIRST(Yj) 都含有 ( 即 YY11..Y..Y(i-1)(i-1) ), 则把FIRST(Yj) 中的所有非元素都加到 FIRST(X)中 ; 特别是 , 若所有的 FIRST(Yj , j=1,2,…,K)均含有 , 则把加到 FRIST(X) 中 .

**

Page 21: 第5章 自顶向下语法分析方法

编译原理编译原理

S→ABS→bCA→εA→bB→εB→aDC→ADC→bD→aSD→c

FIRST(S)=(FIRST(A)-{ε}) FIRST(B)-∪{ε}) {∪ ε} {∪ b}={a,b,ε}

FIRST(A)={b, ε}

FIRST(B)={a, ε}

FIRST(C)={a,b,c}

FIRST(D)={a,c}

FIRST(AB)={a,b,ε}

FIRST(AD)={a,b,c}

Page 22: 第5章 自顶向下语法分析方法

编译原理编译原理

3. 计算 FOLLOW 集

• 1. 对于文法的开始符号 S, 置 # 于FOLLOW(S) 。 ;

• 2. 若A→ αBβ 是一个产生式 , 则把 FIRST(β)\{} 加至 FOLLOW(B) 中 ;

• 3. 若A→ αB 是一个产生式 , 或A→ αBβ 是 一个产生式而 β ( 即 FIRST(β) ),则把FOLLOW ( A ),加至 FOLLOW ( B )中.

**

Page 23: 第5章 自顶向下语法分析方法

编译原理编译原理

S→ABS→bCA→εA→bB→εB→aDC→ADC→bD→aSD→c

FOLLOW(S)={#} FOLLOW(D)∪

FOLLOW(A)={a} {a,c} FOLLOW(S)∪ ∪

FOLLOW(B)=FOLLOW(S)

FOLLOW(C)=FOLLOW(S)

FOLLOW(D)=FOLLOW(B) FOLLOW(C)∪

FOLLOW(S)= {#}

FOLLOW(A)= {a,c,#}

FOLLOW(B)= {#}

FOLLOW(C)= {#}

FOLLOW(D)= {#}

Page 24: 第5章 自顶向下语法分析方法

编译原理编译原理4. 计算 SELECT 集S→ABS→bCA→εA→bB→εB→aDC→ADC→bD→aSD→c

FIRST(S)={a,b,ε}FIRST(A)={b, ε}FIRST(B)={a, ε}FIRST(C)={a,b,c}FIRST(D)={a,c}FIRST(AB)={a,b,ε}FIRST(AD)={a,b,c}

SELECT(S→AB)={a,b,ε,#}

SELECT(S→bC)={b}

SELECT(A→ε)={a,c,#,ε}

SELECT(A→b)={b}

SELECT(B→ε)={#,ε}

SELECT(B→aD)={a}

SELECT(C→AD)={a,b,c}

SELECT(C→b)={b}

SELECT(D→aS)={a}

SELECT(D→c)={c}

FOLLOW(S)= {#}

FOLLOW(A)= {a,c,#}

FOLLOW(B)= {#}

FOLLOW(C)= {#}

FOLLOW(D)= {#}该文法不是 LL(1) 文法。

Page 25: 第5章 自顶向下语法分析方法

编译原理编译原理

某些非 LL(1) 文法到 LL(1) 文法的等价变换

提取左公共因子 消除左递归

Page 26: 第5章 自顶向下语法分析方法

编译原理编译原理提取左公共因子A→αβ|αγ 导致 SELECT(A→αβ)∩ SELECT(A→αγ)≠Φ ,因此非 LL(1) 文法。等价变换为 A→α(β|γ) ,然后:A→αA'A' → β|γ

A→αβ1|αβ2|…|αβn 变换为 A→α(β1|β2|…|βn) ,然后:A→αA'A' → β1|β2|…|βn

Page 27: 第5章 自顶向下语法分析方法

编译原理编译原理

• 例:文法 G1[S] 为 :S→aSbS→aSS→ε

化为:S→aS(b|ε)S→ε

进一步化为:S→aSAA→bA→εS→ε

结果仍然不是 LL(1) 文法。因此,文法中不含左公共因子只是 LL(1) 文法的必要条件。

w=aabb

S=>aSA =>aaSAA =>aaAA =>aabA (aaA)

Page 28: 第5章 自顶向下语法分析方法

编译原理编译原理

• 例:文法 G2 为 :A→adA→BcB→aAB→bB

1. 化为:A→adA→aAcA→bBcB→aAB→bB

2. 化为:A→a(d|Ac)A→bBcB→aAB→bB

3. 化为:A→aA' A→bBcA'→dA'→AcB→aAB→bB

结果是 LL(1) 文法。

Page 29: 第5章 自顶向下语法分析方法

编译原理编译原理

• 例:文法 G3[S] 为 :S→aSd S→Ac A→aS A→b

1. 化为:S→aSdS→aScS→bc A→aSA→b

2. 化为:S→aS(d|c)S→bc A→aSA→b

3. 化为:S→aSA' S→bcA'→dA'→cA→aSA→b

结果中 A 是不可达到的符号。

Page 30: 第5章 自顶向下语法分析方法

编译原理编译原理• 例:文法 G4[S] 为 :

S→Ap|BqA→aAp|dB→aBq|e1. 化为:S→aApp|aBqq|dq|eqA→aAp|dB→aBq|e

2. 化为:S→a(App|Bqq)S→dq|eqA→aAp|dB→aBq|e

3. 化为:S→aS' S→dq|eqS'→App|BqqA→aAp|dB→aBq|e4. 化为:S→aS' S→dq|eqS'→ aAppp|aBqqq|dpp|eqqA→aAp|dB→aBq|e

利用提取左公共因子利用提取左公共因子无法在有限步骤内无法在有限步骤内替替换成无左公共因子的文法。换成无左公共因子的文法。

Page 31: 第5章 自顶向下语法分析方法

编译原理编译原理

结论

不一定每个文法的左公共因子都能在有限的步骤内替换成无左公共因子的文法。一个文法提取了左公共因子后,只解决了相同左部产生式右部的 FIRST 集不相交问题,当改写后的文法不含空产生式,且无左递归时,则改写后的文法是 LL(1) 文法,否则还需用LL(1) 文法的判别方式进行判断才能确定是否为 LL(1) 文法。

Page 32: 第5章 自顶向下语法分析方法

编译原理编译原理

消除左递归

直接左递归:A→Aβ AVN, β V*

间接左递归:A→BβB→Aα A,BVN, α,β V*

Page 33: 第5章 自顶向下语法分析方法

编译原理编译原理

文法 G5 含有直接左递归:S→SaS→b所能产生的语言 L={ban|n≥0}输入串 baaaa# 是该语言的句子,但如何用自顶向下分析呢?

Page 34: 第5章 自顶向下语法分析方法

编译原理编译原理

文法 G6 含有间接左递归:A→aBA→BbB→AcB→d输入串 adbcbcbc#A→aB→adA→aB→aAc→aBbc→aAcbc…

Page 35: 第5章 自顶向下语法分析方法

编译原理编译原理

消除直接左递归

把直接左递归改写为右递归。 如 G5:

S→SaS→b(L={ban|n≥0})

改为:S→bS'S'→aS'|ε

Page 36: 第5章 自顶向下语法分析方法

编译原理编译原理

消除直接左递归的一般方法:A→Aα1| Aα2|…| Aαm|β1|β2|…|βn

其中: αi 不等于 ε , βj 不以 A 开头。 改为:A→ β1A'| β2A' |…| βnA' A'→ α1A' | α2A' |…| αmA' |ε

Page 37: 第5章 自顶向下语法分析方法

编译原理编译原理

消除间接左递归

将间接左递归变为直接左递归,然后消除直接左递归。如文法 G6 含有间接左递归:

A→aBA→BbB→AcB→d

B→aBcB→BbcB→d

B→aBcB' | dB' B'→bcB'| ε

Page 38: 第5章 自顶向下语法分析方法

编译原理编译原理

消除文法中一切左递归的算法• 1. 无回路 (A(A (A) 2. 无空产生式 ( 1) 以某种顺序将文法非终结符排列 A1 ,A2 …An

( 2) for i:=1 to n do begin

for j:=1 to i-1 do • 用 Ai-->1| 2r…| k r 替代• 形如 Ai--> Ajr 的规则 , 其中• Aj--> 1| 2…| k 是关于 Aj 的全部产生式 ;

消除 Ai 规则的直接左递归 ;

end; ( 3)化简由 2 得到的文法

+

Page 39: 第5章 自顶向下语法分析方法

编译原理编译原理

例:

• 文法 G:S→Qc|cQ→Rb|bR→Sa|a

R→ Qca|ca|a

R→ Rbca|bca|ca|a

R→ (bca|ca|a)R'R' → bcaR'|ε

Page 40: 第5章 自顶向下语法分析方法

编译原理编译原理

不确定的自顶向下分析思想1. 由于相同左部的产生式的右部 FIRST 集交集不为空引起回溯。设文法 G[S] 为 : S→xAy

A→ab|a

w=xay

S

x A y

S

x A y

a b

S

x A y

a

试探 回溯 试探

Page 41: 第5章 自顶向下语法分析方法

编译原理编译原理

2. 由于相同左部非终结符的右部能 ε 且该非终结符 FOLLOW 集中含有其右部 FIRST 集的元素。 设文法 G[S] 为 :S→aASS→bA→bASA→ε

*

w=ab#

S

a A S

S

a A S

b A S

S

a A S

ε b

试探再试探 回溯

Page 42: 第5章 自顶向下语法分析方法

编译原理编译原理

3. 由于文法含有左递归而引起回溯。设文法 G[S] 为 :S→SaS→b w=baa#

S

b

S

S a

S

S a

b

S

S a

S a

S

S a

S a

b

Page 43: 第5章 自顶向下语法分析方法

编译原理编译原理

确定的自顶向下分析方法

1. 递归子程序法 实现思想:对文法中每个非终结符编写一个递

归过程,每个过程的功能是识别由该非终结符推出的串,当某非终结符的产生式有多个候选时能够按 LL(1) 形式可唯一地确定选择某个候选进行推导。

限制:对文法要求高,必须满足 LL(1) 文法;由于递归调用多,速度慢,占用空间多。

Page 44: 第5章 自顶向下语法分析方法

编译原理编译原理

2. 预测分析法

预测分析器:预测分析程序( P.88 )先进后出栈预测分析表

Page 45: 第5章 自顶向下语法分析方法

编译原理编译原理

预测分析表的构造

• 表达式文法:E →E+T | T

T →T*F | F

F → i | ( E )

Page 46: 第5章 自顶向下语法分析方法

编译原理编译原理

构造过程1. 判断文法是否为 LL(1) 文法 消除左递归:

E →E+T | T

T →T*F | F

F → i | ( E )

E →E+T | T

T →T*F | F

F → i | ( E )

E →TE'E' → +TE' | ε

T →FT'T' → *FT' | ε

F → i | ( E )

E →TE'E' → +TE' | ε

T →FT'T' → *FT' | ε

F → i | ( E )

Page 47: 第5章 自顶向下语法分析方法

编译原理编译原理可推出 ε 的非终结符表:

E →TE'E' → +TE' | ε

T →FT'T' → *FT' | ε

F → i | ( E )

E →TE'E' → +TE' | ε

T →FT'T' → *FT' | ε

F → i | ( E )

E E' T T' F

否 是 否 是 否

Page 48: 第5章 自顶向下语法分析方法

编译原理编译原理

各非终结符的 FIRST 集和 FOLLOW 集:FIRST(E)={ ( , i }

FIRST(E')={ + , ε }

FIRST(T)={ ( , i }

FIRST(T')={ * , ε }

FIRST(F)={ ( , i }

FOLLOW(E)={ ) , # }

FOLLOW(E')={ ) , # }

FOLLOW(T)={ + , ) , # }

FOLLOW(T')={ + , ) , # }

FOLLOW(F)={ * , + , ) , # }

E →TE'E' → +TE' | ε

T →FT'T' → *FT' | ε

F → i | ( E )

E →TE'E' → +TE' | ε

T →FT'T' → *FT' | ε

F → i | ( E )

查看 FOLLOW 定义

查看 FIRST 定义

Page 49: 第5章 自顶向下语法分析方法

编译原理编译原理各产生式的 SELECT 集:

E →TE'E' → +TE' | ε

T →FT'T' → *FT' | ε

F → i | ( E )

E →TE'E' → +TE' | ε

T →FT'T' → *FT' | ε

F → i | ( E )

SELECT(E →TE') ={ ( , i }SELECT(E' → +TE' ) ={ + }SELECT(E' → ε) ={ ε, ) , # }SELECT(T →FT') ={ ( , i }SELECT(T' → *FT' ) ={ * }SELECT(T' → ε) ={ ε, + , ) , # }SELECT(F → ( E )) ={ ( }SELECT(F → i) ={ i }

FIRST(E)={ ( , i }FIRST(E')={ + , ε }FIRST(T)={ ( , i }FIRST(T')={ * , ε }FIRST(F)={ ( , i }

FIRST(E)={ ( , i }FIRST(E')={ + , ε }FIRST(T)={ ( , i }FIRST(T')={ * , ε }FIRST(F)={ ( , i }

FOLLOW(E)={ ) , # }FOLLOW(E')={ ) , # }FOLLOW(T)={ + , ) , # }FOLLOW(T')={ + , ) , # }FOLLOW(F)={ * , + , ) , # }

FOLLOW(E)={ ) , # }FOLLOW(E')={ ) , # }FOLLOW(T)={ + , ) , # }FOLLOW(T')={ + , ) , # }FOLLOW(F)={ * , + , ) , # }

查看 SELECT 定义

是 LL(1) 文法。是 LL(1) 文法。

Page 50: 第5章 自顶向下语法分析方法

编译原理编译原理2. 构造预测分析表SELECT(E →TE') ={ ( , i }SELECT(E' → +TE' ) ={ + }SELECT(E' → ε) ={ ε, ) , # }SELECT(T →FT') ={ ( , i }SELECT(T' → *FT' ) ={ * }SELECT(T' → ε) ={ ε, + , ) , # }SELECT(F → ( E )) ={ ( }SELECT(F → i) ={ i }

i + * ( ) #

E →TE' →TE'

E' +TE' → ε → ε

T →FT' →FT'

T' → ε → *FT' → ε

F → i → ( E )

Page 51: 第5章 自顶向下语法分析方法

运行:

i + * ( ) #

E →TE'

→TE'

E' → +TE'

→ ε → ε

T →FT'

→FT'

T' → ε → *FT'

→ ε

F → i → ( E )

分析栈#E#E'T#E'T'F#E'T'i#E'T'#E'#E'T+#E'T#E'T'F#E'T'i#E'T'#E'T'F*#E'T'F#E'T'i#E'T'#E'#

剩余串i+i*i#i+i*i#i+i*i#i+i*i#+i*i#+i*i#+i*i#

i*i#i*i#i*i#*i#*i#i#i####

产生式E→TE'T→FT'F → ii i 匹配匹配T' → εE' → +TE'+ + 匹配匹配T →FT'F → ii i 匹配匹配T → *FT'* * 匹配匹配F → ii i 匹配匹配T' → εE' → ε接受接受

例:输入 i+i*i