编译原理FIRST集和FOLLOW集
一、FIRST集
定义:
设
G
=
(
V
T
,
V
N
,
S
,
P
)
G=(V_T,V_N,S,P)
G=(VT,VN,S,P)是上下文无关文法,则
F
I
R
S
T
(
α
)
=
a
∣
α
⇒
a
.
.
.
,
a
∈
V
T
FIRST(\alpha)= { a\vert \alpha\Rightarrow a...,a \in V_T }
FIRST(α)=a∣α⇒a...,a∈VT
理解定义:
FIRST(A)是以A为开始符的集合,即左边为A的产生式的集合,A的所有可能推导的开头终结符或者是
ϵ
\epsilon
ϵ
例子:
1.右边不是以非终结符开头
A->aB|
ϵ
\epsilon
ϵ
A->c
左边为A的产生式有两个,且右边都以终结符开头或
A
⇒
ϵ
A\Rightarrow \epsilon
A⇒ϵ,First(A)即为开头的终结符或
ϵ
\epsilon
ϵ
First(A)={a,c,
ϵ
\epsilon
ϵ}
2.右边以非终结符开头(1)
A->Ba
B->b
A继续往后推导得到A->ba,此时满足条件1,所以
First(A)={b}
3.右边以非终结符开头(2)
A->Bc
B->b|
ϵ
\epsilon
ϵ
A继续推导可得到A->bc、A->
ϵ
\epsilon
ϵc,第一个式子满足条件1,第二个式子以
ϵ
\epsilon
ϵ开头,可忽略
ϵ
\epsilon
ϵ得到A->c,所以
First(A)={b,c}
4.右边以非终结符开头(3)
A->BC
B->b|
ϵ
\epsilon
ϵ
C->c|
ϵ
\epsilon
ϵ
此时A可推导出A->bC,A->
ϵ
\epsilon
ϵC,第二个式子忽略
ϵ
\epsilon
ϵ继续推导可得到A->c,A->
ϵ
\epsilon
ϵ,A直接推导出
ϵ
\epsilon
ϵ需加入First,所以
First(A)={b,c,
ϵ
\epsilon
ϵ}
Follow集
定义:
假定S是文法G的开始符号,对于G的任何非终结符A,我们定义
F
O
L
L
O
W
(
A
)
=
a
∣
S
⇒
.
.
.
A
a
.
.
.
,
a
∈
V
T
FOLLOW(A)={a\vert S\Rightarrow...Aa...,a\in V_T}
FOLLOW(A)=a∣S⇒...Aa...,a∈VT
理解定义
Follow(A)为非终结符A后跟符号的集合,Follow(A)是所有句型中出现在紧接A之后的终结符或’#’
求解规则
(1)对于文法的开始符号S,置#于Follow(s)中;
(2)若A->
α
\alpha
αB
β
\beta
β是一个产生式,则把First(
β
\beta
β)-{
ϵ
\epsilon
ϵ}加入到Follow(B)中
(3)A->
α
\alpha
αB是一个产生式,或A->
α
\alpha
αB
β
\beta
β是一个产生式且
β
⇒
ϵ
\beta \Rightarrow\epsilon
β⇒ϵ,则把Follow(A)加入到Follow(B)中
理解求解规则
(1)对于开始符号S,首先将#放入Follow(S)中
(2)形如A->
α
\alpha
αB
β
\beta
β
(
α
\alpha
α可以是终结符或者直接为空,
β
\beta
β可以是终结符或者非终结符,注意
β
\beta
β不能为空,B后面要有东西),比如
A->aBc
A->aBd
A->BC
A->Bd
将First(
β
\beta
β)-{
ϵ
\epsilon
ϵ}(即去掉
ϵ
\epsilon
ϵ)加入到Follow(B)中
(3) 形如A->
α
\alpha
αB(
α
\alpha
α可以是终结符或非终结符或者直接为空)或者A->
α
\alpha
αB
β
\beta
β是一个产生式且
β
⇒
ϵ
\beta \Rightarrow \epsilon
β⇒ϵ
比如
A->B
A->cB
A->dBC
C->
ϵ
\epsilon
ϵ
将Follow(A)加入到Follow(B)中
综合例子
一般我们先求出所有First集合,因为Follow集的第二条规则求解会用到First集,Follow集的求解套用三条求解规则即可
例一
注意:[if]是一个终结符,同理[b],[other],[else],[then]
G(S):S->IETSP | O
I->if
E->b
O->other
L->else
T->then
P->LS|
ϵ
\epsilon
ϵ
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, ϵ \epsilon ϵ} | Follow§={else,#} |
First(T)={then} | Follow(T)={else,#} |
挑两个来进行分析
First( P):
P往后推导可得到P->elseS,P->
ϵ
\epsilon
ϵ,所以First( P)={else,
ϵ
\epsilon
ϵ}
Follow(O):
O出现在产生式S->O的右边,此时对应第三条规则,Follow(S)加入到Follow(O)中
所以Follow(O)={else,#}
Follow(S):
这里可能有些迷惑,因为P->LS中也包含S,这里如果用第三条规则就会有些麻烦,其实我们可以试着将P->LS代入S->IETSP中的到S->IETSLS,满足S->…S,将#加入Follow(S)集
此时应该已经明白First和Follow的求解方法,可以去找题目进行练习,查漏补缺,有写的不好的地方,还请指出 😄,视频地址。