编译原理First集 Follow集 Select集

编译原理First集 Follow集 Select集

First集

First(N)=从非终结符N开始推导得出的句子开头的所有可能终结符集合。
计算规则:

基本情况:
		x->a		First(X)∪={a}
归纳情况:
		x->Y1 Y2 ……Yn
		First(X)∪=First(Y1)
		if Y1∈NULLABLE First(X)∪=First(Y2)
		if Y1 Y2∈NULLABLE First(X)∪=First(Y3)
		……

Follow集

Follow(N)=所有紧跟N之后的终结符或者#所组成的集合。
(在包含N的句子中,N后面可以跟哪些终结符)
计算规则:(必须消除左递归和提取公共左因子)

1.若S是文法的开始符号,则将#放到Follow(S)中。(只有开始符号才进行这一步骤)
2.如果存在一个产生式A->αBβ,那么first(β)中除了ε之外的所有符号都在Follow(B)中。(β不为空)
注释:Follow(B)是求跟在B后面的终结符或者#所组成的集合,因此对于跟在B后面的β,它的first集合就是Follow(B)的子集。
3.如果存在一个产生式A->αB,或者存在产生式A->αBβ且first(β)包含ε,那么follow(A)中的所有符号都在Follow(B)中。
注释:A->αBβ并且β多步推出ε,那么可以用αB替换A,B后面紧跟的字符就是A后面紧跟的字符。
**α可以为空;Follw集中没有ε。**
进行迭代直到follow集合不会再变化为止

Select集(First_S集)

计算规则:

1.对于产生式A->α,如果α不能推出ε,则select(A->α)=first(α)。
2.对于产生式A->α,如果α能推出ε,则select(A->α)={first(α)-{ε}}∪follow(A)

LL(1)文法

所有具有相同左部的SELECT集合的交集都是空集,才是LL(1)文法。

例题

(0) E -> TE'
(1) E'-> +TE' | ε
(2) T -> FT'
(3) T'-> *FT' | ε
(4) F -> (E) | i

因为求FIRST集合如果有终结符号会比较好处理,所以我们先从有终结符的开始求解。

first(F)=first((E))first(i)={(,i}
first(T')=first(*FT')first(ε)={*,ε}
first(T)=first(FT')=first(F)={(,i}
first(E')=first(+ET')first(ε)={+,ε}
first(E)=first(TE')=first(T)={(,i}

接下来求解follow集,follow集会比first集更复杂一点,要注意不要遗漏。

首先将结束标志#加入到FOLLOW(E)FOLOOW(E)={#}
接下来按照规则进行迭代
第一次迭代:
E -> TE'
第一种情况 follow(T)=fisrt(E')={+}
第二种情况 follow(E')=follw(E)={#}
E'-> +TE' | ε
第一种情况 follow(T)=fisrt(E')={+}
第二种情况 follow(T)=follw(E')={+,#}
T -> FT'
第一种情况 follow(F)=fisrt(T')={*}
第二种情况 follow(T')=follw(T)={+,#}
T'-> *FT' | ε
第一种情况 follow(F)=fisrt(T')={*}
第二种情况 follow(F)=follw(T')={+,*,#}
F -> (E) | i
第一种情况 follow(E)=fisrt())={#,)}
第二次迭代:
follow(E)={#,)}
follow(E')={#,)}
follow(T)={+,),#}
follow(T')={+,),#}
follow(F)={+,*,),#}
第三次迭代:
follow(E)={#,)}
follow(E')={#,)}
follow(T)={+,),#}
follow(T')={+,),#}
follow(F)={+,*,),#}
已经不会改变了,所以这就是最终的follow集合

Follow比较容易出错,出错的点主要在迭代过程的第二种情况的:A -> αBβ 且FIRST(β)包含ε,我们容易忽略这种情况。

最后求解Select集。

select(E -> TE')=first(TE')=first(T)={(,i}
select(E'-> +TE')=first(+)={+}
select(E'-> ε)=follw(E')={#,)}
select(T -> FT')=first(F)={(,i}
select(T'-> *FT')=first(*)={*}
select(T'-> ε)=follow(T')={+,),#}
select(F -> (E))=first(()={(}
select(F -> i)=first(i)={i}

LL(1)分析表
列为非终结符,行为终结符,填入即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值