FIRST集、FOLLOW集 和 SELECT集

来源:互联网 发布:org.apache.log4j.mdc 编辑:程序博客网 时间:2024/05/01 02:38

FIRST集

FIRST(A)为A的开始符或者首符号集。

定义:

设G=(VT,VN,S,P)是上下文无关文法 ,FIRST(α)={a|α能推导出aβ,a∈VT,α,β∈V*}   
特别的,若α能推导出ε,则规定ε∈FIRST(α).

根据定义求解FIRST集(对每一文法符号X∈V 计算FIRST(X)):

  1. 若X∈VT,则FIRST(X)={X}。(简单讲,终结符的FIRST集就是它本身)
  2. 若X∈VN,且有产生式X→a…,a∈VT, 则 a∈FIRST(X)X→ε,则ε∈FIRST(X)。 (简单讲,若是非终结符X,能推导出以终结符a开头的串,那么这个终结符a属于FIRST(X),若X能够推导出空符号串ε,那么空符号串ε也属于X的FIRST集)
  3. X→Y…是一个产生式且Y ∈VN 则把FIRST(Y)中的所有非空符号串ε元素都加入到FIRST(X)中。(这个可以理解吧)
  4. 若X∈VN;Y1,Y2,…,Yi∈VN,且有产生式X→Y1 Y2… Yn;当Y1 Y2… Yn-1都能推导出ε时,则FIRST(Y1)、FIRST(Y2)、…、FIRST(Yn-1)的所有非空元素和FIRST(Yn) 包含在FIRST(X)中。即: FIRST(X)=(FIRST(Y1)-{ε} )∪(FIRST(Y2)-{ε} )∪…∪(FIRST(Yn-1)-{ε})∪{FIRST(Yn)}
  5. 当(4)中所有Yi 能够推导出ε,(i=1,2,…n),则 FIRST(X)=(FIRST(Y1)-{ε})∪(FIRST(Y2)- {ε}∪…∪(FIRST(Yn) -{ε})∪{ε}

反复使用上述②~⑤步直到每个符号的FIRST集合不再增大为止。

求解示例

文法G [S]为:
- S→AB
- S→bC
- A→ε
- A→b
- B→ε
- B→aD
- C→AD
- C→b
- D→aS
- D→c

求每个非终结符的First集?

解:对于非终结符S,S的开始符有终结符b和非终结符A,根据上面定义(2)把b加入FIRST(S),由上面的定义(3)把FIRST(A)中的所有非空符号串ε元素都加入到FIRST(S)中,而且因为S→AB符合上面的定义(4)和(5),所以FIRST(S)=(FIRST(A)-{ε})∪(FIRST(B) -{ε})∪{ε}那么先求FIRST(A)和FIRST(B),A的开始符有终结符b和空符号串ε,由定义(1)和定义(2)全部加入FIRST(A),也就是FIRST(A)={ε,b},同理,FIRST(B)={a,ε},这样FIRST(S)也就求出来了,FIRST(S)={b,a,ε},其实回过头来看之所以要反复调用定义(2)~(5),是因为开始符中A可能为空字符串ε,所以要考虑A后面的情况。

再求,FIRST(C),由定义(1),把b加入FIRST(C),再由定义(4),FIRST(C)=(FIRST(A)-{ε} )∪{FIRST(D)},先求FIRST(D),易知,FIRST(D)={a,c},所以FIRST(C)={b,a,c}

小结

  1. 对于终结符而言,FIRST集中的元素只有它本身

  2. 对于非终结符而言,如果开始符是终结符或者空符号串ε,则加入其FIRST集中;若开始符是非终结符,则要加入它的不含ε的FIRST集,并考虑其为ε时的情况。

FOLLOW集

FOLLOW(A)={a|S能推导出μAβ,且a∈VT,a∈FIRST(β),μ∈VT* ,β∈V+},若S能推导出μAβ,且β能推导出ε, 则#∈FOLLOW(A)。 也可定义为:FOLLOW(A)={a|S能推导出…Aa…,a ∈VT} ,若有S能推导出…A,则规定#∈FOLLOW(A) ,这里我们用‘#’作为输入串的结束符,或称为句子括号。

如:#输入串#。

FOLLOW(A)为非终结符A的后跟符号集合。

定义

设G=(VT,VN,S,P)是上下文无关文法,A∈VN,S是开始符号  
需要注意的是,FOLLOW(A)集是针对非终结符A的,集合中的元素是终结符,是A的全部后跟符号的集合,当A是文法G的开始符(识别符)时,把‘#也加入其中’

根据定义求解FOLLOW集(对每一文法符号S∈VN计算FOLLOW(S))

  1. 设S为文法中开始符号,把{#}加入FOLLOW(S)中(这里“#” 为句子括号)。

  2. 若A→αBβ是一个产生式,则把FIRST(β)的非空元素加入FOLLOW(B)中。如果β能够推导出ε则把FOLLOW(A)也加入FOLLOW(B)中。

  3. 反复使用(b)直到每个非终结符的FOLLOW集不再增大为止。

求解示例

文法G [E]为:
- E → TE’
- E’ → +TE’ | ε
- T → FT’
- T’ → *FT’ | ε
- F → (E) | i

求每个非终结符的FOLLOW集?

解:先给出它们的FIRST集:(求解方法见上面FIRST集的求解)

FIRST(F)={ (,i }FIRST(T’)={ *,ε }FIRST(T) ={ (,i }FIRST(E’)={ +,ε }FIRST(E)={ (,i }

FOLLOW集的求解:

因为E是文法的识别符所以把#加入FOLLOW(E),又由规则F → (E) | i得E的后跟符号),所以,FOLLOW(E)={ #,) };

FOLLOW(E’)={ #,) } ∵E → TE’ ∴FOLLOW(E)加入 FOLLOW(E’)

FOLLOW(T)={+,),#} ∵E’→ +TE’ ∴FIRST(E’)-{ε}加入FOLLOW(T); 又E’→ε,∴ FOLLOW(E’)加入FOLLOW(T)

FOLLOW(T’)= FOLLOW(T)= {+,),#} ∵T → FT’ ∴ FOLLOW(T)加入FOLLOW(T’)

FOLLOW(F)={*,+,),#} ∵T → FT’ ∴ FOLLOW(F)=FIRST(T’)-{ε} ; 又T’→ε ∴ FOLLOW(T)加入FOLLOW(F)

小结

FOLLOW集对于非终结符而言,是非终结符的全部后跟符号的集合,如果后跟终结符则加入,如果后跟非终结符,则加入该非终结符的不含空符号串的FIRST集,特别地,文法的识别符的FOLLOW集需要额外的加入‘#’。

SELECT集

定义

给定上下文无关文法的产生式A→α, A∈VN,α∈V*, 若α不能推导出ε,则SELECT(A→α)=FIRST(α)   

如果α能推导出ε则:SELECT(A→α)=(FIRST(α) –{ε})∪FOLLOW(A)

需要注意的是,SELECT集是针对产生式而言的。

LL(1)文法

  1. 一个上下文无关文法是LL(1)文法的充分必要条件是:对每个非终结符A的两个不同产生式,A→α, A→β,满足SELECT(A→α)∩SELECT(A→β)=空集 其中α,β不同时能推导出ε。
  2. LL(1)文法的含义:
    • 第一个L 从左到右扫描输入串
    • 第二个L 生成的是最左推导
    • 1 向右看一个输入符号便可决定选择哪个产生式。
  3. LL(1)文法的判别:当我们需选用自顶向下分析技术时,首先必须判别所给文法是否是LL(1)文法。因而我们对任给文法需计算FIRST、FOLLOW、SELECT集合,进而判别文法是否为LL(1)文法。

求解示例

文法G [S]为:
- S→AB
- S→bC
- A→ε
- A→b
- B→ε
- B→aD
- C→AD
- C→b
- D→aS
- D→c

求每个产生式的SELECT集,并判断文法G是否为LL(1)文法?

解:

SELECT(S→AB)=(FIRST(AB)-{ε})∪FOLLOW(S)={b,a,#}   SELECT(S→bC)=FIRST(bC)={b}   SELECT(A→ε)=(FIRST(ε) -{ε})∪FOLLOW(A)={a,c,#}   SELECT(A→b)=FIRST(b)={b}   SELECT(B→ε)=(FIRST(ε) -{ε})∪FOLLOW(B)={#}   SELECT(B→aD)=FIRST(aD)={a}   SELECT(C→AD)=FIRST(AD)={a,b,c}   SELECT(C→b)=FIRST(b)={b}   SELECT(D→aS)=FIRST(aS)={a}   SELECT(D→c)=FIRST(c)={c}

由以上计算结果可得相同左部产生式的SELECT交集为:   

SELECT(S→AB)∩SELECT(S→bC)={b,a,#}{b}={b}≠фSELECT(A→ε)∩SELECT(A→b)={a,c,#}{b}=фSELECT(B→ε)∩SELECT(B→aD)={#}{a}=фSELECT(C→AD)∩SELECT(C→b)={b,a,c}{b}{b}≠фSELECT(D→aS)∩SELECT(D→c)={a}{c}=ф

由LL(1)文法定义知该文法不是LL(1)文法,因为具有相同左部其产生式的SELECT集的交集不为空。

小结

Select集的作用是将first集和follow集进行合并,如果两个文法的左端都是A,若他们的select集交集为空,表明他们是两个无关的,不会产生不确定性的文法,反之,则表明文法不是LL(1)文法。

原文链接

FIRST集、FOLLOW集 和 SELECT集

原创粉丝点击