第四章 自上而下语法分析

Post on 23-Jan-2016

65 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

第四章 自上而下语法分析. 主要内容 4.1 语法分析器的功能 4.2 自上而下语法分析 4.3 LL(1) 文法 4.4 递归下降分析器 4.5 预测分析法 4.6 LL(1) 分析中的错误处理. 4.1 语法分析器的功能. 语法分析是编译过程的核心部分 . 它的任务是在词法分析识别出单词符号串的基础上 , 分析并判定程序的语法结构是否符合语法规则 . 语法分析器在编译程序中的地位如图所示. 单词符号. 源程序. 语法分析树. 词法分析器. 语法分析器. 编译程序 后续部分. 取下一个 单词符号. 符号表. - PowerPoint PPT Presentation

Transcript

1

第四章 自上而下语法分析

主要内容 4.1 4.1 语法分析器的功能语法分析器的功能 4.2 4.2 自上而下语法分析自上而下语法分析 4.3 LL(1)4.3 LL(1) 文法文法 4.4 4.4 递归下降分析器递归下降分析器 4.5 4.5 预测分析法预测分析法 4.6 LL(1)4.6 LL(1) 分析中的错误处理分析中的错误处理

2

4.1 4.1 语法分析器的功能语法分析器的功能 语法分析是编译过程的核心部分 . 它的任务是

在词法分析识别出单词符号串的基础上 , 分析并判定程序的语法结构是否符合语法规则 . 语法分析器在编译程序中的地位如图所示 .

词法分析器词法分析器词法分析器词法分析器 语法分析器语法分析器语法分析器语法分析器 编译程序编译程序后续部分后续部分

编译程序编译程序后续部分后续部分

单词符号语法分析树

符号表符号表符号表符号表

源程序

取下一个单词符号

3

语法分析问题就是句子的识别问题语法分析问题就是句子的识别问题 .. 按照识别句子时语法树的建立方法不同分为自上而按照识别句子时语法树的建立方法不同分为自上而

下与自下而上两大类分析方法下与自下而上两大类分析方法 .. 自上而下语法分析就是从文法的识别符号出发自上而下语法分析就是从文法的识别符号出发 ,, 识识

别输入符号串是否为一个句子别输入符号串是否为一个句子 .. 自上而下分析法可能遇到的问题有自上而下分析法可能遇到的问题有回溯回溯以及以及左递归左递归

带来的无限循环带来的无限循环 .. 带回溯的分析方法效率太低带回溯的分析方法效率太低 .. 不带回溯的分析方法要求文法没有左递归并能避免不带回溯的分析方法要求文法没有左递归并能避免

回溯回溯 ,, 有一类被称为有一类被称为 LL(1)LL(1) 文法文法可用递归子程序方可用递归子程序方法或预测分析法实现自上而下的语法分析法或预测分析法实现自上而下的语法分析 ..

语法分析器的工作语法分析器的工作

4

词法分析和语法分析都是对输入符号串的识别词法分析和语法分析都是对输入符号串的识别 ,, 但但词法分析的输入符号串是一个单词词法分析的输入符号串是一个单词 ,, 而语法分析的而语法分析的输入符号串是一个句子或者说是一个程序输入符号串是一个句子或者说是一个程序 .. 我们用我们用小写字母表示终结符号小写字母表示终结符号 ,, 在词法分析中在词法分析中 ,, 小写字母小写字母表示组成单词的字符表示组成单词的字符 ;; 而在语法分析中而在语法分析中 ,, 小写字母小写字母表示组成程序的单词表示组成程序的单词 .. 从识别方式来说从识别方式来说 ,, 词法分析词法分析和语法分析都是对输入符号串的结构的识别和语法分析都是对输入符号串的结构的识别 ,, 但由但由于单词和程序的结构是不一样的于单词和程序的结构是不一样的 ,, 所以具体的识别所以具体的识别方法不一样方法不一样 ..

关于识别的符号串关于识别的符号串

5

4.2 4.2 自上而下语法分析 4.2.1.4.2.1. 基本思想基本思想 从识别符号出发从识别符号出发 ,, 不断建立直接推导不断建立直接推导 ,, 试图构试图构

造一个推导序列造一个推导序列 ,, 最终由它推导出与输入符号最终由它推导出与输入符号串相同的符号串串相同的符号串 ..

从语法树的角度看从语法树的角度看 ,, 自上而下分析过程将以识自上而下分析过程将以识别符号为根结点别符号为根结点 ,, 试图向下构造一棵语法树试图向下构造一棵语法树 ,,其末端节点符号串正好与输入符号串相同其末端节点符号串正好与输入符号串相同 ..

6

4.2.2. 4.2.2. 遇到的问题遇到的问题 1.1. 左递归左递归 当文法中出现左递归时当文法中出现左递归时 ,, 会使分析过程陷入无会使分析过程陷入无

限循环限循环 .. 左递归的形式为左递归的形式为 :: 存在非终结符号存在非终结符号 U, U, 对于它有 对于它有 U->U… U->U… 或或 U U =>U…=>U… 2.2. 回溯回溯 如果对于同一个非终结符号如果对于同一个非终结符号 ,, 存在若干个产生存在若干个产生

式右部式右部 , U->x, U->x11|x|x22|…|x|…|xn n

时时 ,, 要对要对 UU 展开展开 ,, 那么按哪一个产生式右部展那么按哪一个产生式右部展开开 ? ? 即即 :: 如何确定替换如何确定替换 UU 的的 xxii

++

7

例 : 对文法例 : 对文法 S → c A dS → c A d A → a b A → a b || a a 输入 输入 w = cad w = cad 的分析的分析

£ á £ â

A d

£ Ó

£ á

A d

£ Ó

这时意味着这时意味着 AA 的第一个此刻的第一个此刻不适用于构造不适用于构造 WW 的语法的语法树树 ,, 此时应该回头此时应该回头 (( 回溯回溯),), 看看 AA 是否还有别的候选是否还有别的候选..

8

3.3. 在上述的自上而下分析过程中在上述的自上而下分析过程中 ,, 当一个非终结符当一个非终结符用某一候选匹配成功时用某一候选匹配成功时 ,, 这种成功可能仅是暂时的这种成功可能仅是暂时的 ..

例如例如 ,, 就文法就文法 (4.1)(4.1) 而言而言 ,, 考虑输入串考虑输入串 x**y,x**y, 如果首先匹配如果首先匹配 *,*, 就可能匹配不成就可能匹配不成功功 ,, 如首先匹配如首先匹配 **** ,就成功,就成功 ,, 这意味着这意味着 ,A,A 首先使用第二个候选所得的不成功匹首先使用第二个候选所得的不成功匹配是虚假的配是虚假的 .. 由于这种虚假现象由于这种虚假现象 ,, 我们需要更复杂的回溯技术我们需要更复杂的回溯技术 .. 一般说一般说 ,, 要消除虚要消除虚假匹配是很困难的假匹配是很困难的 .. 但若从最长的候选开始匹配但若从最长的候选开始匹配 ,, 虚假匹配的现象就会减少一些虚假匹配的现象就会减少一些 ..

4.4. 当最终报告分析不成功时当最终报告分析不成功时 ,, 我们难于知道输入串我们难于知道输入串中出错的确切位置中出错的确切位置 ..

5.5. 由于带回溯的自上而下分析实际上采用了一种穷由于带回溯的自上而下分析实际上采用了一种穷举一切可能的试探法举一切可能的试探法 ,, 因此因此 ,, 效率很低效率很低 ,, 代价极高代价极高 ..严重的低效使得这种分析法只有理论意义严重的低效使得这种分析法只有理论意义 ,, 而在实而在实践上价值不大践上价值不大 ..

后面后面 ,, 将集中讨论不带回溯的自上而下的分析法将集中讨论不带回溯的自上而下的分析法 ..

9

4.3.LL(1)4.3.LL(1) 分析法分析法 4.3.1.4.3.1. 消除左递归消除左递归

对于某些 对于某些 αα,存在推导 ,存在推导 P => P αP => P α 引入新的非终结符 引入新的非终结符 P’P’ 将 将 P → PαP → Pα || β β 替换为替换为 P→βP' P→βP' 和 和 P'→αP'P'→αP' || εε

++

10

例 :表达式文法直接左递归的消除

E → E + TE → E + T || TT

T → T * FT → T * F || FF

F → ( E )F → ( E ) || idid

EE →  → T E'T E'

E' → + T E'E' → + T E' || εε

TT →  → F T'F T'

T' → * F T'T' → * F T' || εε

FF →  → ( E )( E ) || idid

11

(1).(1). 将间接左递归改为直接左递归将间接左递归改为直接左递归 .. 将文法中所有如下形式将文法中所有如下形式的产生式的产生式 ::

PPjj→P→Pjjγγ|| ββ11 || ββ2 2 |…||…| ββnn

PPjj→→δδ11 || δδ22 |…||…| δδkk

改写成改写成 :P:Pjj→→δδ11γγ|| δδ22γγ|…||…| δδkkγ γ || ββ11 || ββ2 2 |…||…| ββnn

则可消除文法中的间接左递归则可消除文法中的间接左递归 .. (2).(2). 消除直接左递归消除直接左递归 .. 将文法中所有如下形式的产生式将文法中所有如下形式的产生式 :: P→PαP→Pα11 | | PαPα22 |…||…| PαPαmm|| ββ11 || ββ22 |… ||… | ββnn

其中每个其中每个 αα 都不等于都不等于 ε,ε, 而每个而每个 ββ都不以都不以 PP开头开头 ,, 那么那么 ,, 消除消除PP的直接左递归性就是把这些规则改写成的直接左递归性就是把这些规则改写成 ::

P→βP→β11P'P'|| ββ22P'P'|… ||… | ββnnP'P'

P'→αP'→α11P'P'|| αα22P'P'|… ||… | ααmmP'P'|| εε 把直接左递归都改成直接右递归把直接左递归都改成直接右递归 ..

消除文法中所有左递归的方法

12

例 : 消除下面文法的左递归S → QcS → Qc || cc Q → RbQ → Rb || bbR → SaR → Sa || aa令它的非终结符的排序是令它的非终结符的排序是 :R,Q,S:R,Q,S对对 R,R, 不存在直接左递归不存在直接左递归 ,, 将 将 R R 代入代入 Q,Q,Q → SabQ → Sab || abab || bb

同样不含同样不含 QQ 直接左递归直接左递归 ,, 将 将 Q Q 代入代入 S,S,S → SabcS → Sabc || abcabc || bcbc || cc

13

消除消除 SS 的直接左递归的直接左递归 ,,得文法得文法 : :     S → abcS'S → abcS'|| bcS'bcS'|| cS'cS'    S' → abcS'S' → abcS'|| εε Q → SabQ → Sab || abab || bb R → SaR → Sa || aa显然显然 ,Q,Q和和 RR的规则已是多余的规则已是多余 ,,化简后得文化简后得文

法法 :: S → abcS'S → abcS'|| bcS'bcS'|| cS'cS'    S' → abcS'S' → abcS'|| εε

14

由于对非终结符排序的不同由于对非终结符排序的不同 ,, 最后所得的文法在形最后所得的文法在形式上可能不一样式上可能不一样 ,, 但它们都是等价的但它们都是等价的 . .    

如上例中若非终结符的排序为如上例中若非终结符的排序为 :S,Q,R, :S,Q,R, 那么最后所那么最后所得的无左递归文法为得的无左递归文法为 ::

S → QcS → Qc || cc    Q → RbQ → Rb || bb R → bcaR'R → bcaR'|| caR'caR'|| aR'aR'    R' → bcaR'R' → bcaR'|| εε

15

设有文法设有文法 G[S]:G[S]: S → QdS → Qd    Q → RbQ → Rb || SeSe R → Sa|Qf|a R → Sa|Qf|a 试消除其左递归试消除其左递归 ..解解 ::令它的非终结符的排序是令它的非终结符的排序是 S,Q,R; S,Q,R; 将将 SS代入代入 Q:Q: Q → RbQ → Rb || Qde Qde 消除消除 QQ的左递归的左递归 , , 得到得到 :: Q → RbQ’ Q’ →deQ’Q → RbQ’ Q’ →deQ’|| εε 将将 SS代入代入 R, R → Qda|Qf|a, R, R → Qda|Qf|a, 由于由于 Q → RbQ’ ,Q → RbQ’ ,得得 :: R → RbQ’ da| RbQ’ f|a, R → RbQ’ da| RbQ’ f|a, 消除消除 RR的左递归的左递归 :: R →aR’ R’ → bQ’ da R’|bQ’ fR’| εR →aR’ R’ → bQ’ da R’|bQ’ fR’| ε 所以所以 ,, 文法消除左递归后变为文法消除左递归后变为 :: S → QdS → Qd    Q → RbQ’ Q → RbQ’ Q’ →deQ’Q’ →deQ’|| εε R →aR’ R →aR’ R’ → bQ’ da R’|bQ’ fR’|aR’ → bQ’ da R’|bQ’ fR’|a

例 :

16

消除下列文法的左递归消除下列文法的左递归 :: (1).G[A] :(1).G[A] : A → BxA → Bx || CzCz|| w B → Abw B → Ab || Bc C → AxBc C → Ax || ByBy|| CpCp解解 : : 因为因为 B → Ab, A → BxB → Ab, A → Bx || CzCz|| ww 所以将所以将 BB 改写为改写为 :B → Bxb:B → Bxb || CzbCzb || wbwb || BcBc 消除产生式消除产生式 BB的左递归的左递归 :: B → CzbB’B → CzbB’|| wbB’ B’ → xbB’wbB’ B’ → xbB’|| cB’ cB’ || εε 因为因为 C → Ax, A → BxC → Ax, A → Bx || CzCz|| ww 所以将所以将 CC 改写为改写为 :C → Bxx:C → Bxx || CzxCzx || wxwx || ByBy|| CpCp 因为因为 C → BxxC → Bxx || By, B → CzbB’By, B → CzbB’|| wbB’wbB’ 所以将所以将 CC 改写为改写为 :: C → CzbB’ xxC → CzbB’ xx | | CzbB’ yCzbB’ y|| wbB’ xxwbB’ xx || wbB’ ywbB’ y|| CCzxzx || wxwx || CpCp

消除产生式消除产生式 CC的左递归的左递归 :: C → wbB’ xxC’C → wbB’ xxC’|| wbB’ yC’wbB’ yC’|| wxC’wxC’ C’ → zbB’ xxC’C’ → zbB’ xxC’| | zbB’ yC’zbB’ yC’|| zxC’zxC’|| pC’ pC’ || εε

例 :

17

所以所以 , , 文法消除后的左递归为文法消除后的左递归为 :: A → BxA → Bx || CzCz|| ww B → CzbB’B → CzbB’ || wbB’wbB’ B’ → xbB’B’ → xbB’ || cB’ cB’ || εε C → wbB’ xxC’C → wbB’ xxC’ || wbB’ yC’wbB’ yC’ || wxC’wxC’ C’ → zbB’ xxC’C’ → zbB’ xxC’ | | zbB’ yC’zbB’ yC’ || zxC’zxC’

|| pC’ pC’ || εε

结果 :

18

4.3.2 消除回溯 ,提左因子 1.1. 消除回溯消除回溯令令 GG是一个不含左递归的文法是一个不含左递归的文法 ,, 对对 GG的所有非终结符的所有非终结符

号的每个候选号的每个候选 αα 定义它的终结首符集定义它的终结首符集 FIRST(α)FIRST(α) 为为 :: FIRST(α)={a|α=FIRST(α)={a|α=**>a… , a ∈>a… , a ∈VV TT}}特别是特别是 ,, 若若 α=α=**>ε,>ε, 则规定 则规定 ε ∈FIRST(α)ε ∈FIRST(α)即即 : FIRST(α): FIRST(α) 是是 αα 的所有可能推导的开头终结符或可的所有可能推导的开头终结符或可

能的能的 ε.ε.若若 AA 的任何两个不同候选的任何两个不同候选 ααii 和和 ααjjFIRST(αFIRST(αii ) ∩ FIRST(α ) ∩ FIRST(αjj ) = φ ) = φ 则当要求则当要求 AA匹配输入串时匹配输入串时 ,A,A 就根据它所面临的第一个就根据它所面临的第一个

输入符号输入符号 a,a,准确地指派某一个候选前去执行任务准确地指派某一个候选前去执行任务 ..

19

2. 左因子提取方法 对于所有形如 对于所有形如 A→ A→ δδββ11 || δδββ22 || ...... || δδββnn || γγ1 1 || γγ2 2 || ...... || γγmm的的

规则 规则 (( 其中每个其中每个 γγ不以不以 δδ开头开头 )) 改写为改写为

A → A → δδA'A'| | γγ1 1 || γγ2 2 || ...... || γγmm和 和 A'→βA'→β11 || ββ22 || ...... || ββnn

经过反复提取左因子,就能够把每个非终结符(包括经过反复提取左因子,就能够把每个非终结符(包括新引进者)的所有候选首符集变成为两两不相交。为新引进者)的所有候选首符集变成为两两不相交。为此付出的代价是,大量引进新的非终结符和此付出的代价是,大量引进新的非终结符和 ε-ε- 产生产生式。式。

