天天看點

FOLLOW集的不動點算法

FIRST集合意義明确,求解直覺,不再贅述

FOLLOW集的不動點算法

先給出僞碼:

//init 
foreach(nonterminal N)
	FOLLOW(N) = {}
//開始符号S
FOLLOW(S) = { $ }

while(somw set is changing)
	foreach (production p: N->β1 ... βn)
	temp = FOLLOW(N)
	foreach (βi from βn downto β1)
		if(βi == a...)
			temp = {a}
		if(βi == M...)
			FOLLOW(M) ∪= temp
			if(M is not NULLABLE)
				temp = FIRST(M)
			else 
				temp ∪= FIRST(M)
           

為什麼這樣做呢?

因為如果有N->β1 …βn-2 βn-1βn

  • 如果βn-1是一個終結符,那麼一定會有一個句型根據廣義推導,使得βn-1跟在βn-2後,是以應該有

    βn-2 ∈ FOLLOW(βn-1)

  • 如果βn-1是一個非終結符,并且βn-1推不出ε,那麼有, FIRST(βn-1) ∈ FOLLOW(βn-2)
  • 如果βn-1是一個非終結符,并且βn-1可以經過若幹推導産生ε,也即 ε∈FIRST(βn-1), FIRST(βn-1) ∈ FOLLOW(βn-2),并且βn-1可以推到産生ε,FIRST(βn) 也可以加入FOLLOW(βn-2)

注意上述推導都是逆序周遊每一個産生式。

還是不懂?沒關系,我們來看一個例子,直覺的感受一下這個算法。

設有文法G[S]

S − > A A − > B A ′ A ′ = > i B A ′ ∣ ϵ B − > C B ′ B ′ − > + C B ′ ∣ ϵ C − > ) A ∗ ∣ ( S->A\\A->BA'\\A'=>iBA'|ϵ\\B->CB'\\B'->+CB'|ϵ\\C->)A*|( S−>AA−>BA′A′=>iBA′∣ϵB−>CB′B′−>+CB′∣ϵC−>)A∗∣(

求每個非終結符FOLLOW集

FIRST(S)={( , )}

FIRST(A)={( , )}

FIRST(A’)={ i,ε }

FIRST(B)={( , )}

FIRST(B’)={ +,ε }

FIRST©={( , )}

開始求解FOLLOW集:

第一次周遊 第二次周遊 第三次周遊(沒有變化,算法終止)
FOLLOW(S) { $ } { $ } { $ }
FOLLOW(A) { $ , * } { $ , * } { $ , * }
FOLLOW(A’) { $ } { $ , * } { $ , * }
FOLLOW(B) { $ , i } { $ , i , * } { $ , i , * }
FOLLOW(B’) { $ , i } { $ , i , * } { $ , i , * }
FOLLOW© { $, *,+ , i } { $, *,+ , i } { $, *,+ , i }

繼續閱讀