上一章中,我說 Parser 的工做就是依據文法定義,找到一個與源代碼匹配的展開方案就能夠了。聽起來咱們只要先給出一個 tao 語言的文法定義,而後寫一個找匹配方案的的程序就能夠了。
然而事情狀況並不是如此簡單。由於假如咱們不對文法定義的形式加諸任何限制的話,讓 Parser 找到匹配方案並不是很輕易的事情。語法
所以,我規定,tao 語言的將用 LL(1) 文法來定義。程序
在簡單介紹 LL(1) 文法以前,我還要說明一種比較特別的產生式。語言
A → ε集合
希臘字母 ε 表示「空」,這個產生式代表非終結符 A 能夠產生一個空。具體來講,若是有以下文法。源代碼
S → αAβblock
A → ε工作
那麼:
S → αβ
非終結符能夠產生空這一特性,令文法的形式更加複雜,可是倒是必不可少的。少了這一特徵,就很難描述 tao 語言的語法細節了。
此外,對於一個文法之中的非終結符,還有 FIRST 集、FOLLOW 集的概念。
對於一個非終結符 A 而言,它的 FIRST 集指 A 可能展開的各類形式中,位於第一的全部終結符所組成的集合。記爲 FIRST(A)。
而 FOLLOW 集,指在整個文法中,非終結符 A 後面可能接的全部終結符組成的集合。記爲 FOLLOW(A)。
這麼描述可能有點繞,細節先無論,但有一點很重要,即不管是 FIRST 集仍是 FOLLOW 集,它們都只能包含終結符。
那麼,LL(1) 又是怎樣一種文法呢?
對於一個文法而言,若是它的每個非終結符的產生式
A → α | β | γ ……
都知足以下三個條件,則將這個文法稱之爲 LL(1) 文法。
對於全部不能導出 ε 的表達式 α、β、γ……,都有,FIRST(α)、FIRST(β)、FIRST(γ)……兩兩互不相交。
最多隻有一個表達式能夠導出 ε。
若是有一個表達式能夠導出 ε,那麼對於其餘不能夠導出 ε 的表達式 ξ,有,FIRST(ξ) ∩ FOLLOW(A) = Φ。
最後一條有加粗,固然並不是由於它對 LL(1) 自己很重要,而是由於我在實現 Parser 的時候並無徹底遵照這一條。某種意義上說,tao 語言的 Parser 並不是嚴格遵照 LL(1) 文法,所以在此加粗這條,以便與後面的章節呼應。