20

例 :分析符号串 i + i * i 符合表达式文法:

E → T E' E → T E' E'→ + T E'E'→ + T E' || ε ε T → F T' T → F T' T'→ * F T'T'→ * F T' || ε ε F → ( E )F → ( E ) || ii

按照最左推导过程,构造分析树按照最左推导过程,构造分析树

E →E+T|TE →E+T|TT →T*F|FT →T*F|FF →(E)|iF →(E)|i

21

推导过程 (P72)E

T E’

F T’ T+ E’

i ε F T’

i

ε

F* T’

i ε生成语法分析树

i ∈ FIRST(TE’)

i∈FIRST(FT’)

T’ →T’ →εε

E → T E' E → T E' E'→ + T E'E'→ + T E'|| ε ε T → F T' T → F T' T'→ * F T'T'→ * F T'|| ε ε F → ( E )F → ( E ) || ii句子句子 i+i*ii+i*i

22

4.2.5 FIRST 和 FOLLOW 集 令令 GG是一个不含左递归的文法是一个不含左递归的文法 定义:对定义:对 GG的所有非终结符的每个候选的所有非终结符的每个候选 αα 定定 义它的终结首符集义它的终结首符集 FIRSTFIRST (( αα)为)为

FIRST( α ) = { a FIRST( α ) = { a || α ==α ==**> a …> a …,, a∈a∈VV TT** } }

αα 的所有首符号(选择产生式的依据)的所有首符号(选择产生式的依据) 定义: 定义: FOLLOW( A )FOLLOW( A ) 是所有句型中出现在紧接是所有句型中出现在紧接 AA之后的终结符或‘之后的终结符或‘ #’#’

FOLLOW( A ) = { a FOLLOW( A ) = { a | | S ==S ==**> …Aa…> …Aa…,, a∈a∈VV TT } } A A 的后续符号的后续符号

α

a … …

S

… A a ...

23

定义 令G[S]=(VT,VN,S,P), 则 FIRST(α)={ a| α*aβ,a∈VT , α、β∈V*} 、 若 α*ε ,则 ε∈FIRST(α) FIRST( X ) 的计算法对所有语法符号 对所有语法符号 XX,重复进行以下计算,重复进行以下计算 1) 1) 若 若 X ∈X ∈VV TT,则 ,则 FIRST( X ) = X FIRST( X ) = X 。。

2) 2) 若 若 X ∈X ∈VV NN,, 有产生式 有产生式 X → a…X → a…,则将 ,则将 a a 加入加入

FIRST(X)FIRST(X);; 有产生式 有产生式 X →εX →ε,则将,则将 εε 加入加入 FIRST( X )FIRST( X )。。

24

3) 3) 若有产生式 若有产生式 X → Y…X → Y…,且 ,且 Y ∈Y ∈VV NN,, 则把则把 FIRST(Y)FIRST(Y) 中的所有非中的所有非 ε-ε-元素都加到元素都加到 FIRST(X)FIRST(X) 中;中;

若有产生式 若有产生式 X → YX → Y11…Y…Yk k , , YY11 ... Y ... Yi-1i-1 都是非终结符,而且,都是非终结符,而且,

对于任何对于任何 jj ,, 1<=j<=i-1, FIRST( Y1<=j<=i-1, FIRST( Yjj ) ) 都含有都含有 εε (即(即 YY11 ... Y ... Yi-1i-1

==>ε ==>ε ),则把),则把 FIRST( YFIRST( Yii ) ) 中的所有非中的所有非 ε-ε-元素都加到元素都加到 FIRSTFIRST

(( XX )中;特别是,若所有的)中;特别是,若所有的 FIRSTFIRST ( ( YYjj)均含有)均含有 ε,j=1,2ε,j=1,2

,…,k,,…,k, 则把则把 εε 加到加到 FIRSTFIRST (( XX )中。)中。

反复使用反复使用 (1)-(3),(1)-(3), 直到直到 FIRST(X)FIRST(X) 不再增大为止。 不再增大为止。

**

25

求解 FIRST集合的算法 对每一文法符号对每一文法符号 X V ∈X V ∈ 计算计算 FIRST(X)FIRST(X)

(a) (a) 若若 X V∈X V∈ TT,则,则 FIRST(X)FIRST(X) == {X}{X}。。(b) (b) 若若 X V∈X V∈ NN,且有产生式,且有产生式 X→a…X→a…,, a V∈a V∈ TT,则,则 a FIRST(∈a FIRST(∈X)X)。。(c) (c) 若若 X V∈X V∈ NN,, X→ε,X→ε, 则则 ε FIRST(X)∈ε FIRST(X)∈ 。。(d) (d) 若若 X V∈X V∈ NN;; YY11,, YY22,,……,, YYii V∈V∈ NN,且有产生式,且有产生式 X→YX→Y11 Y Y

22 … Y … Ynn;当;当 YY11 Y Y22 … Y … Yi-1i-1 都都 εε 时,时, (( 其中其中 1≤i≤n)1≤i≤n) ,则,则 FIRST(YFIRST(Y11

))、、 FIRST(YFIRST(Y22))、、……、、 FIRST(YFIRST(Yi-1i-1)) 的所有非的所有非 {ε}{ε}元素和元素和 FIRSTFIRST

(Y(Yii)) 都包含在都包含在 FIRST(X)FIRST(X) 中。中。(e) (e) 当当 (d)(d) 中所有中所有 YYiiε,(i=1,2,…n)ε,(i=1,2,…n) ,则,则   FIRST(X)=FIRST(YFIRST(X)=FIRST(Y11) FIRST(Y∪) FIRST(Y∪ 22) … FIRST(Y∪ ∪) … FIRST(Y∪ ∪ nn) {ε}∪) {ε}∪反复使用上述反复使用上述 (b)(b)~~ (e)(e) 步直到每个符号的步直到每个符号的 FIRSTFIRST集合不再增集合不再增大为止。大为止。

26

求一个符号串的求一个符号串的 FIRSTFIRST 集合集合若符号串若符号串 α V∈α V∈ ** ,, α=Xα=X11 X X22 … X … Xnn,, 当当 XX11 不能 不能

ε,ε, 则置则置 FIRST(α)= FIRST(XFIRST(α)= FIRST(X11)) 。。若对任何若对任何 j(1≤j≤i-1j(1≤j≤i-1 ,, 2≤i≤n), ε FIRST(X∈2≤i≤n), ε FIRST(X∈ jj) , ) , 则则

FIRST(α)= (FIRST(XFIRST(α)= (FIRST(Xjj)-{ε}) FIRST(X∪)-{ε}) FIRST(X∪ ii))

当所有当所有 FIRST(XFIRST(Xjj)(1≤j≤n))(1≤j≤n) 都含有都含有 {ε}{ε} 时,则时,则 FIRFIRST(α)= (FIRST(XST(α)= (FIRST(Xjj))∪{ε} ))∪{ε}

1

1

i

j

n

j 1

27

文法文法 G[S]G[S] 为:为: S→AB| bC S→AB| bC    A→ b |ε B→ aD |εA→ b |ε B→ aD |ε C→AD| b C→AD| b    D→aS| cD→aS| c

可产生空串的非终结符:可产生空串的非终结符: AA 、、 BB 、、 SSFIRST(S)FIRST(S) {FIRST(A)-{ε}} {FIRST(B)-{ε}} {ε} ∪ ∪{FIRST(A)-{ε}} {FIRST(B)-{ε}} {ε} ∪ ∪

{b}={b,a,ε}∪{b}={b,a,ε}∪

FIRST(A)FIRST(A) {ε} ∪{b}={ε,b} {ε} ∪{b}={ε,b}

FIRST(B)FIRST(B) {ε} ∪{a}={ε,a} {ε} ∪{a}={ε,a}

FIRST(C)FIRST(C) {FIRST(A) -{ε}} FIRST(D) FIRST(b) ∪ ∪{FIRST(A) -{ε}} FIRST(D) FIRST(b) ∪ ∪={b,a,c}={b,a,c}

FIRST(D)FIRST(D) {a} ∪{c}={a,c} {a} ∪{c}={a,c}

28

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

FIRST(bC) FIRST(bC) {b} {b}

FIRST(ε) FIRST(ε) {ε} {ε}

FIRST(b) FIRST(b) {b} {b}

FIRST(aD) FIRST(aD) {a} {a}

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

FIRST(b) FIRST(b) {b} {b}

FIRST(aS) FIRST(aS) {a} {a}

FIRST(c) FIRST(c) {c} {c}

字符串的字符串的 FIRSTFIRST 集合集合

