自己寫個JavaScript parser (分析器)系列 (1)


注:參考自http://dukeland.hk,本博客系列內容為自己解讀的成果,以備將來自己回顧使用。所有版權歸原作者所有,如有任何問題,請聯系原作者。

 

寫編程語言的分析器是一個較為困難的工作。按常規思路,遇到困難的工作我們首先要做的就是把它分解成數個模塊,便於我們化解和定位問題,然后各個擊破。那么為了完成編程語言的分析器:

1(字):將代碼按字符讀入,過濾掉空格、換行符、注釋等內容。

2(詞):在字符讀入的過程中就將這些字符組裝成編程語言關鍵字。比如不間斷地讀入了'v', 'a', 'r',那么就形成了'var’關鍵字,可以先行保存,以待后續分析使用。

3(句):關鍵字讀入了之后,還需要根據一些符號或其它方式“斷句”,把一堆關鍵字切分成一個個的語句。比如用‘\r\n'切或者用’;'切等等。當然,多個句子可以組成一個代碼塊,也需要在這里完成。經過這樣的整理,讀入的關鍵字之間的親疏關系才有了依據。

4(意):只有到了這個層面,才真正涉及到大量的編程語言的語義規范。比如一個加減乘除四則運算的語句,又如用正則表達式替換字符串的語句等等。

*5(譯):如果是編譯器,在了解了輸入代碼的意思后,還需要把這個意思再翻譯成另一種可用的語言來執行。

難點:

1(字):單字符讀入不存在什么難點;

2(詞):

a,因為讀詞是在讀字符的基礎上進行的,所以需要一個狀態機來指示,什么時候是一個詞的開始,什么時候是一個詞的結束。

b,遇到二義性的詞,還需要往前或往后多讀一個詞,看看這個詞所在的上下文來做出判斷。比如關鍵字'/',遇到它你不能判斷這是一個除法符號還是行注釋的第一個字符,需要繼續往下讀一個才能做出判斷。類似的有'+'和'++',‘*’和‘/*’等。

3(句):斷句不難,但是需要考慮以何種存儲方式保存同屬於一個語句或一個代碼塊的詞,這樣后續的語義分析才會更加容易處理。

4(意):

a,四則運算中運算符優先級問題。

b,語法規則寬松的語言里,同一個意義多種表達的問題。比如JS中,var a; var b; 和 var a, b;是等同的。function f() {} 和 f = function () {}也是等同的。

c,JS中變量類型的問題。

d,以何種方式存儲語義分析結果的問題。

*5(譯):如果第四步翻的好,到這里譯起來就沒多大問題了。以為這里是用另一種語言來譯當前的語言,會涉及到你用來譯的這種語言的技巧問題。往往在這里還會對第四步形成反饋,比如該怎么去翻才能更快速的譯出來,這就是所謂的編譯器優化問題了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM