FIRST集

FIRST集

1.什么是FIRST集?

一个符号的FIRST集表示一个符号或句型可以推导出的句子的首符号的集合。

举个例子:A→aa|bb|cc。a,b,c是终结符,则FIRST(A)={a,b,c}

通过上面的定义解释一下,符号A可以推导出三个句子{aa,bb,cc},那么,这三个句子的首符号集合FIRST(A)={a,b,c}。

2.FIRST集求法

再给出最终结论之前,首先看以下的几种情况

求一个终结符号的FIRST集

终结符号经过推导(0步推导)后,推导出自己本身,所以如果a是一个终结符号,则FIRST(a)={a}

可以推导出空串的非终结符号的FIRST集

如果一个非终结符号可以推导出空串,则有以下两种情况:

在这里插入图片描述

在这里插入图片描述

对于经过若干步可以推导出空串的非终结符号,有以下结论

在这里插入图片描述

不能推导出空串的非终结符号的FIRST集

如果一个非终结符号不能推导出空串,它可以被形式的描述为:

在这里插入图片描述

对于上面的情况,首先FIRST(Y1)-{ε}(这里减去{ε}的原因下面说)是FIRST(X)的一个子集,因为经过推导之后,用产生式的右部(多个Y)替换了X,则第一个字符就是Y1,所以,FIRST(Y1)-{ε}是FIRST(X)的一个子集(或者说,将FIRST(Y1)-{ε}加入FIRST(X))。

减去{ε}的原因:如果Y1可以推导出ε,则ε属于FIRST(Y1),但是仅仅Y1可以推导出空串,还不足以说明X可以推导出空串,只有X可以推导出ε,才可以将ε加入FIRST集(上面讨论的情况)。Y2可能不能推导出空串,所以X就不能推导出空串。

举个例子:

在这里插入图片描述

如上图的例子,我们可以看到,我们上面讨论的Y1就是A,所以,FIRST(A)-{ε}是FIRST(X)的一个子集(或者说将FIRST(A)-{ε}加入FIRST(X)),因为X只有一条产生式,这个产生式有这一条“线索”,因此分析到这里,就分析结束了,也就是说FIRST(X)=FIRST(A)-{ε}。

所以,问题变成了求FIRST(A),这里,A有三个产生式,分别推导出终结符号a,b,c。也就是说,对于每一个产生式,Y1分别为a,b,c。FIRST(a)-{ε},FIRST(b)-{ε},FIRST( c)-{ε}都是FIRST(A)的子集,也就是说,FIRST(A)=FIRST(a)-{ε}+FIRST(b)-{ε}+FIRST( c)-{ε}={a,b,c}(终结符号的FIRST集就是它自己构成的集合,我们上面讨论过的)

继续分析,上面的情况,我们忽略了Y1可能推导出空串的情况。也就是说,如果将文法做一下修改,变成如下分文法:

在这里插入图片描述

想一下,如果X在推导过程中,A使用了空串产生式,那么,B就变成了第一个符号,因此FIRST(B)-{ε}也应该是FIRST(X)的子集。也就是说,如果Y1有空串产生式,则Y2的FIRST集-{ε}是FIRST(X)的子集。

继续进行归纳,如果Y1和Y2都有空串产生式,再将文法修改一下:

在这里插入图片描述

如果在X推导过程中,A和B都使用空串产生式,则C就变成了第一个符号,因此FIRST( C)-{ε}也应该是FIRST(X)的子集。也就是说,如果Y1,Y2有空串产生式,则Y3的FIRST集-{ε}是FIRST(X)的子集。

通过归纳,我们可以得到结论,设产生式X→Y1Y2Y3…Yk。则,如果Y1Y2Y3…Yi-1可以推导出空串,也就是说从Y1到Yi,每一个符号都能推导出空串,则Yi的FIRST集-{ε}是FIRST(X)的子集。Y1,Y2…Yi-1这些符号不使用空串产生式时,它们中的每一个都可能成为第一个符号,它们的FIRST集-{ε}都是FIRST(X)的子集。也就是说,对于这种情况,FIRST(X)=FIRST(Y1)-{ε}+FIRST(Y2)-{ε}+…+FIRST(Yi)-{ε}

当然,如果Y1Y2Y3…Yk可以推导出空串,也就是X推导出了空串,这就变成了我们上面讨论的情况。

3.总结

  1. 如果X是终结符号,则FIRST(X)={X}。
  2. 如果X是非终结符号,且X可以推导出ε,则将ε加入FIRST(X)。
  3. X→Y1Y2Y3…Yk,若ε∈FIRST(Y1Y2Y3…Yi-1)(i<k),则将(FIRST(Y1)-{ε}+FIRST(Y2)-{ε}+…+FIRST(Yi)-{ε})加入FIRST(X),否则,将(FIRST(Y1)-{ε})加入FIRST(X)。如果Y1Y2Y3…Yk可以推导出空串,则就变成了情况2。
  4. 补充一条规则,X→Y1Y2Y3…Yk,FIRST(X)⊇FIRST(Y1Y2Y3…Yk)

总结方法

如果要求FIRST(X),首先找到X在左部的产生式,然后对这些产生式应用上面的规则,每应用一次规则,会计算出一个FIRST集的子集,将这些子集加入FIRST(X)。

需要应用两次规则的产生式:对于X→Y1Y2Y3…Yk,如果Y1Y2Y3…Yk可以推导出ε,则就说明X可以推导出ε,因此,就可以利用规则2和规则3,也就是两条规则

举个例子:

在这里插入图片描述

求FIRST(E),首先,找到E在左部的产生式

在这里插入图片描述

可以看到,产生式的形式属于,X→Y1Y2Y3…Yk,首先,将FIRST(T)-{ε}加入FIRST(X)。(应用第三条规则,因为T不能推导出空串,所以不需要讨论E’

问题又变成了求FIRST(T),找到T在左部的产生式,

在这里插入图片描述

同理,将FIRST(T)=FIRST(F)-{ε}(同样,因为F不能推导出ε,而且这里只有一条产生式,且只用了一次规则,所以,可以确定FIRST(T)=FIRST(F)-{ε})

因此,又要先求FIRST(F)
找到F在产生式左部的产生式
在这里插入图片描述
可以看到,F在左部的产生式有两个,因此,FIRST(F)=FIRST(()-{ε}+FIRST(i)-{ε}={(, i}

FIRST(T) = FIRST(F)-{ε} = {(, i}
FIRST(E) = FIRST(E)-{ε} = {(, i}

经过上面的分析,我们得到FIRST(E)=FIRST(T)=FIRST(F)={(, i}

接下来分析稍复杂的FIRST(E’),还是那样,需要找到E’在产生式左部的产生式

有两个产生式,一个是空串产生式,应用规则3;另一个应用规则3,再将这两个结果求并集即可,FIRST(E’)={ε}+(FIRST(+)-{ε})={ε, +}

同理,FIRST(T’)={ε, *}

FIRST(E’T’)=? 句型E’T’是符合应用两次规则的句型。
第一次应用规则:应用规则3,(FIRST(E’)-{ε}+FIRST(T’)-{ε})是FIRST(E’T’)的子集。

第二次应用规则:应用规则2,又因为E’T’可以推导出空串,所以ε∈FIRST(E’T’)。

将两条“线索”得到的结果求并集,FIRST(E’T’)=FIRST(E’)-{ε}+FIRST(T’)-{ε}+{ε}={+}+{*}+{ε}={+,*,ε}

  • 28
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值