29

例 :表达式文法的 FIRST 集 E → T E' E → T E' E'→ + T E'E'→ + T E'|| ε ε T → F T' T → F T' T'→ * F T'T'→ * F T'|| ε ε F → ( E )F → ( E ) || idid可产生空串的非终结符:可产生空串的非终结符: E’E’ 、、 T’T’FIRST( F ) = { ‘(‘, id }FIRST( F ) = { ‘(‘, id }FIRST( T ) = FIRST( F )-FIRST( T ) = FIRST( F )-{ε}{ε}= { ‘(‘, id} = { ‘(‘, id} FIRST( E ) = FIRST( T )-FIRST( E ) = FIRST( T )-{ε}{ε}= { ‘(‘, id} = { ‘(‘, id} FIRST( E' ) = { ‘+’FIRST( E' ) = { ‘+’ ,, ε}ε}FIRST( T' ) = { ‘*’, ε} FIRST( T' ) = { ‘*’, ε}

30

例:求下列文法的 FIRST 和 FOLLOW 集合 11)) S S →ABc→ABc A →a|εA →a|ε B →b|εB →b|ε可产生空串的非终结符: 可产生空串的非终结符: AA 、 、 BB FIRST(A)={a,ε}FIRST(A)={a,ε}

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

∪ ∪FIRST(C) ={a,b,c}FIRST(C) ={a,b,c} FOLLOW(S)={#}FOLLOW(S)={#} FOLLOW(A)=FIRST(Bc)={FIRST(B)-{ε}}∪{c}FOLLOW(A)=FIRST(Bc)={FIRST(B)-{ε}}∪{c} ={b,c}={b,c} FOLLOW(B)={c}FOLLOW(B)={c}

31

例如:例如: SS →ABBA→ABBA A →a|εA →a|ε B →b|εB →b|ε FIRST(A)={a,ε}FIRST(A)={a,ε}

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

∪ ∪{ε} ={a,b,ε}{ε} ={a,b,ε} FOLLOW(S)={#}FOLLOW(S)={#} FOLLOW(A)=FIRST(BBA)={FIRST(B)-{ε}}∪{c}FOLLOW(A)=FIRST(BBA)={FIRST(B)-{ε}}∪{c} ={b,c}={b,c} FOLLOW(B)={c}FOLLOW(B)={c}

32

FOLLOW( A ) 的计算法 计算 ( 从右向左看齐)

对于所有非终结符对于所有非终结符 , , 重复进行以下计算重复进行以下计算 1) 1) 设设 SS 是开始符号,则 是开始符号,则 # ∈ FOLLOW( S )# ∈ FOLLOW( S )

句子的结束符句子的结束符 2) 2) 若 若 A → αBβA → αBβ ,,

则将 则将 FIRST(β) FIRST(β) 的非的非 εε 元素加入 元素加入 FOLLOW(B)FOLLOW(B) 3) 3) 如果 如果 A → αB A → αB 或 或 A → αBβA → αBβ ,且 ,且 β==>εβ==>ε (即(即 ε∈ε∈FIRST(β)FIRST(β)),则将 ),则将 FOLLOW(A) FOLLOW(A) 的所有元素加入 的所有元素加入 FFOLLOW(B)OLLOW(B)

反复使用反复使用 (1)-(3)(1)-(3) 直到直到 FOLLOWFOLLOW集不再增大为止。集不再增大为止。

33

例:文法例:文法 G[S]G[S] ,其产生式如下,其产生式如下 : : S→AB|bC A→ε|b B→ε|aD C→AD|b S→AB|bC A→ε|b B→ε|aD C→AD|b D→a|cD→a|c 可产生空串的非终结符:可产生空串的非终结符: AA 、、 BB 、、 SS

FOLLOW(FOLLOW(S)S)

{#} {#}

FOLLOW(FOLLOW(A)A)

{FIRST(B)-{FIRST(B)-{ε}}∪FOLLOW(S)∪{FIRST(D) -{ε}}∪FOLLOW(S)∪{FIRST(D) -{ε}}{ε}}={#,a,c} ={#,a,c}

FOLLOW(FOLLOW(B)B)

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

FOLLOW(FOLLOW(C) C)

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

FOLLOW(FOLLOW(D)D)

FOLLOW(B)∪FOLLOW(C)={#}FOLLOW(B)∪FOLLOW(C)={#}

34

例:表达式文法的 FOLLOW 集 E → T E' E → T E' E'→ + T E'E'→ + T E'|| ε ε T → F T' T → F T' T'→ * F T'T'→ * F T'|| ε ε F → ( E )F → ( E ) || idid可产生空串的非终结符:可产生空串的非终结符: E’E’ 、、 T’T’FOLLOW( E ) = { ‘)’, # } FOLLOW( E ) = { ‘)’, # } 由由 F → ( E ),F → ( E ), 则则 FIRST(‘)’)=FOLLOW(E) ,FIRST(‘)’)=FOLLOW(E) , 规则规则 11FOLLOW( E‘ ) = FOLLOW( E ) = { ‘)’, # } FOLLOW( E‘ ) = FOLLOW( E ) = { ‘)’, # } 规则规则 33FOLLOW( T ) = { +, ‘)’, # } FOLLOW( T ) = { +, ‘)’, # } FIRST(E’), FOLLOW(E’)FIRST(E’), FOLLOW(E’)FOLLOW( T' ) = FOLLOW( T ) = { +, ‘)’, # } FOLLOW( T' ) = FOLLOW( T ) = { +, ‘)’, # } 规则规则 33FOLLOW( F ) = { *, +, ‘)’, # } FOLLOW( F ) = { *, +, ‘)’, # } FIRST(T’), FOLLOW(T’), FOLLOW(TFIRST(T’), FOLLOW(T’), FOLLOW(T

))

35

例 : 设有以下文法设有以下文法 G[S]:G[S]: S → aAbDeS → aAbDe|| d d A → BSDA → BSD|| e e B → SAcB → SAc || cDcD|| ε ε D → SeD → Se|| ε ε 求出该文法的每一个非终结符求出该文法的每一个非终结符 UU 的的 FOLLOWFOLLOW集集 ..

36

解 : 可产生空串的非终结符:可产生空串的非终结符: BB 、、 DD (1)(1) 因为因为 SS 是识别符号是识别符号 ,, 且有且有 A→BSD,B→SAc,D→Se,A→BSD,B→SAc,D→Se, 所以所以

FOLLOW(S)FOLLOW(S) 应包含应包含 {FIRST(D)-{{FIRST(D)-{εε}}∪{FIRST(Ac)-{}}∪{FIRST(Ac)-{εε}}∪{FIRST(e)-{}}∪{FIRST(e)-{εε}} ∪{#}={a,d}}} ∪{#}={a,d}

∪{a,d,c,e}∪{e}∪{#} = {a,c,d,e,#}∪{a,d,c,e}∪{e}∪{#} = {a,c,d,e,#} (2)(2) 又因又因 A→BSDA→BSD 和和 D →ε,D →ε, 所以所以 FOLLOW(S)FOLLOW(S) 中还包含有中还包含有 FF

OLLOW(A).OLLOW(A). 因为因为 S → aAbDeS → aAbDe 和和 B → SAc,B → SAc, 所以所以 :: FOLLOW(A)=FIRST(bDe)∪FIRST(c) = {b,c}FOLLOW(A)=FIRST(bDe)∪FIRST(c) = {b,c} 综合综合 (1),(2)(1),(2) 得得 FOLLOW(S)= {a,c,d,e,#}∪{b,c}FOLLOW(S)= {a,c,d,e,#}∪{b,c} = {a,b,c,d,e,#}= {a,b,c,d,e,#} (3)(3) 因为因为 A→BSD, A→BSD, 所以所以 FOLLOW(B)=FIRST(SD)={a,d}FOLLOW(B)=FIRST(SD)={a,d} (4)(4) 因为因为 S→aAbDeS→aAbDe || d, A→BSDd, A→BSD || e e 和和 B→SAcB→SAc || cD,cD,

所以所以 : FOLLOW(D)=FIRST(e)∪FOLLOW(A)∪FOLLOW(B) : FOLLOW(D)=FIRST(e)∪FOLLOW(A)∪FOLLOW(B) ={e}∪{b,c}∪{a,d}={a,b,c,d,e}={e}∪{b,c}∪{a,d}={a,b,c,d,e}

S → aAbDeS → aAbDe|| d d A → BSDA → BSD|| e e B → SAcB → SAc || cDcD|| ε ε D → SeD → Se|| εε

37

4.3 LL( 1 ) 文法

第一个 L 表示从左向右扫描输入符号串 第二个 L 表示生成最左推导 1 表示读入一个符号可确定下一步推导

表示了自上而下方法能够处理的文法

38

文法G是 LL(1) 的充要条件 : 对于 对于 G G 的每个非终结符 的每个非终结符 A A 的的 任何两个不同的产生式 任何两个不同的产生式 A → αA → α || ββ

1) FIRST( α ) ∩ FIRST( β ) = φ1) FIRST( α ) ∩ FIRST( β ) = φ

2) 2) 如果 如果 β ==β ==**> ε> ε,则 ,则 FISRT( α ) ∩ FOLLOW( A ) = φFISRT( α ) ∩ FOLLOW( A ) = φ

39

对于一个对于一个 LLLL (( 11 )文法,可以对其输入串进行有效)文法,可以对其输入串进行有效的无回溯的自上而下分析。假设要用非终结符的无回溯的自上而下分析。假设要用非终结符 AA 进进行匹配,面临的输入符号为行匹配,面临的输入符号为 aa ,, AA 的所有产生式为的所有产生式为::

A A →a1|a2|a3|…|an→a1|a2|a3|…|an11)若)若 a ∈FIRST(ai)a ∈FIRST(ai),则指派,则指派 aiai去执行匹配任务。去执行匹配任务。22)若)若 aa 不属于任何一个候选首符集,则:不属于任何一个候选首符集,则: a.a. 若若 εε 属于某个属于某个 FIRST(ai)FIRST(ai)且且 a∈FOLLOW(Aa∈FOLLOW(A)) ,, 则则让让 AA 与与 εε自动匹配。自动匹配。

