【編譯原理】求First和Follow


寫這篇博客的原因,是因為考試前以為自己已經將這個問題弄清楚了,但是,考試的時候,發現自己還是不會,特別是求follow集合。雖然考試結束了,希望可以幫助屏幕前的你,可以真正理解這個問題。

碼字和做視頻都不容易,可以給個三連嗎?嗷嗚~

2020-09-12更新第一版

2021-04-13更新第二版

2021-06-22更新第三版

講解視頻

博客對應的視頻教程地址(一定要看看):https://www.bilibili.com/video/BV17K4y1a72M#reply4409274160

視頻中的一些問題

下面列舉的問題可以先不看,等到視頻看完,再拉到對應的時間點看視頻中小小的錯誤

視頻的05:12 剪輯視頻的時候寫錯了,正確的應該是First(β) 
視頻的07:11 忘記計算First(T)和Follow(T),筆記中補了
視頻的09:09 利用規則2或3兩邊可以是一樣的非終結符
視頻的12:03 First(E')和First(T')應該用逗號分隔

image-20210413214242541


image-20210413214917997


image-20210413221359517
在這里插入圖片描述

First集

官方定義

設G=(VT,VN,S,P)是上下文無關文法 ,則

image-20200911080521074

理解定義

不求信達雅,但求“說人話”。官方定義看不懂?下面的描述比較通俗易懂。

FIRST(A)是以A的開始符的集合,A的所有可能推導的開頭終結符或者是ε

例子

通過例子來加強理解。

  1. 后面跟的不是非終結符
...
A->aB|ε
A->c
...
First(A)={a,ε,c}
  1. 后面跟非終結符(一)
...
A->Ba
B->b
...
First(A)={b}
  1. 后面跟非終結符(二)
...
A->Bc
B->b|ε
...
First(A)={b,c}
  1. 后面跟非終結符(三)
...
A->BC
B->b|ε
C->c|ε
...
First(A)={b,c,ε}

Follow集

相對於First集,Follow集的理解會稍微難一點,但是認真聽,還是簡單的。

官方定義

這個是信達雅版本的定義

假定S是文法G的開始符號,對於G的任何非終結符A,我們定義

image-20200911080541959

理解定義

這個是“說人話”版本的定義

Follow(A)為非終結符A后跟符號的集合,Follow(A)是所有句型中出現在緊接A之后的終結符或'#'

求解規則

(1)對於文法的開始符號S,置#於Follow(S)中;

(2)若A->αBβ是一個產生式,則把First(β) \ {ε} 加入到Follow(B)中

(3)若A->αB是一個產生式,或A->αBβ是一個產生式且β=>ε,則把Follow(A)加入到Follow(B)中

理解求解規則

(1)對於開始符號,首先將#放入Follow集中

(2)形如A->αBβ

(α可以是終結符或者非終結符或者直接為空,β可以是終結符或者非終結符,
注意β不能為空,B后面要有東西
注意β不能為空,B后面要有東西
注意β不能為空,B后面要有東西

比如

A->aBC
A->aBd
A->BC
A->Bd

將First(β) \ {ε}(即First(β)除去ε) 加入到Follow(B)中

(3)形如A->αB(α可以是終結符或者非終結符或者直接為空)或者A->αBβ是一個產生式且β=>ε

比如

A->B
A->cB

A->dBC
C->ε

將Follow(A)加入到Follow(B)中

綜合例子

讓我們通過例子來對上面的知識點進行梳理和再次的理解。

綜合例子一

注意:[if] 是一個終結符,同理[b] [other] [else] [then]

G(S):S->IETSP|O
I->if
E->b
O->other
L->else
T->then
P->LS|ε
First Follow
First(S)={if,other} Follow(S)={#,else}
First(I)={if} Follow(I)={b}
First(E)={b} Follow(E)={then}
First(O)={other} Follow(O)={else,#}
First(L)={else} Follow(L)={if,other}
First( P )={else,ε} Follow( P )={else,#}
First(T)={then} Follow(T)={if,other}

綜合例子一 中反饋的問題:

  • S->IETSP|O 中求Follow(S)能運用規則2和3來求解S嗎?

解答:

可以的,雖然規則中給出的是A和B兩個不同的非終結符,但是
A和B在實際運用的過程中是可以相等的,即B=A
A和B在實際運用的過程中是可以相等的,即B=A
A和B在實際運用的過程中是可以相等的,即B=A
S->IETSP|O S后面有P,利用規則3,將First(P)加入Follow(S)中
但是,發現P可以等於ε,即S->IETS,利用規則二,將Follow(S)加入Follow(S)中
  • 在求Follow(S)發現P->LS|ε也是存在的,那么follow(s)={#,else}+follow( p ),而算到follow( p )發現follow( p )=follow(s) 就不知道怎么算了

解答:(很重要,認認真真地看)

我們需要同時滿足
follow(s)={#,else}+follow(p)
follow(p)=follow(s)
將第二個式子帶入一式得到
follow(s)={#,else}+follow(s)
注意:不能將follow(s)約掉,而是要想怎么樣上面的等式仍然成立
那么,我們就會發現follow(s)只能等於{#,else}
因為 {#,else}={#,else}+{#,else}是成立的

綜合例子二

G(E):E->TE'
E'->+TE'|ε
T->FT'
T'->*FT'|ε
F->(E)|i
First Follow
First(E)={(,i} Follow(E)={#,)}
First(E')={+,ε} Follow(E')={#,)}
First(T)={(,i} Follow(T)={+,#,)}
First(T')={*,ε} Follow(T')={+,#,)}
First(F)={(,i} Follow(F)={*,+,#,)}

綜合例子二 中反饋的問題:

  • 為什么求E的FOLLOW集看到F->(E)|I直接將)右括號直接加入Follow中

解答:

這個問題需要回到最初的定義來理解
follow集的意思是緊跟后面的符號集,E后面有),即E后面有終結符。
屬於規則二,但是終結符沒有first和follow,所以直接添加即可。

綜合例子三

G[S]: S→aH
H→aMd
H→d
M→Ab
M→ε
A→aM
A→e
First Follow
First(S)={a} Follow(S)={#}
First(H)={a,d} Follow(H)={#}
First(M)={a,e,ε} Follow(M)={d,b}
First(A)={a,e} Follow(A)={b}

綜合例子四

G(E):E->TE'
E'->+E|ε
T->FT'
T'->T|ε
F->PF'
F'->*F'|ε
P->(E)|a|b|^
First Follow
First(E)={(,a,b,^} Follow(E)={#,)}
First(E')={+,ε} Follow(E')={#,)}
First(T)={(,a,b,^} Follow(T)={+,#,)}
First(T')={(,a,b,^,ε} Follow(T')={+,#,)}
First(F)={(,a,b,^} Follow(F)={(,a,b,^,+,#,)}
First(F')={*,ε} Follow(F')={(,a,b,^,+,#,)}
First( P )={(,a,b,^} Follow( P )={*,(,a,b,^,+,#)}

綜合例子四中反饋的問題:

怎么求follow(E)和follow(E‘)?

根據G(E)和規則一,#加入follow(E)
根據P->(E)|a|b|^和規則二,)加入follow(E)
根據E'->+E|ε和規則三,將follow(E')到follow(E)里面

根據E->TE'和規則三得到將follow(E)到follow(E‘)里面 

=>
Follow(E)={#,)}+Follow(E')
Follow(E')=Follow(E)
根據綜合例子一中一樣的分析方法
Follow(E)={#,)}+Follow(E)=>Follow(E)={#,)}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM