[现在的爬虫还真厉害,phpfans,你下一次爬的时候记得把日期给爬爬对,虽然写了我的名字我很感谢但是这日期:2009-12-26 我雷到了] 

[下次爬错日期的话礼拜五晚上的考试考不出的哦~]

 

[软院的同志们你们好~大家周五晚上的考试加油哦]

 

网上看了国内外N多个版本,都或多或少的有错误或者是省略,步骤有的也非常复杂。

我研究了很久,结合多个版本,得出了求LL(1)文法的First Set,Follow Set最正确最简单的方法

首先约定几点:

大写字母为非终结符

小写字母为终结符(即最终的字符)

如果一个位置上既可以放大写字母也可以放小写字母,表示为A1,A2....

一个非终结符为Nullable代表它能够推导出空(暂时用#表示)

 

First Set:较容易,网上的版本也基本都正确。

1,终结符的First Set是自己,如First(a)={a}

2,对于每个产生式,形如X->A1A2A3A4(注意A1,A2,A3,A4可以是非终结符,也可以是终结符)

2.1,将First(A1)加入到First(X),如果A1是Nullable的,继续,否则停止。

2.2,将First(A2)加入到First(X),如果A2是Nullable的,继续,否则停止。

以此类推,如果到了最后一个符号(例子中的A4)仍为Nullable,则将空字符#加入First(X),此时X已经成为Nullable

循环执行每一个产生式(对于每个产生式可能需要执行N多次),直到First集不再发生变化。

 

Follow Set:网上的版本五花八门,算出的结果各不相同,很多CSDN上用户上传的程序也都是错误。

1,Follow Set仅针对于非终结符,但是可以通过以下方法类似地推导出终结符的Follow Set,不过推出来也没用

2,首先将$加入到起始非终结符。

3,对于每个非终结符X,观察产生式右侧的表达式中X的右侧所有字符串s(例如E->TXaB,右侧字符串为aB,如果产生式右侧无X则忽略),s可以为空

3.1,如果s为空或者s是Nullable的(不仅仅是s的开头是Nullable,必须s的全部是Nullable),则将产生式左侧的非终结符E的Follow Set加入到X的Follow Set (Follow(E)=>Follow(X))

3.2,如果s不为空,则将First(s)加入到Follow(X)

4,循环执行每一个产生式(对于每个产生式可能需要执行N多次),直到Follow集不发生变化。

grammar
    E -> T X                               X -> + E | # 
    T -> ( E ) | int Y                   Y -> * T | #
Follow sets
 Follow( E ) = {), $}
 Follow( X ) = {$, ) }
 Follow( T ) = {+, ) , $}
 Follow( Y ) = {+, ) , $}

 

posted on 2010-10-22 00:35  Latifrons  阅读(11313)  评论(0编辑  收藏  举报