b.b. 否则,否则, aa 的出现是一种语法错误。的出现是一种语法错误。根据根据 LLLL(( 11)文法的条件,每一步这样的工作都是确)文法的条件,每一步这样的工作都是确信无疑的。信无疑的。

40

表达式文法是 LL(1) 文法 E → T E' E → T E' E'→ + T E'E'→ + T E'|| ε ε T → F T' T → F T' T'→ * F T'T'→ * F T' || ε ε F → ( E )F → ( E ) || idid考察考察 E’: + E’: + 不在 不在 FOLLOW( E’ ) = { ), # }FOLLOW( E’ ) = { ), # } T’: * T’: * 不在 不在 FOLLOW( T’ ) = { +, ), # }FOLLOW( T’ ) = { +, ), # } F : ( F : ( 和 和 id id 不同不同

41

例 : 以下文法以下文法 G[S]G[S] 是否是是否是 LL(1)LL(1) 文法文法 ? ? S → aAbDeS → aAbDe || d d A → BSDA → BSD || e e B → SAcB → SAc || cDcD || ε ε D → SeD → Se|| ε ε

解解 : G[S] : G[S] 不是不是 LL(1)LL(1) 文法文法 . . 因为产生式因为产生式 B → SAcB → SAc || cDcD || ε ε 中中 ,, FIRST(SAc)∩FOLLOW(B)={a,d}<>φ FIRST(SAc)∩FOLLOW(B)={a,d}<>φ

42

4.4 递归下降分析程序构造 当一个文法满足当一个文法满足 LL(1)LL(1)条件时条件时 ,, 可以可以

为它构造一个不带回溯的自上而下分为它构造一个不带回溯的自上而下分析程序析程序 ,, 这个分析程序是由一组递归这个分析程序是由一组递归过程组成的过程组成的 ,,每个过程对应文法的一每个过程对应文法的一个非终结符个非终结符 .. 这样的一个分析程序称这样的一个分析程序称为递归下降分析器为递归下降分析器 ..

43

E的子程序E的子程序 procedure E;procedure E; beginbegin T;E’T;E’ endend procedure E’;procedure E’; IF SYM='+' IF SYM='+'

THEN THEN begin begin ADVANCE; ADVANCE; T;E’T;E’ endend

4.4.1 例 :递归子程序ADVANCE: 下一个符号 . SYM: 当前符号 .ERROR: 错误处理程序

TT 的子程序的子程序 procedure T;procedure T; beginbegin F;T’F;T’ endend procedure T’;procedure T’; IF SYM=‘*' IF SYM=‘*'

THEN THEN begin begin ADVANCEADVANCE F;T’F;T’ endend

FF 的子程序的子程序procedure F;procedure F;IF SYM=‘id' THEN IF SYM=‘id' THEN

ADVANCEADVANCEELSEELSE IF SYM=‘(' THENIF SYM=‘(' THEN begin begin ADVANCE; ADVANCE; E;E; endend IF SYM=‘)' THEN IF SYM=‘)' THEN

ADVANCEADVANCE ELSE ERRORELSE ERROR ELSE ERRORELSE ERRORENDEND

E → T E' E → T E' E'→ + T E'E'→ + T E' || ε ε T → F T' T → F T' T'→ * F T'T'→ * F T' || ε ε F → ( E )F → ( E ) || idid

44

4.4.2 扩充的巴科斯范式(1)(1) 用花括号用花括号 {α}{α}表示闭包运算表示闭包运算 αα** . .

(2)(2) 用用 {α}{α}0 0 表示表示 αα 可重复可重复 00 次至次至 nn次次 , {α}, {α}0 0 =α=α0 0 = ε= ε

(3)(3) 用用 [α][α] 表示表示 {α}{α}0 0 ,, 即表示即表示 αα 的出现可有可无的出现可有可无 ((等价于等价于 α| εα| ε).).

例例 ::通常的实数可定义为通常的实数可定义为 :: decimal →[sign]integer.{digit}[exponent]decimal →[sign]integer.{digit}[exponent] exponent→E[sign]integerexponent→E[sign]integer integer→ digit{digit}integer→ digit{digit} sign → +|-sign → +|-

nn 00

11

45

4.4.3 例 :

文法文法 :: E → T | E+T E → T | E+T T → F | T*F T → F | T*F F → id |( E ) F → id |( E )

可表示成可表示成 :: E → T { +T }E → T { +T } T → F { *F }T → F { *F } F → id |( E ) F → id |( E )

推导过程:推导过程:E → T E' E → T E' E'→ + T E'E'→ + T E'|| ε ε T → F T' T → F T' T'→ * F T'T'→ * F T'|| ε ε F → ( E )F → ( E ) || idid

46

语法图表示为 :

E

+

T

T

T

*

F

F

F

)

id

