编译原理FIRST集和FOLLOW集的求法

编译原理 专栏收录该内容
0 篇文章 0 订阅

编译原理FIRST集和FOLLOW集的求法

由于最近要期末考试了,所以要从头到尾复习(预习)一遍了。陈意云老师写的课本比较抽象,看不太懂,最后又找了中科大的编译原理课,可能听的时候太困了没有集中精力,又跑去看了以前曾经看过的哈工大的公开课,应该是看懂了,所以就厚颜无耻的来捋一捋,欢迎交流,批评指正。

废话不多说,直接看怎么计算的吧。
首先看FIRST集,文字描述如下:

1.FIRST(X):可以从X推导出的所有串首终结符构成的集合
如果X=>*ε,那么ε∈FIRST(X)

举个栗子

表达式FIRST集FOLLOW集
E -> TE’{}{}
E’-> +TE’|ε{}{}
T-> FT’{}{}
T’->*FT’|ε{}{}
F-> (E)|id{}{}

我是这样做的,首先看有终结符的表达式F-> (E)|id可以得到FIRST(F)={(, id};
再看有终结符的表达式T’->FT’|ε,得到FIRST(T’)={*, ε}
再看E’-> +TE’|ε,得到FIRST(E’)={+ , ε},所得得到以下结果:

表达式FIRST集FOLLOW集
E -> TE’{}{}
E’-> +TE’|εFIRST(E’)={+ , ε}{}
T-> FT’{}{}
T’->*FT’|εFIRST(T’)={*, ε}{}
F-> (E)|idFIRST(F)={(, id}{}

然后再从头看每个表达式可以得到FIRST(E)=FIRST(T),所以去求FIRST(T);
所以来看表达式T-> FT’,得到FIRST(T)=FIRST(F),又因为F无法推导出ε,所以FIRST(T)=FIRST(F);
同理可得FIRST(E)=FIRST(T)=FIRST(F)
所以表就更新为以下结果:

表达式FIRST集FOLLOW集
E -> TE’FIRST(E)={(, id}{}
E’-> +TE’|εFIRST(E’)={+ , ε}{}
T-> FT’FIRST(T)={(, id}{}
T’->*FT’|εFIRST(T’)={*, ε}{}
F-> (E)|idFIRST(F)={(, id}{}

这时候,我们FIRST集就已经求完了,接下来看FOLLOW集:
同样先来文字描述:

FOLLOW(A):可能在某个句型中紧跟在A后边的终结符a的集合
FOLLOW(A)={a| S=>*αAaβ, a∈VT, α,β∈(VT∪VN)*
如果A是某个句型的最右符号,则将结束符“$”添加到FOLLOW(A)中。

还是上面的栗子:

表达式FIRST集FOLLOW集
E -> TE’FIRST(E)={(, id}{}
E’-> +TE’|εFIRST(E’)={+ , ε}{}
T-> FT’FIRST(T)={(, id}{}
T’->*FT’|εFIRST(T’)={*, ε}{}
F-> (E)|idFIRST(F)={(, id}{}

我是首先找处在句子最右边的非终结符有哪些,由上面的表达式可以看出,分别有E’、T’所以首先把"$"填进去:

表达式FIRST集FOLLOW集
E -> TE’FIRST(E)={(, id}{}
E’-> +TE’|εFIRST(E’)={+ , ε}FOLLOW(E’)={$}
T-> FT’FIRST(T)={(, id}{}
T’->*FT’|εFIRST(T’)={*, ε}FOLLOW(T’)={$}
F-> (E)|idFIRST(F)={(, id}{}

然后从头开始看,首先看E,先直观的看E后面跟有哪些终结符;很容易可以看到有“)”;
又因为E为开始符号,所以FOLLOW(E)中有“$”符
再看T,T后面跟的是E’,所以FOLLW(T)要包含FIRST(E’);又由于E’可以推导出空串,所以T也可以是最右符号;
再看T’,T’首先是最右符号,所以FOLLOW(T)包含结束符;
最后看F,F后面跟的是T’,所以FOLLOW(F)包含FIRST(T’),又由于T’可以推导出空串,所以F也可以是最右符号
所以得到以下列表:

表达式FIRST集FOLLOW集
E -> TE’FIRST(E)={(, id}FOLLOW(E)={), $}
E’-> +TE’|εFIRST(E’)={+ , ε}FOLLOW(E’)={$}
T-> FT’FIRST(T)={(, id}FOLLOW(T)={+, $}
T’->*FT’|εFIRST(T’)={*, ε}FOLLOW(T’)={$}
F-> (E)|idFIRST(F)={(, id}FOLLOW(F)={*, $}

接下来再看有表达式推导得到的FOLLOW集是否发生改变:
又由于E->TE’,所以FOLLOW(E)=FOLLOW(E’);
又因为T->FT’,所以FOLLOW(T)=FOLLOW(T’)
所以有些FOLLOW集需要更新如下所示:

表达式FIRST集FOLLOW集
E -> TE’FIRST(E)={(, id}FOLLOW(E)={), $}
E’-> +TE’|εFIRST(E’)={+ , ε}FOLLOW(E’)={$, )}
T-> FT’FIRST(T)={(, id}FOLLOW(T)={+, $}
T’->*FT’|εFIRST(T’)={*, ε}FOLLOW(T’)={$, +}
F-> (E)|idFIRST(F)={(, id}FOLLOW(F)={*, $}

再看有些表达式能够推出空串,所以右边非终结符的FOLLW集合需包含左边非终结符的FOLLW集合,如E -> TE’,由于E’能够推导出空串,所以FOLLW(T)要包含FOLLW(E),根据这条规则,对FOLLW集做以下更新:

表达式FIRST集FOLLOW集
E -> TE’FIRST(E)={(, id}FOLLOW(E)={), $}
E’-> +TE’|εFIRST(E’)={+ , ε}FOLLOW(E’)={$, )}
T-> FT’FIRST(T)={(, id}FOLLOW(T)={+, $, )}
T’->*FT’|εFIRST(T’)={*, ε}FOLLOW(T’)={$, +, )}
F-> (E)|idFIRST(F)={(, id}FOLLOW(F)={*, $, +,)}

总结

FIRST集没什么问题,很好求,但是FOLLOW集合想对就比较麻烦,需要考虑的地方比较多,在做题目的时候千万不要遗漏!
欢迎批评指正,交流。

评论 1 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

爱吃草的Tom

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值