天天看點

JQuery 擴充多語言支援

iQuery是一個開源的自動化測試架構項目,有興趣的朋友可以在這裡下載下傳: 

<a href="https://github.com/vowei/iQuery/downloads">https://github.com/vowei/iQuery/downloads</a>

源碼位置: 

<a href="https://github.com/vowei/iQuery">https://github.com/vowei/iQuery</a>

目前iQuery已經實作了Java和JavaScript版本,對其他語言的支援仍在讨論當中,感興趣的網友可以參照本文的講解自行擴充。

我們知道,一般來說編譯器或者解釋器的流程都是: 

詞法解析 -&gt; 文法解析 -&gt; 語義分析 -&gt; 代碼優化 -&gt; 生成(執行)代碼

由于iQuery很簡單,充其量就是一個DSL,是以在實作時,就直接将語義分析、代碼優化跳過了,後面在講解iQA這個程式設計語言的時候會聊到那些内容。

首先看一下iQuery的完整文法(其實可以把它當作一個廣義的正規表達式對待): 

<a href="https://github.com/vowei/iQuery/blob/master/iQuery.g">https://github.com/vowei/iQuery/blob/master/iQuery.g</a>

因為文法非常簡單,就沒有必要将詞法和文法分到兩個檔案去寫了,直接合并在一個檔案裡,但合并并不意味着詞法分析和文法分析這兩個過程就合并成一個步驟了,antlr在生成代碼是,還是會生成兩個類,iQueryLexer和iQueryParser兩個類,也就是說還是兩個步驟。

先看詞法分析過程,詞法分析過程實際上就是将輸入的字元串歸類,歸類過程中可以剔除一些不用的字元(比如空格、注釋之類的),友善在文法分析過程中處理。詞法分析和文法分析這兩個過程,跟打牌類似,比如八十分,抓牌把牌分類的時候就是詞法分析,打牌時就是文法和語義分析,抓牌後打牌前有個墊底過程,相當于在詞法分析時扔掉一些不用的字元:

所有大寫字母組成的單詞都是詞法分析後生成的記号(Token),比對的方式是依照簡化的正規表達式方式比對,而且比對的優先級依照記号在檔案裡的出現順序。比如說:

例如’a’ .. ‘z’表示比對從字元’a’到’z’的所有字元,“?”表示可選比對,“|”表示取一(Or)比對,“*”表示比對零到多次等等,這個跟大家熟悉的正規表達式文法很接近,不詳述。

當詞法分析器(這裡是iQueryLexer – 由上表的代碼生成)碰到“&gt;&gt;”這個字元串,就将其歸類為記号DESCENDANT。

在比對字元串時,詞法分析器按照各記号在檔案裡的順序依次比對,比如碰到“text”這個字元串,詞法分析器從DESCENDANT開始比對,由于在ELEMENT之前都沒有比對成功,最後将其歸類為ELEMENT(因為其比對)。

如果所有記号都不比對,那麼詞法分析器會扔出一個錯誤,antlr已經能夠處理很多詞法、文法方面的錯誤了,但是其還是留了一個接口,供我們精煉詞法、文法方面的錯誤處理,錯誤處理會在後文講到。

如果在記号前加了一個fragment關鍵字,則說明該記号不是一個獨立記号,會被其他記号引用,詳情參看:INTEGER、PERCENTAGE、FLOAT和DIGIT。

對于空格、注釋等内容,使用skip()函數跳過,也就是說在文法分析階段不會看到這些字元,詳情參看:WS。

最後,針對每一個記号,antlr都會生成一個函數,這個函數裡的代碼可以放入一些自定義的代碼,這裡由于iQuery很簡單,是以沒有擴充詞法分析器,後面講解iQA的實作方式時,會提到它,我以前有一篇文章也談到了這一點:python等縮進語言的詞法分析實作。

今天先聊到這裡,關于文法分析的内容,下一篇再講。