E(

E → T { +T }E → T { +T }T → F { *F }T → F { *F }F → id |( E )F → id |( E )

47

E的子程序E的子程序 procedure E;procedure E; beginbegin T;T; WHILE WHILE SYM='+' DOSYM='+' DO begin begin ADVANCE; ADVANCE; T endT end endend

化简的递归子程序ADVANCE: 下一个符号 . SYM: 当前符号 .ERROR: 错误处理程序

TT 的子程序的子程序 procedure T;procedure T; beginbegin F;F; WHILE WHILE

SYM=‘*' DOSYM=‘*' DO begin begin ADVANCE; ADVANCE; F endF end

endend

FF 的子程序的子程序procedure F;procedure F;IF SYM=‘id' THEN IF SYM=‘id' THEN

ADVANCEADVANCEELSEELSE IF SYM=‘(' THENIF SYM=‘(' THEN begin begin ADVANCE; ADVANCE; E;E; endend IF SYM=‘)' THEN IF SYM=‘)' THEN

ADVANCEADVANCE ELSE ERRORELSE ERROR ELSE ERRORELSE ERRORENDEND

E → T { +T }E → T { +T }T → F { *F }T → F { *F }F → id |( E )F → id |( E )

48

消除下列文法的左递归消除下列文法的左递归 :: (2).G[E] :(2).G[E] : E→ ET+E→ ET+|| ET-ET- || TT T → TF*T → TF*|| TF/ TF/ || FF F → (E)F → (E) || ii解解 : : 消除产生式消除产生式 EE的左递归的左递归 :: E → T{(T+|T-)}E → T{(T+|T-)} 消除产生式消除产生式 TT的左递归的左递归 :: T → F{(F*|F/)}T → F{(F*|F/)} 所以所以 ,, 文法消除左递归后变为文法消除左递归后变为 :: E → T{(T+|T-)}E → T{(T+|T-)} T → F{(F*|F/)}T → F{(F*|F/)} F → (E)F → (E) || ii

例 :

49

4.5 预测分析程序实现实现 LL(1)LL(1) 分析的另一种方法是使用一张分析表和分析的另一种方法是使用一张分析表和一个栈进行联合控制一个栈进行联合控制 .. 如图为预测分析器模型如图为预测分析器模型 ::

输入缓冲区

栈栈总控程序

预测分析表

输出输出

二维数组 [非终结符,终结符 a ]表项用于指示产生式或出错标志

50

4.5.1 预测分析程序工作过程 1.1. 预测分析表预测分析表 预测分析表是一个预测分析表是一个 M[A,a]M[A,a]形式的矩阵形式的矩阵 ..

其中其中 ,A,A 为非终结符为非终结符 ,a,a 是终结符或是终结符或 # (## (#表示输入串的结束符表示输入串的结束符 ),), 矩阵元素矩阵元素 M[A,a]M[A,a]中存放着一条关于中存放着一条关于 AA 的产生式的产生式 ,, 指出当指出当AA面临输入符号面临输入符号 aa 时所应采取的候选时所应采取的候选 . M. M[A,a][A,a]中也可能存放着一个”出错标志”中也可能存放着一个”出错标志”,, 指出指出 AA 根本不该面临输入符号根本不该面临输入符号 a.a.

51

4.5.1 预测分析程序工作过程 2.2. 栈栈 栈栈 STACKSTACK用于存放文法符号用于存放文法符号 .. 分析开始分析开始

时时 ,, 栈底先放一个栈底先放一个 #,#, 然后放进文法开始然后放进文法开始符号符号 .. 同时假定输入串之后也总有一个同时假定输入串之后也总有一个 ##,, 标志输入串结束标志输入串结束 ..

52

4.5.1 预测分析程序工作过程 3.3.总控程序总控程序 预测分析的总控程序在任何时候都是按栈预测分析的总控程序在任何时候都是按栈 STACKSTACK 栈顶符号栈顶符号 XX

和当前的输入符号行事的和当前的输入符号行事的 ,, 对任何对任何 (X,a),(X,a),总控程序每次执行下总控程序每次执行下述三种动作之一述三种动作之一 :: (1)(1) 若若 X=a=‘#’, X=a=‘#’, 则宣布分析成功则宣布分析成功 ,,停止分析过程停止分析过程 .. (2)(2) 若若 X=a<>‘#’,X=a<>‘#’, 则把则把 XX从从 STACKSTACK 栈顶逐出栈顶逐出 ,,让让 aa指向指向

下一个输入符号下一个输入符号 .. (3)(3) 若若 XX是一个非终结符是一个非终结符 ,, 则查看分析表则查看分析表 M.M. 若若 M[A,a]M[A,a]中中

存放着关于存放着关于 XX的一个产生式的一个产生式 ,, 那么首先把那么首先把 XX 逐出栈顶逐出栈顶 ,,把把产生式的右部符号串按产生式的右部符号串按反序反序一一推进一一推进 STACKSTACK 栈栈 (( 若右部符若右部符号为号为 ε,ε, 则不推什么东西进栈则不推什么东西进栈 ).). 若若 M[A,a]M[A,a]中存放”出错标中存放”出错标志”志” ,, 则调用出错诊查程序则调用出错诊查程序 ERROR.ERROR.

53

4.5.1 预测分析程序工作过程 4.4.总控程序的描述总控程序的描述 ::BEGINBEGIN 首先把首先把 ## 然后把文法开始符号推进然后把文法开始符号推进 STACK STACK 栈栈 ;; 把第一个输入符号读进把第一个输入符号读进 a;a; FLAG:=TRUE;FLAG:=TRUE; WHILE FLAG DOWHILE FLAG DO BEGIN BEGIN 把栈把栈 STACKSTACK 栈顶符号上托出去并放在栈顶符号上托出去并放在 XX 中中 ;; IF X∈IF X∈ VV TT THEN THEN IF X=a THEN IF X=a THEN 把下一符号读入把下一符号读入 a ELSE ERRORa ELSE ERROR ELSE IF X=‘#’ THENELSE IF X=‘#’ THEN IF X=a THEN FLAG:=FALSE ELSE ERRORIF X=a THEN FLAG:=FALSE ELSE ERROR ELSE IF M[X,a]=[X →XELSE IF M[X,a]=[X →X1 1 XX2 …2 …XXkk] THEN] THEN 把 把 XXk k XXk-1… k-1… XX1 1 一一推进栈 一一推进栈 /*/* 若若 XX1 1 XX2 …2 …XXkk= ε,= ε, 不推什么进栈 不推什么进栈 */*/ ELSE ERRORELSE ERROR END OF WHILEEND OF WHILE STOPSTOPENDEND

54

4.5.2 预测分析表的构造算法

1) 1) 对于每一产生式 对于每一产生式 A→αA→α ,作 ,作 2)2) 和和 3)3) 2) 2) 对于 对于 FIRST(α)FIRST(α) 中的每一终结符中的每一终结符 a, a, 将 将 AA

→α →α 填入 填入 M[A,a]M[A,a] 3) 3) 如果如果 εε 属于 属于 FIRST(α)FIRST(α) ,则对任何,则对任何 b b ∈ ∈ FFOLLOW(A)OLLOW(A) 把 把 A→αA→α 填入 填入 M[A,b]M[A,b] ;;

4) 4) 将所有无定义的 将所有无定义的 M[A,b] M[A,b] 标上错误标志。标上错误标志。

55

表达式文法的预测分析表输入符号非终

结符i d + * ( ) #

E → TE’ → TE’

E' → +TE → ε → ε

T → FT’ → FT’

T' → ε → *FT’ → ε → ε

F → i d → (E)

56

执行例:分析 id+id*id栈 输入缓冲区 输出栈 输入缓冲区 输出#E id+id*id# #E id+id*id# #E'T id+id*id# E → TE'#E'T id+id*id# E → TE'#E'T'F id+id*id# T → FT'#E'T'F id+id*id# T → FT'#E'T'id id+id*id# F → id#E'T'id id+id*id# F → id#E'T' +id*id# #E'T' +id*id# #E' +id*id# T' → ε#E' +id*id# T' → ε#E'T+ +id*id# E' → +TE'#E'T+ +id*id# E' → +TE'#E'T id*id# #E'T id*id#

57

分析过程

#E'T id*id# #E'T id*id# #E'T'F id*id# T → FT'#E'T'F id*id# T → FT'#E'T'id id*id# F → id#E'T'id id*id# F → id#E'T' *id# #E'T' *id# #E'T'F* *id# T' → *FT'#E'T'F* *id# T' → *FT'#E'T'F id##E'T'F id##E'T'id id# F → id#E'T'id id# F → id#E'T' ##E'T' ##E' # T' → ε#E' # T' → ε# # E' → ε# # E' → ε

输出的产生式序列形成了按最左推导生成的分析树输出的产生式序列形成了按最左推导生成的分析树

58

预测分析法(状态矩阵法) 1) 1) 编写文法,消除二义性;编写文法,消除二义性; 2) 2) 消除左递归、提取左因子;消除左递归、提取左因子; 3) 3) 求 求 FIRST FIRST 集和 集和 FOLLOW FOLLOW 集集 44)检查是不是 )检查是不是 LL(1) LL(1) 文法文法

若不是 若不是 LL(1),LL(1), 说明文法的复杂性超过自顶向下方法的说明文法的复杂性超过自顶向下方法的分析能力 分析能力

55) 按照 ) 按照 LL(1) LL(1) 文法构造预测分析表文法构造预测分析表 66) 实现预测分析器) 实现预测分析器

59

4.6 LL(1) 分析中的错误处理 在预测分析过程中在预测分析过程中 ,, 出现下面两种情况出现下面两种情况 ,, 说明遇到说明遇到

语法错误语法错误 .. (1)(1) 栈顶的终结符与当前的输入符号不匹配栈顶的终结符与当前的输入符号不匹配 .. (2)(2) 非终结符非终结符 AA 处于栈顶处于栈顶 ,,面临的输入符号为面临的输入符号为 a,a, 但分析但分析

表表 M[A,a]M[A,a]为空为空 .. 解决错误的方法解决错误的方法

跳过输入串中的一些符号直至遇到”同步符号”为止跳过输入串中的一些符号直至遇到”同步符号”为止 ..

60

例 :求文法求文法 G[S]G[S] 的的 FIRSTFIRST集和集和 FOLLOWFOLLOW集集 : : S → AB S → bC A → ε A → bS → AB S → bC A → ε A → b B → ε B → aD C → AD C → bB → ε B → aD C → AD C → b D → aS D → cD → aS D → c

解解 ::FIRST(S)={FIRST(A)\{ε}}∪{FIRST(B)\{ε}}∪{ε} ∪{b}={b,a, εFIRST(S)={FIRST(A)\{ε}}∪{FIRST(B)\{ε}}∪{ε} ∪{b}={b,a, ε}}

