[编译原理] 期末复习,求FIRST集和FOLLOW集。简单易懂,例题讲解。

1、终结符和非终结符

终结符:ε、a、b、c、d、+、-、*、/、,等非大写字母

非终结符:A、B、C、D、S、… 大写字母。

2、求first集

核心理念:first(A) A能推出的第一个是什么。

结果的取值范围:终结符,即非大写字母。答案要写成一个集合。

2.1 例1

G[A]:

A---->aB|ε

A---->c

解析:因为A能推出的第一个字符是a、ε、c,且都是非大写字母(都是终结符),所以可以直接得到

first(A)={a,ε,c}

竖线 | 表示或

2.2 例2

G[A]:

A-----> Bc | ε

B ------>b | ε

解析:A能推出的第一个字符是B,B是大写字母,即是非终结符,我们要利用产生式(规则)对B进行替换

得到 A---->bc | ε | εc, 由于 εc 可以化简成 c,所以得到 A---->bc | ε | c。 可以看出,A能推出的第一个字符是b、 ε 、c,且都是非大写字母,所以,first(A)={b,ε,c}

因为B能推出的第一个字符是 b、ε,所以first(B) = {b,ε}

掌握:替换

2.3 例3

G[S] :

S ----> ABc

A------>a | ε

B -------> b | ε

答案
first(S) {a,b,c}
frst(A) {a,ε}
first(B) {b,ε}

解析first(S):

S-----> ABc,将A和B都进行替换,得到 S------>abc | aεc | εbc | εεc ,即 S------>abc | ac | bc | c

替换过程:就是A取a时,B可以取b或 ε; A取ε时,B可以取b或ε。就是小学学的排列组合

所以,first(S)={a,b,c}

first(A) 和 first(B)很简单,不赘述。

2.4 例4

G[A] :

A------> BC

B------>b | ε

C ------->c|ε

答案
first(A) {b,c,ε}
first(B) {b,ε}
first© {c,ε}

解析first(A):A----->BC,对B和C都进行替换, A---->bc| bε | εc | εε ,即 A------> bc | bε | c | ε

注:εc 为什么能变成 c,因为 ε后面有个终结符c,而ε代表空串,所以εc可以变成c。

所以,first(A) = {b,c,ε}

2.5 例5

G[E]:

E-------> TE

E------> +TE | ε

T--------> FT

T----------> *FT | ε

F ------------>(E) | i

