2020编译原理(五)------绕绕绕的First,Follow,Select集

,为了更好的进行自顶向下的语法分析,以及判断LL(1)文法,最后介绍的便是FIRST集,FOLLOW集和SELECT集.

一. FIRST 集

为了更好的理解,我们通过一个例子来挨个介绍。
文法G[S]
S->AB|bC
A->#|b
B->aD|#
C->AD|b
D->aS|c

【注】:#表示空
1.FIRST集是一个文法符号串所可能推导出的符号串的第一个终结符的集合
2.因为有公共左因子的问题,所以要引入FIRST集的概念,公共左公因子是指在文法的产生式集合中,某个非终结符的多个候选式具有相同的前缀。

了解了一些基本概念之后,我们就进入正题分析一下各个非终结符的FIRST集。

FIRST(S)
由S->AB和S->bC,可以知道FIRST(S)={b},
然后S->AB先放在一边。

由A->#|b,可以得出S->B和S->bB,FIRST(S)={b},进一步推出S->aD和S->#
最后便可总结起来:FIRST(S)={a,b,#)

二.FOLLOW集

1.定义:设G=(Vt,Vn,P,S),上下文无关文法,A∈Vn,S是开始符号,FOLLOW(A)={a|S=*>uAb&&a∈Vt,a∈FIRST(b),u∈Vt,b∈V*}
只有非终结符的FOLLOW集才有定义

2.对于文法的开始符号S,置 # 于 FOLLOW(S)中.
若 A →aBβ 是一个产生式, 则把 FIRST(β)\ε 加至 FOLLOW(B) 中.
若 A →aB 是一个产生式,或 A →aBβ是一个产生式而 β⇒ε,则把 FOLLOW(A) 加至 FOLLOW(B) 中.
【例】
S->BS’
S’->aB|ε
B->DB’
B’->B|ε
D->d|ε
求各个非终结符的FOLLOW集
FOLLOW(S)
因为S 是开始符号,所以将#置于FOLLOW(S)中,在产生式右部找S,没有所以FOLLOW(S)={#}
FOLLOW(S’)
根据第三条规则,S->BS’,将FOLLOW(S)加到FOLLOW(S’),然后再找其他的S’在右部的,没有就过了。所以FOLLOW(S’)={#}
FOLLOW(B)
根据第二条规则,S->BS’,FOLLOW(B)=FIRST(S’)\ε={a}
根据第三条规则,S’->aB,FOLLOW(B)=FOLLOW(S’)={#}
还有就是第三条规则,S->BS’,又因为S’->ε,S->B,FOLLOW(B)=FOLLOW(S)={#}
综上所述:FOLLOW(B)={a,#}
FOLLOW(B’)
根据第三条规则,B->DB’,FOLLOW(B’)=FOLLOW(B)={a,#}
FOLLOW(D)
根据第二条规则,B->DB’,FOLLOW(D)=FIRST(B’)\ε={b}

三.SELECT集

1.Select集合就是产生式左部的可能的推导结果的起始符号。

2.Select(A–>B)就是求这个产生式中A可能推导出起始符号集合(不包含空串ε)。
求Select集合可分如下几种情况:

  • A–>X (X为任意文法符号串,不限于非终结符或单个符号),并且X不能推导出空串 ε,根据定义,显然A推出的符号串起始就是X的起始,也就是First(X).Select(A–>X)= First(X)
  • A–>X (X为任意文法符号串,不限于非终结符或单个符号),并且X能推导出空串ε,根据定义,显然First(X)属于Select(A–>X),此外,当X推导为空串时,显然A 也推导为空串,那么此时推导出的符号串就会是A后面的符号的推导结果。也就是 Follow(A),所以,此时Follow(A)也属于Select(A–>X)
  • Select集合中不包括空串ε,但有可能会包含#(句子括号)。

四.最后是一道例题,可以很好地利用一下上面所有规则。

S→AB|bC
A→b|ε
B→aD|ε
C→AD|b
D→aS|c
求FIRST,FOLLOW,SELECT集
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

经过一番绕绕绕的推导,终于拨开云雾见青天,具体过程欢迎大家一起探讨~~~~~

修正:SELECT集 中

select (A->ε) = First (ε)- ε + Follow(A) = {a,b,#}

谢谢热心网友批评指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章