FIRST(A)={ε}}∪{b}={ε,b}FIRST(A)={ε}}∪{b}={ε,b}FIRST(B)={ε}}∪{a}={ε,a}FIRST(B)={ε}}∪{a}={ε,a}FIRST(C)={FIRST(A)\{ε}}∪{FIRST(D)} ={b,a,c}FIRST(C)={FIRST(A)\{ε}}∪{FIRST(D)} ={b,a,c}FIRST(D)={a}}∪{c}={a,c}FIRST(D)={a}}∪{c}={a,c}

61

解 :求文法求文法 G[S]G[S] 的的 FIRSTFIRST集和集和 FOLLOWFOLLOW集集 : : S → AB S → bC A → ε A → bS → AB S → bC A → ε A → b B → ε B → aD C → AD C → bB → ε B → aD C → AD C → b D → aS D → cD → aS D → c

FOLLOW FOLLOW 集集 ::FOLLOW(S)={#}∪{FOLLOW(D)}FOLLOW(S)={#}∪{FOLLOW(D)}FOLLOW(A)={FIRST(B)\{ε}}∪FOLLOW(S) ∪FIRST(D)FOLLOW(A)={FIRST(B)\{ε}}∪FOLLOW(S) ∪FIRST(D)FOLLOW(B)= FOLLOW(S) FOLLOW(B)= FOLLOW(S) FOLLOW(C)= FOLLOW(S) FOLLOW(C)= FOLLOW(S) FOLLOW(D)= FOLLOW(B) ∪ FOLLOW(C) FOLLOW(D)= FOLLOW(B) ∪ FOLLOW(C) 即即 :FOLLOW(S)={#}, FOLLOW(A)={a,#,c}, FOLLOW(B)={#},:FOLLOW(S)={#}, FOLLOW(A)={a,#,c}, FOLLOW(B)={#}, FOLLOW(C)={#}, FOLLOW(D)={#}FOLLOW(C)={#}, FOLLOW(D)={#}

62

例 :

已知文法已知文法 GG 为为 : : S → a|^|(T) S → a|^|(T) T → T,S|S T → T,S|S (1)(1) 消去文法消去文法 GG的左递归,并对每个非终结符写出的左递归,并对每个非终结符写出

不带回溯的递归子程序。不带回溯的递归子程序。(2)(2)改写后的文法改写后的文法 G’G’是否是是否是 LL(1)LL(1) 文法文法 ? ? 构造构造

文法文法 G’G’的预测分析表。的预测分析表。

63

解 :(1)(1) 由于文法由于文法 GG 含有左递归,所以先消除含有左递归,所以先消除 左递归,即将左递归,即将 T→ T,S|S T→ T,S|S 改写为:改写为: T → ST’T → ST’ T’ →,ST’| εT’ →,ST’| ε 也即文法也即文法 G’ G’ 为:为: S → a|^|(T)S → a|^|(T) T → ST’T → ST’ T’ →,ST’| εT’ →,ST’| ε

S → a|^|(T) S → a|^|(T)

T → T,S|ST → T,S|S

64

解 :(2)(2) 对应非终结符对应非终结符 S,T,T’S,T,T’的递归子程序的递归子程序 ::

S → a|^|(T)S → a|^|(T)T → ST’T → ST’T’ →,ST’| εT’ →,ST’| ε

Procedure T;Procedure T;begin begin S;T’S;T’endend

Procedure T’;Procedure T’;begin begin if SYM=‘,’ if SYM=‘,’ thenthen begin begin advance;advance; S;T’S;T’ endendendend

Procedure S;Procedure S;begin begin if SYM=‘a’ or SYM=‘^’ thenif SYM=‘a’ or SYM=‘^’ then advanceadvance elseelse if SYM=‘(’ thenif SYM=‘(’ then beginbegin advanceadvance T;T; if SYM=‘)’ then advanceif SYM=‘)’ then advance else errorelse error endend else errorelse errorendend

65

解 :(3)(3) 为了构造预测分析表,首先需求出为了构造预测分析表,首先需求出 文法文法 G’G’的的 FIRSTFIRST 集和集和 FOLLOWFOLLOW集。集。 FIRST(S)={ a,^,( }FIRST(S)={ a,^,( } FIRST(T’)={,,ε}FIRST(T’)={,,ε} FIRST(T)=FIRST(S)\{ε}={ a,^,( }FIRST(T)=FIRST(S)\{ε}={ a,^,( } FOLLOW(S)={ #, ,,) }FOLLOW(S)={ #, ,,) } FOLLOW(T)={ ) }FOLLOW(T)={ ) } FOLLOW(T’)={ ) }FOLLOW(T’)={ ) } 构造分析表: 构造分析表:

S → a|^|(T) S → a|^|(T) T → ST’ T → ST’

T’ →,ST’|εT’ →,ST’|ε

aa ^̂ (( )) ,, ##

SS S →aS →a S →^S →^ S →(T)S →(T)

TT T →ST’T →ST’ T →ST’T →ST’ T →ST’T →ST’

T’T’ T’ → T’ → εε T’ →,ST’T’ →,ST’

文法文法 G’G’是是 LL(1)LL(1) 文文法法 ..

66

例 :

已知文法已知文法 GG 为为 : : E → TE’E → TE’ E’ → +E|εE’ → +E|ε T → FT’T → FT’ T’ → T| εT’ → T| ε F → PF’F → PF’ F’ → *F’|εF’ → *F’|ε P → (E)|^|a|bP → (E)|^|a|b(1)(1) 计算文法计算文法 GG的每个非终结符的的每个非终结符的 FIRSTFIRST 集和集和 FOLLOWFOLLOW集。集。(2)(2) 证明文法证明文法 GG为为 LL(1)LL(1) 文法。文法。(3)(3) 构造文法构造文法 GG的预测分析表。的预测分析表。

67

解 :因为因为 FIRST(P)={(,^,a,b},FIRST(P)={(,^,a,b}, 而而 E→T…, T→F…,F→P… E→T…, T→F…,F→P… 所以有所以有 FIRST(E)=FIRST(T)=FIRST(F)=FIRST(P)= {(,FIRST(E)=FIRST(T)=FIRST(F)=FIRST(P)= {(,^,a,b} ^,a,b} 因为因为 FIRST(T’)={ε},FIRST(T’)={ε},且且 T’→T, T’→T, 所以:所以: FIRST(T’)= {(,^,a,b,ε} FIRST(T’)= {(,^,a,b,ε} FIRST(E’)={+,ε} FIRST(F’)={*,ε}FIRST(E’)={+,ε} FIRST(F’)={*,ε} FOLLOW(E)={ #,)} FOLLOW(E’)={#,) }FOLLOW(E)={ #,)} FOLLOW(E’)={#,) } FOLLOW(T)={#,),+} FOLLOW(F)={(,^,a,b,#,),+}FOLLOW(T)={#,),+} FOLLOW(F)={(,^,a,b,#,),+} FOLLOW(F’)={(,^,a,b,#,),+}FOLLOW(F’)={(,^,a,b,#,),+} FOLLOW(P)={(,^,a,b,#,),+}FOLLOW(P)={(,^,a,b,#,),+}

68

解 :2. 2. 根据根据 LL(1)LL(1) 文法的充要条件:文法的充要条件: P → (E)|^|a|b P → (E)|^|a|b 满足调件满足调件 1. 1. 而以下式子满足条件而以下式子满足条件 22 FIRST(+E)∩FOLLOW(E’)= φFIRST(+E)∩FOLLOW(E’)= φ FIRST(T)∩FOLLOW(T’)= φFIRST(T)∩FOLLOW(T’)= φ FIRST(*F’)∩FOLLOW(F’)= φFIRST(*F’)∩FOLLOW(F’)= φ 所以文法所以文法 GG是是 LL(1)LL(1) 文法。文法。

69

解 :3. 3. 构造分析表:构造分析表:

++ ** (( )) aa bb ^̂ ##

EE TE’TE’ TE’TE’ TE’TE’ TE’TE’

E’E’ +E+E εε εε

TT FT’FT’ FT’FT’ FT’FT’ FT’FT’

T’T’ εε TT εε TT TT TT εε

FF PF’PF’ PF’PF’ PF’PF’ PF’PF’

F’F’ εε *F’*F’ εε εε εε εε εε εε

PP (E)(E) aa bb ^̂

70

例 :设文法设文法 G[S]: G[S]: S → SbAS → SbA || aA aA B → Sb B → Sb A → BcA → Bc(1)(1) 将此文法改写为将此文法改写为 LL(1)LL(1) 文法文法(2)(2) 求文法的每一个非终结符号的求文法的每一个非终结符号的 FIRSTFIRST 集合和集合和 FOLLOWFOLLOW集合集合

(3)(3) 构造相应的构造相应的 LL(1)LL(1) 分析表分析表解解 : : (1).(1).改写文法为改写文法为 LL(1)LL(1) 文法文法 因为文法因为文法 S → SbAS → SbA || aAaA 有左递归有左递归 ,,故将其改写为故将其改写为 : : S → aA{bA}S → aA{bA} 文法变为文法变为 :: S → aA{bA}S → aA{bA} B → Sb B → Sb A → BcA → Bc 这样的文法满足这样的文法满足 LL(1)LL(1) 文法的条件文法的条件

71

解 :(2)(2) 文法的每一个非终结符号的文法的每一个非终结符号的 FIRSTFIRST集合集合 :: FIRST(S)={a}FIRST(S)={a} FIRST(A)={a}FIRST(A)={a} FIRST(B)={a}FIRST(B)={a}

文法的每一个非终结符号的文法的每一个非终结符号的 FOLLOWFOLLOW集合集合 ::

因为 因为 SS 为开始符号为开始符号 ,,且有产生式 且有产生式 S → aA{bA} S → aA{bA} 和 和 B → Sb B → Sb

所以所以 : FOLLOW(S)={#} FIRST(b)={#,b}∪: FOLLOW(S)={#} FIRST(b)={#,b}∪因为 因为 S → aA{bA} S → aA{bA}

所以所以 : FOLLOW(A)=FOLLOW(S) FIRST(bA)= {#,b}∪: FOLLOW(A)=FOLLOW(S) FIRST(bA)= {#,b}∪因为 因为 A → Bc A → Bc

所以所以 : FOLLOW(B)=FIRST(c)= {c}: FOLLOW(B)=FIRST(c)= {c}

S → aA{bA} S → aA{bA} B → Sb B → Sb A → BcA → Bc

72

解 :(3)(3) 构造相应的构造相应的 LL(1)LL(1) 分析表分析表 因为 因为 FIRST(S)={a} FIRST(S)={a}

所以 所以 M[S,a]=“S → aA{bA} ”M[S,a]=“S → aA{bA} ”

因为 因为 FIRST(A)={a} FIRST(A)={a}

所以 所以 M[A,a]=“A → Bc ”M[A,a]=“A → Bc ”

因为 因为 FIRST(B)={a} FIRST(B)={a}

所以 所以 M[B,a]=“B → Sb ”M[B,a]=“B → Sb ”

文法文法 G[S] G[S] 的分析表为的分析表为 ::

S → aA{bA} S → aA{bA} B → Sb B → Sb A → BcA → Bc

aa bb cc dd

SS S → aA{bA}S → aA{bA}

AA A → BcA → Bc

BB B → SbB → Sb

73

例 :已知文法已知文法 GG 为为 : : A → aABlA → aABl|| a a B → Bb |dB → Bb |d(1)(1) 试给出与文法试给出与文法 GG 等价的等价的 LL(1)LL(1) 文法文法 G’ ;G’ ;(2)(2) 构造构造 G’G’的预测分析表的预测分析表 , , 给出输入串给出输入串 aadl#aadl#的的

分析过程。分析过程。解解 : : (1).(1).改写文法为改写文法为 LL(1)LL(1) 文法文法 将将 A → aABlA → aABl|| aa改为改为 : : A → aA’A → aA’ A’ →Abl| εA’ →Abl| ε 而将而将 BB 改为改为 :: B → dB’ B → dB’ B’ → bB’ | εB’ → bB’ | ε

74

解:即改造后的文法即改造后的文法 G’G’ 为为 : :

A → aA’A → aA’ A’ →Abl| εA’ →Abl| ε B → dB’ B → dB’ B’ → bB’ | εB’ → bB’ | ε文法文法 G’G’的的 FIRST FIRST 集和集和 FOLLOW FOLLOW 集:集:FIRST(A)={a} FIRST(A’)={a,ε}, FIRST(B)={d},FIRST(A)={a} FIRST(A’)={a,ε}, FIRST(B)={d},FIRST(B’)={b,ε}FIRST(B’)={b,ε}FOLLOW(A)={d,#}, FOLLOW(A’)={d,#},FOLLOW(A)={d,#}, FOLLOW(A’)={d,#},FOLLOW(B)={l},FOLLOW(B’)={l}’FOLLOW(B)={l},FOLLOW(B’)={l}’

75

解:

判断判断 G’G’ 是否为是否为 LL(1)LL(1) 文法文法文法文法 G’G’ 形如 形如 A → αA → α || ββ的产生式有:的产生式有:A’ →Abl| ε A’ →Abl| ε B’ → bB’ | εB’ → bB’ | ε它们满足条件 它们满足条件 FIRST( α ) ∩ FIRST( β ) = φFIRST( α ) ∩ FIRST( β ) = φFIRST(Abl) ∩FOLLOW(A’)={a} ∩{d,#}= φFIRST(Abl) ∩FOLLOW(A’)={a} ∩{d,#}= φFIRST(bB’) ∩FOLLOW(B’)={b} ∩{l}= φFIRST(bB’) ∩FOLLOW(B’)={b} ∩{l}= φ满足条件满足条件 2. 2. 所以文法所以文法 G’G’是是 LL(1)LL(1) 文法。文法。

A → aA’A → aA’A’ →Abl| εA’ →Abl| εB → dB’ B → dB’ B’ → bB’ | εB’ → bB’ | ε

76

解:

文法文法 G’G’ 的预测分析表的预测分析表 ::

A → aA’A → aA’A’ →Abl| εA’ →Abl| εB → dB’ B → dB’ B’ → bB’ | εB’ → bB’ | ε

aa bb ll dd ##AA A → aA’A → aA’

A’A’ A’ →AblA’ →Abl A’ → εA’ → ε A’ → εA’ → ε

BB B → dB’B → dB’

B’B’ B’ → bB’ → bB’B’

B’ → εB’ → ε

77

解: aadl# 的分析过程栈顶栈顶符号符号

栈栈 输入符输入符号号

输入输入串串

动作动作

#A#A aadl#aadl# 初始状态,移进并弹出栈顶符号初始状态,移进并弹出栈顶符号

AA ## aa adl#adl# 按按 A → aA’A → aA’, , 将将 aA’aA’ 反序压栈反序压栈

#A’a#A’a aa adl#adl# 弹出栈顶符号弹出栈顶符号

aa #A’#A’ aa adl#adl# 栈顶符号栈顶符号 == 输入符号输入符号 ,, 移进并弹出栈顶符移进并弹出栈顶符号号

A’A’ ## aa dl#dl# 按按 A’ →Abl,A’ →Abl, 将将 AblAbl 反序压栈反序压栈

#lBA#lBA aa dl#dl# 弹出栈顶符号弹出栈顶符号

AA #lB#lB aa dl#dl# 按按 A → aA’A → aA’, , 将将 aA’aA’ 反序压栈反序压栈

#lBA’a#lBA’a aa dl#dl# 弹出栈顶符号弹出栈顶符号

aa #lBA’#lBA’ aa dl#dl# 栈顶符号栈顶符号 == 输入符号输入符号 ,, 移进并弹出栈顶符移进并弹出栈顶符号号

78

解: aadl# 的分析过程栈顶栈顶符号符号

栈栈 输入符输入符号号

输入输入串串

动作动作

A’A’ #lB#lB dd l#l# A’ → ε, A’ → ε, 弹出栈顶符号弹出栈顶符号BB #l#l dd l#l# 按按 B → dB’B → dB’, , 将将 dB’dB’ 反序压栈反序压栈

#lB’d#lB’d dd l#l# 弹出栈顶符号弹出栈顶符号dd #lB’#lB’ dd l#l# 栈顶符号栈顶符号 == 输入符号输入符号 ,, 移进并弹出栈顶符移进并弹出栈顶符

号号B’B’ #l#l ll ## B’ → ε, B’ → ε, 弹出栈顶符号弹出栈顶符号ll ## ll ## 栈顶符号栈顶符号 == 输入符号输入符号 ,, 移进并弹出栈顶符移进并弹出栈顶符

号号## ## #=#, #=#, 分析成功分析成功

79

例 :构造构造 G[S]G[S] 的的 LL(1)LL(1) 分析表 分析表 S → aAbDeS → aAbDe|| d d A → BSDA → BSD|| e e B → SAcB → SAc || cDcD|| ε ε D → SeD → Se|| ε ε

aa bb cc dd ee ##

SS SS→→AbDeAbDe dd

AA AA→→BSDBSD AA→→BSDBSD AA→→ BSD BSD ee

BB BB→→SAc/SAc/εε BB→→ cD cD BB→→SAc/SAc/εεDD DD→→ DSe/ DSe/εε DD→→εε DD→→ εε DD→→ Se/ Se/εε εε

top related