Grammarinator:基於ANTLR4語法自動生成語句

Grammarinator是一個基於ANTLR 4的grammar文件,自動生成語句的開源項目:https://github.com/renatahodovan/grammarinator。從語言的grammar生成語句或者所謂的Fuzzy Testing,對軟件測試很幫助。就像Grammarinator的README裏所說,它已經幫助一些項目發現了很多缺陷。本文通過一個簡單例子,讓大家先了解一下它是如何安裝和使用,是用來做什麼的。至於背後的理論,則還需要花時間深入學習。


1.安裝

Grammarinator的安裝不是很複雜,以下是我在Linux Mint 19上的安裝過程,主要依賴是Python3。一開始嘗試用pip3安裝,GitHub上說這樣比較簡單。但不知道爲什麼會報錯,沒安裝成功。沒辦法還是clone源碼安裝吧,最後終於成功。

#Install with pip3
$ sudo apt-get install -y python-setuptools
$ pip3 install grammarinator

#Install from source
$ git clone https://github.com/renatahodovan/grammarinator.git
$ cd grammarinator
$ sudo python3 setup.py install

安裝成功後應該會有兩個命令,grammarinator-processgrammarinator-generate,自動加到你的path裏。我們會在下一部分使用這兩個命令,來從ANTLR的grammar文件自動生成語句。


2.使用

下面已OpenDistro SQL項目爲例,看看如何利用其中的ANTLR grammar自動生成合法的語句。注意:src/main/antlr/OpenDistroSqlParser.g4因爲疏忽,沒有在Lexer的g4文件中定義DATE。在ANTLR裏不是問題,但Grammarinator不允許這種情況,所以先註釋掉Parser.g4中使用DATE的那一行避免Grammarinator拋異常。

$ git clone https://github.com/opendistro-for-elasticsearch/sql.git
$ cd sql

$ grammarinator-process src/main/antlr/OpenDistroSqlLexer.g4 src/main/antlr/OpenDistroSqlParser.g4 -o unparser
$ grammarinator-generate -l unparser/OpenDistroSqlUnlexer.py -p unparser/OpenDistroSqlUnparser.py -r selectStatement -n 100 -d 20 -o tests/test_%d.txt -t grammarinator.runtime.simple_space_transformer

可以看到Grammarinator是分兩步走的,第一步先生成所謂的Unlexer和Unparser。兩者都是Python文件,包含了兩個類,可以供我們自行擴展和修改。第二步纔是真正的自動生成。我們需要通過命令行參數指定:

  • -l:第一步生成的Unlexer文件的位置
  • -p:第一步生成的Unparser文件的位置
  • -n:我們想生成的總的語句個數
  • -d:我們想在grammar這些rule裏遞歸的深度。比如SQL因爲可以自由組合Subquery,所以需要depth選項控制深度。
  • -o:我們想把語句生成到哪,文件名是什麼樣子。
  • -t:可以額外指定transformer,比如官方提供了一個必選的simple_space_transformer。它會自動加空格,否則Gramminator生成的文本不會用空格間隔。
cat tests/test_274439899472822055781341517707794922780.txt
SELECT * , NESTED ( .FEFB   . `𝔋઄𑱐`   . * )   FROM ( `ኊ𝀀𖽿`  / MIN      )  , .WUMON   *  ""    NATURAL LEFT JOIN .CBG   / `𐨘ᜀ𐠹`     NATURAL JOIN ( ( `꣚𞠀𯨞`  / `𝕆𞹥𑌄᏾`   `𑙚଺𖿡¢`   )   )     WHERE \N    LIKE NOT \N     < =  ~  NULL      IS NOT TRUE  | |  NULL    IS MISSING ...

3.深入

別看Grammarinator在GitHub上的Star並不多,它本身是有紮實的理論基礎的。因爲從grammar生成合法語句這件事並不那麼簡單,比如:

  1. 左遞歸:grammar中經常會有left recursion,ANTLR和Grammarinator都會自動處理。如果要自己做的話,除了控制深度,左遞歸也是要考慮的一點。
  2. 收集語句:需要知道在哪一點是可以把當前的語法樹作爲合法語句保存起來,這不是簡單的遞歸遍歷語法的Token和Rule那樣簡單。

如果感興趣想要深入學習的話,請看Grammarinator作者們寫的這篇論文以及最後reference部分引用的其他論文:<Grammarinator: A Grammar-Based Open Source Fuzzer>。這部分資料貌似不是很多,自己搜索的話也基本就是這幾篇論文了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章