答案
first(E) { ( , i }
first(E) { + , ε }
first(T) { ( , i }
first(T) { *, ε }
first(F) { (, i }

解析:做完前面的例题,你应该会求first了,就是看能推出的第一个是啥,如果是大写字母(非终结符),则要对其进行替换

  • E== > T ==> F ==> ( | i

​ 所以,first(E)= { (, i}

  • E ===> + | ε

​ 所以,first(E)={ + ,ε }

  • T ==> F ==> ( | i

    所以,first(T) = { ( , i}

  • T ==> * | ε

    所以,first(T)= { ( ,i }

  • F ==> ( | i

    所以,first(F) = { ( , i }

3、求follow集

[编译原理] 期末复习,求FIRST集和FOLLOW集。简单易懂,例题讲解。_第1张图片

空就是 ε 。 式子就是产生式。

规则②的第二种情况其实和规则①的情况是一样的,因为,当东西推出ε 时,就代表着A后面没有东西,所以,将follow(左)加入

规则②的情况1,如果A后面的东西是终结符(即非大写字母)可以直接加入。

规则②的情况1,如果first(东西)的集合里有 ε ,则

重点:如果求开始符的follow集,必须要将 # 加入。(记住就行,想了解原因的可以去看课本。)

一定要想求出first集,再去求follow集,因为求follow集的时候要用到first集

3.1 例1

G[S] :

S ----> ABc ①

A------>a | ε ②

B -------> b | ε ③

为了方便说明,我给每一个产生式标了序号。

答案
first(S) {a,b,c}
frst(A) {a,ε}
first(B) {b,ε}
答案
follow(S) { #}
follow(A) {b,c}
follow(B) {c}

解析:

  • follow(S): 因为S是开始符,所以,将 # 加入。然后再看S在哪个产生式的右边出现,发现这3个产生式的右边都没有S出现。所以,follow(S) = { #}

  • follow(A): 发现A在产生式①的右边出现,A后面有东西,即A后面是B,我们由③可以知道,B可以推出b(非空),也可以推出空 ε ,所以,

    B推不出空时,将first(B)除去ε后加入.

    B推出空时,由于后面有个c,所以,此时相当于变成 S ---->Ac,此时 A后面有东西,所以,将终结符c加入

    综上follow(A) = { first(B)除去ε , c} = {b,c }

    这题有坑,有些人可能会写成 {b,#},做错的原因就是: 当B推出空时,你没看到后面有个c,你直接把follow(S) 加入了,所以就错写成了 {b,#}

  • follow(B):发现B在产生式①的右边出现,B后面有个终结符c,所以,将c加入。所以,follow(B) = {c}

3.2 例2

G[E]:

E-------> TE

E------> +TE | ε

T--------> FT

T----------> *FT | ε

F ------------>(E) | i

先求出first集合

答案
first(E) { ( , i }
first(E) { + , ε }
first(T) { ( , i }
first(T) { *, ε }
first(F) { (, i }

再求follow集合

答案
follow(E) {#,)}
follow(E) {#,)}
follow(T) {+,#,)}
follow(T) {+,),#}
follow(F) {*,+,),#}

:因为是集合,所以,里面字符的是无序的。字符是不重复的。和java里的Set是一样的。

解析:

G[E]:

E-------> TE

E------> +TE | ε

T--------> FT

T----------> *F T | ε

F ------------>(E) | i

  • follow(E):E只在 F ------------>(E) | i 这个式子的右边出现。由于E的右边是),是一个终结符,所以,直接将)加入。又因为E是开始符,所以将#加入。所以,follow(E)={#, ) }

  • follow(E): E 在下面两个式子的右边都出现过,所以,两个式子都要看一下。

    E-------> TE

    E------> +TE | ε

    对于 E-------> TE ,由于 E 后面没东西,所以,将follow(E)加入,

    对于 E------> +TE | ε,由于E 后面没东西,所以,将follow(E) 加入。因为咱求得是follow('),所以此时就是自己加入自己,对于集合来说,重复的元素是无意义的。

​ 综上,follow(E)={#,)}

  • follow(T): T只在下面两个式子的右边出现。

    E-------> TE

    E------> +TE | ε

对于E-------> TE: T的后面有东西,是E, 但是,我们要判断一下E能否推出 ε。由式子 E------> +TE | ε可以知道,E可以推出非空 也可以推出空。E 推出非空时,将first(E) 这个集合去掉空后加入;E 推出空时,将follow(E)加入.

对于, E------> +TE | ε ,T的后面有东西,是E,结果和上面一样,重复的元素加入集合中是没意义的。

综上,follow(T)={+,#,)}

  • follow(T):T只在下面两个式子的右边出现。

    T--------> FT

    T----------> *F T | ε

    与求follow(T)一样,只要follow(T)会求,这个也必会,不赘述。

    follow(T) = {+,),#}

  • follow(F):F只在下面这个式子的右边出现。

​ T--------> FT

​ F的右边有东西,是T, 由 T----------> *F T | ε我们可以知道,T能推出空和非空。

T 推出非空时,将first(T)加入

T 推出空时,将follow(左)加入,即将follow(T)加入。

与求follow(T)一样,只要follow(T)会求,这个也必会,不赘述。

follow(T) = {+,),#}

  • follow(F):F只在下面这个式子的右边出现。

​ T--------> FT

​ F的右边有东西,是T, 由 T----------> *F T | ε我们可以知道,T能推出空和非空。

T 推出非空时,将first(T)加入

T 推出空时,将follow(左)加入,即将follow(T)加入。

你可能感兴趣的:(编译原理)