본문 바로가기
javascript

[JavaScript 통역]자바스크립트 | 제2부

by it-square 2021. 12. 29.
반응형

在上一篇文章裡我們講解了直譯器的基本架構,並實作出一個可以進行基礎四則運算的直譯器。但這個直譯器遇到正負號、空白字元、小數點、括號等等字元時會因為無法解析而出錯,因此本篇文章將會著手解決這些問題。

空白字元

要解決空白字元的問題非常簡單,只需要在讀取到空白字元時自動跳過就可以了,因此需要對我們的lexer稍加修改 :

lexer在讀取文字時若遇到空白字元,直接呼叫advance()跳過。

 

執行程式進行測試 :

js>    1         +              2
3
js> 12   +    345  *    2    / 10
81

測試成功 !

小數點

要能夠解析小數點的話,需要擴展我們lexer裡面的number()定義,在解析數字時遇到第一個小數點,可以接受這個字元並繼續向後解析,但若是同一個數字中出現多個小數點則會拋出錯誤 :

 

同樣的執行測試 :

js> 1.3 + 2.45
3.75
js> 345.2 + 9.8
355

測試成功 !

括號

括號處理起來會稍微麻煩一點,因為它會改變我們的語法規則,當初我們的規則是先乘除後加減,但括號的優先程度又要大於這些四則運算符號,因此我們會需要改變我們的parser,但在修改parser之前,需要先新增代表左右

 

接著修改parser的factor()解析方式 ,讓我們遇到到左括號時,會重新呼叫expr()來解析括號中的內容,解析完畢後再檢查是否有出現右括號,並將解析出來的子樹回傳 :

最後別忘了也要修改lexer,讓遇到括號時能夠解析並產生對應的token :

開始進行測試 :

js> (1+2)*3
9
js> (1+2*3)*4-5*6
-2

測試成功 !

 

上一篇文章有提到過,括號的出現會影響我們的抽象語法樹結構,因此我們可以將剛剛測試用的案例當作目標,練習建構出對應的抽象語法樹 :

正負號

若要處理正負號的狀況,我們需要一個新的抽象語法樹節點類型 : 一元運算符 unary,unary接受一個子節點,而我們可以在走訪的時候將子節點的值先進行正負操作再回傳,以此達到我們想要的效果,我們首先在src/ast

接著在parser解析時,實作unary的建構,我們在factor()裡面處理他,因為正負號的優先度是最高的 :

 

最後在interpreter裡面實作走訪到unary時的行為 :

這樣就完成正負號的部份了,一樣執行專案進行測試 :

js> +++---+-+-++---87
87
js> -(2+3)*-5
25
js> -2 * -(3-11) / ---4
4

測試成功 !

本篇文章的內容到這裡就結束了,這次我們將一些簡單但是重要的功能實作出來,雖然內容篇幅不長,但是剛好lexer、parser、interpreter這三個最重要的核心功能都有涵蓋到,正好能藉此機會更加熟悉直譯器的整個解析與執行流程。

 

下一次我們會介紹javascript程式碼的基本組成,包含函數、作用區塊、變量的型別、賦值與計算等等,並開始以真正的文本來進行解析,讓我們的直譯器更有架式。

這個系列的完整內容可以到我的github repo上參考。

참조:

간단한 통역사를 만들어 봅시다.

如果對於我的文章或程式碼有任何問題,歡迎在下方留言指教。

 

若有幫助到你,也歡迎給文章拍手一下,讓我在寫文章的路上更加進步!

댓글