從零開始寫個編譯器吧 - 文法簡介

我須要定義出 tao 語言的細節,在此,須要引出文法這一律念。所謂文法,便是用於描述語言的一種工具。
例如,一個賦值語句可能寫成以下形式:工具

variable = 1 + 3遞歸

如何充分定義這個賦值語句的形式呢?若用天然語言描述,我能夠說,賦值語句最左邊是一個標示符,而後緊接一個「=」符號,而後再接一個表達式。知足這個條件的,便是賦值語句啦。語法

S → abE語言

用符號來描述的話,就是如上形式,這種形式稱之爲 S 的產生式。其中 S 表示賦值語句,a 表示一個標示符,b 是「=」符號,E 表示表達式。這裏用到了S、a、b、E 四個不一樣的字母。源代碼

等等,彷佛還有什麼沒說完,由於標示符(字母a表示)與「=」符號(字母b表示)都與 Tokenizer 生成的 Token 對應,可是表達式(字母E表示)卻沒有對應的 Token 呀。block

因而,我還要進一步描述表達式。這裏爲了避免讓問題變得過於繁瑣,我先假定表達式只出現加減號和數字。那麼表達式的定義以下。數字

E → d | E+d | E-d生成

這裏出現的「|」表示「或」,這代表表達式(字母E)能夠展開成三種不一樣的式子。同時,E 展開後的式子中可能再次出現 E 自己,這種遞歸形式足以涵蓋任意長度的表達式形式。index

因而,咱們又獲得字母 d,d 表示一個數字(也與某種 Token 對應)。ab

至此,咱們一共獲得了 S、a、b、E、d 五個不一樣的字母,其中 a、b、d 都與 Token 對應。然而,雖然 S、E 卻沒有對應的 Token,但它們都有至少有一個屬於本身的產生式。

對於 a、b、d,稱之爲終結符。即它們不會再有本身的產生式了。而 S、E,稱之爲非終結符

當咱們爲式子中某個非終結符挑選一個特定的產生式,並用產生式的右邊部分代替這個非終結符在式子中的位置,那麼咱們將這個過程稱之爲非終結符的展開

考慮下面這行代碼:

index = 15 + 7 - 3

其形如 abd+d-d(a 爲 "index"、b 爲"="、d 爲"15", "7", "3")

對於 S 有以下展開方式:

S → abE

→ abE-d(展開 E → E-d)

→ abE+d-d(展開 E → E+d)

→ abd+d-d(展開 E → d)

其中 S 表示一個賦值語句。既然 S 存在某種展開方式,其形式與這行代碼徹底相同,咱們說,這行代碼與 S 是匹配的。對於 Parser 而言,便可判定這行語句是一個賦值語句。

所以,Parser 讀取語言的文法定義。而後,經過找到一個展開方案以匹配源代碼。而這個展開方案中對各個非終結符產生式的選擇過程,便是對源代碼中每個部分的定性過程。這個過程讓 Parser 可以理解源代碼各個部分表示的含義,並以今生成對應的語法樹(Syntax Tree)。

相關文章
相關標籤/搜索