我們知道,詞法分析的主要目的是分析輸入的字符流中的所有字符串是否合法,而接下來語法分析的目的是分析字符流的書寫規則是否符合規定的格式。為了對所有表達式進行一般化的處理,在編譯原理的理論上提出了文法這個概念,該文法和語言中的文法有很大區別。現在我們重點來討論LL(1)文法。
在LL(1)文法中引入了兩個集合,分別是first集合和follow集合,那為啥要引入這兩個集合了,難道引入這概念的人吃多了沒事干么(開玩笑),其實不然,為了理解為何引入這個概念,我們先來看下如下文法:

非終結符S為開始符號。
同時給出acb輸入串,分析該串是否符合該文法的描述。
為了驗證輸入串是否符合該文法的描述,直觀的方式就是直接代入文法中,一條一條的進行匹配。如下所示:

通過一步一步的不斷匹配,可以看到該串確實是符合該文法的描述。
那我們現在開始分析我們的步驟,首先,我們先拿出給定的出入串的第一個字符,該字符為a,發現產生式1能夠匹配我們的輸入,此時我們得到推導式aB,依此類推,我們能夠匹配我們的字符串。可以看出,我們每次匹配所得到的推導其實是根據文法中右邊的第一個終結符是否和輸入相等來判斷的,因此,我們就可以將這些字符放到一起,這些字符能夠引導我們選擇文法中的哪個產生式,我們將這些字符的所有集合稱之為First集合,很顯然上面文法中的first集合為:

那什么是follow集合呢?不知道讀者是否留意上面的推導步驟,步驟step2被我用藍色圈標出,這里有個不同的地方,就是acBS-->acS這步,這里加入我們按找之前的方式進行匹配,發現B的first集合中沒有b,這樣就導致我們的推導失敗,很顯然該串是符合該文法的,因此是我們的推導不對,但是我們可以從產生式4得出非終結符B可以是空,這樣我們可以將非終結符B去掉而變為了acS,從上面來看貌似好像不需要其他東西,但是對於計算機而言,它並不知道B可以推導空。所以我們這里需要進行特殊處理,對於每個非終結符而言,當遇到first中沒有匹配的字符時,我們還不能判斷此串就是不符合文法,有點操之過急,還需要進一步判斷。可以看到進一步判斷就是當非終結符能夠推導出空時,此非終結符可以省略,但是我們不能說把他刪除了,我們必須找到一個字符與之匹配,很顯然對於上面的文法而言,該字符就是b,這個b是由S右邊決定的,也就是當非終結符的first集合沒有與之匹配的字符時,我們需要找該終結符緊跟后面的一個非終結符或終結符,很顯然,如果是終結符,那最好了,可以直接確定此符號就是要找的那個與之匹配的字符,如果是非終結符,則對其終結符進行推導,必然能夠找到一個終結符。我們將上面要找的終結符的集合稱之為Follow集,這樣我們判斷輸入的字符時先判斷是否在first集中,如果是則將此產生式的替代該非終結符,如果不是,則在follow集中進行查找,看是否由匹配的字符,如果有,則直接將該非終結符替代,如果沒有,直接輸出該輸入串不符合定義的文法。
上面的文法中follow集如下:

上面的$表示輸入結束,其實就是輸入指針指到了輸入串的尾部,follow(B)中有$是因為B可以推導出空串,同時還是產生式的最后一個非終結符,這兩個條件缺一不可。而follow(S)中也有$是因為S為文法的推導開始,也就是當開始輸入的指向字符串的指針直接指到了輸入串的尾部,其實可以認為沒有字符串輸入,此時是符合文法的,所以將產生式開始的非終結符都要加上$(即輸入結束符)。
注意:上面為何引入follow集的原因就是因為有些非終結符可以推導出ε,如果沒有ε,那該文法分析完全可以省略follow集,只要認真讀過上面的分析過程,都能理解這一點。
知道了上面的步驟,我們很容易來實現上面的分析過程,實現方法很多,但基本思想都是一致的,下面我們使用二維數組的方式實現該過程,
后續更新(時間太緊了,抱歉)
