对产生式 T → FT',T 没有一步推导就能得到的终结符,所以要继续推导,再推导一步会得到:T=>FT'=>(E)T' 或 T=>FT'=>idT' 或 T=>FT'=>numT',由此我们可以看到,T 经过两步推导能够推导出的第一个终结符有:(、id、num,(由于 F 推不出 ε,也就是说 F 无法被穿透,因此关于从 T 经过推导推出的第一个终结符就都和 F 的终结符相同了),因此 FIRST(T) = FIRST(F) = { (, id, num };
求 FOLLOW 集合的过程要顺着产生式从上往下进行,也就是先求 FOLLOW(L),最后求 FOLLOW(F)。首先求第一个产生式 L → E;L|ε 左部的非终结符 L 的 FOLLOW 集合 FOLLOW(L)。
因为我们想要寻找的是在经过推导后跟在 L 后面的终结符,因此我们要首先扫一眼全部的产生式,看看 L 都在哪些产生式中出现过以获取线索。很不幸,只在第一个产生式中出现过……如果选择 E;L 进行推导将导致 L 的递归——也就是说若只用这个产生式进行推导,无论怎么推都永远推不出一个紧随 L (除了#之外)的终结符,最终还是要面对只有 L 的问题。而若选择 ε 展开 L 则会导致 L 的穿透,暴露出文法的结束符号 # ,因此 FOLLOW(L) = {#};
再来看第二个产生式 E → TE',这一步我们求该产生式左部的非终结符 E 的 FOLLOW 集合 FOLLOW(E)。
因为我们想要寻找的是在经过推导后跟在 E 后面的终结符,因此我们先来整体看一下所有的产生式。可以发现非终结符 E 在第一行的产生式 L → E;L|ε 和最后一行的产生式 F → (E)|id|num 中都有出现。产生式 L → E;L|ε 说明,从开始符号 L 开始,经过一步推导得到 E;L ,即 L=*>...E;...因此我们要将 ; 加入到 FOLLOW(E) 中 。此外,我们还可以发现在最后一个产生式 F → (E)|id|num 中,E 后面接上了终结符 ),这说明,从开始符号 L 开始,经过多步推导,可以出现某一刻将 F 用 (E) 展开的情况——即:L=*>...(E)...,因此我们要将 ) 加入到FOLLOW(E) 中。除了这两个产生式之外,再也没有其他右部包含 E 的产生式,也就是说我们找完了 E 后面紧跟终结符的所有情况,故得到:FOLLOW(E) = { ;, ) };
再看第三个产生式 E' → +TE'|-TE'|ε ,这一步求 FOLLOW(E')。
经过观察,我们发现除了这个产生式本身,只有第二行的 E → TE' 中出现了 E' 。通过观察这两个产生式,我们可以发现:下推栈中的 E' 只有一个来源,就是被使用 E → TE' 展开 E 而来。那也就是说,之前在下推栈中【位于 E 下面的非终结符】将被 E‘ “继承“
因此, FOLLOW(E') = FOLLOW(E) = { ;, ) };
下面来看第四个产生式 T → FT' ,这一步求 FOLLOW(T)。
我们发现 T 还出现在第二个产生式 E → TE' 中,因此要将 FIRST(E') 加入到 FOLLOW(T) 中。而又因为 E' 可穿透,因此也要考虑 E' 穿透的情况,故要将 FOLLOW(E) 也加入到 FOLLOW(T) 中。另外,因为 FOLLOW 集合中不能包含 ε,故 ε 不能被加入到 FOLLOW(T) 中。最后,FOLLOW(T) = { +, -, ;, ) }