擴展iQuery使其支持多種編程語言(上) – 兼編譯器的詞法分析簡介

iQuery是一個開源的自動化測試框架項目,有興趣的朋友能夠在這裏下載:
https://github.com/vowei/iQuery/downloadscss

源碼位置:
https://github.com/vowei/iQueryhtml

在上一篇文章中,簡單介紹了擴展iQuery,使其支持儘量多的自動化測試平臺,但剩下對編程語言的擴展沒有講。python

當前iQuery已經實現了Java和JavaScript版本,對其餘語言的支持仍在討論當中,感興趣的網友能夠參照本文的講解自行擴展。git

Antlr是能夠生成不少編程語言的源文件,在其官網上,能夠看到其支持:C、Java、JavaScript、C#、Object-C、Python、Perl等編程語言,詳細狀況請參閱:http://www.antlr.org/wiki/display/ANTLR3/Code+Generation+Targets。github

咱們知道,通常來講編譯器或者解釋器的流程都是:
詞法解析 -> 語法解析 -> 語義分析 -> 代碼優化 -> 生成(執行)代碼正則表達式

因爲iQuery很簡單,充其量就是一個DSL,因此在實現時,就直接將語義分析、代碼優化跳過了,後面在講解iQA這個編程語言的時候會聊到那些內容。編程

首先看一下iQuery的完整語法(其實能夠把它看成一個廣義的正則表達式對待):
https://github.com/vowei/iQuery/blob/master/iQuery.g 框架

由於語法很是簡單,就沒有必要將詞法和語法分到兩個文件去寫了,直接合並在一個文件裏,但合併並不意味着詞法分析和語法分析這兩個過程就合併成一個步驟了,antlr在生成代碼是,仍是會生成兩個類,iQueryLexer和iQueryParser兩個類,也就是說仍是兩個步驟。編程語言

先看詞法分析過程,詞法分析過程實際上就是將輸入的字符串歸類,歸類過程當中能夠剔除一些不用的字符(好比空格、註釋之類的),方便在語法分析過程當中處理。詞法分析和語法分析這兩個過程,跟打牌相似,好比八十分,抓牌把牌分類的時候就是詞法分析,打牌時就是語法和語義分析,抓牌後打牌前有個墊底過程,至關於在詞法分析時扔掉一些不用的字符:函數

DESCENDANT: '>>';
EQ: 'eq';
GT: 'gt';
LT: 'lt';
NOT: 'not';
CONTAINS: 'contains';
EMPTY: 'empty';
HAS: 'has';
PREV: 'prev';
NEXT: 'next';
SIBLINGS: 'siblings';
NTH_CHILD: 'nth-child';
PARENT: 'parent';
LAST_CHILD: 'last-child';
FIRST_CHILD: 'first-child';
FIRST: 'first';
LAST: 'last';
INTEGER: DIGIT+;
PERCENTAGE: ('+' | '-')? DIGIT+ ('.' DIGIT+)? '%';
FLOAT: ('+' | '-')? DIGIT+ ('.' DIGIT+)?;
fragment DIGIT: ('0' .. '9');
ELEMENT: ('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.')*;
ASTERISK: '*';
QUOTED_STRING: '\'' .+ '\''; 
NEWLINE: '\r'? '\n';
WS: (' ' | '\t') { skip(); };

全部大寫字母組成的單詞都是詞法分析後生成的記號(Token),匹配的方式是依照簡化的正則表達式方式匹配,並且匹配的優先級依照記號在文件裏的出現順序。好比說:

  • 例如’a’ .. ‘z’表示匹配從字符’a’到’z’的全部字符,「?」表示可選匹配,「|」表示取一(Or)匹配,「*」表示匹配零到屢次等等,這個跟你們熟悉的正則表達式語法很接近,不詳述。
  • 當詞法分析器(這裏是iQueryLexer – 由上表的代碼生成)碰到「>>」這個字符串,就將其歸類爲記號DESCENDANT。
  • 在匹配字符串時,詞法分析器按照各記號在文件裏的順序依次匹配,好比碰到「text」這個字符串,詞法分析器從DESCENDANT開始匹配,因爲在ELEMENT以前都沒有匹配成功,最後將其歸類爲ELEMENT(由於其匹配)。
  • 若是全部記號都不匹配,那麼詞法分析器會扔出一個錯誤,antlr已經可以處理不少詞法、語法方面的錯誤了,可是其仍是留了一個接口,供咱們精煉詞法、語法方面的錯誤處理,錯誤處理會在後文講到。
  • 若是在記號前加了一個fragment關鍵字,則說明該記號不是一個獨立記號,會被其餘記號引用,詳情參看:INTEGER、PERCENTAGE、FLOAT和DIGIT。
  • 對於空格、註釋等內容,使用skip()函數跳過,也就是說在語法分析階段不會看到這些字符,詳情參看:WS。
  • 最後,針對每個記號,antlr都會生成一個函數,這個函數裏的代碼能夠放入一些自定義的代碼,這裏因爲iQuery很簡單,所以沒有擴展詞法分析器,後面講解iQA的實現方式時,會提到它,我之前有一篇文章也談到了這一點:python等縮進語言的詞法分析實現

今天先聊到這裏,關於語法分析的內容,下一篇再講。

本文由知平軟件 施懿民編寫,請關注咱們的微博

相關文章
相關標籤/搜索