UP | HOME

ANTLR v4–introduction

今天我想介紹一個強大有趣的工具–ANTLR

這個工具根據我們定義的文法產生處理原始碼的 parser,當然不只是處理程式語言,你也可以用來處理其他資料

1. 安裝

cd /usr/local/lib
sudo curl -O http://www.antlr.org/download/antlr-4.7-complete.jar
export CLASSPATH=".:/usr/local/lib/antlr-4.7-complete.jar:$CLASSPATH"
alias antlr4='java -jar /usr/local/lib/antlr-4.7-complete.jar'
alias grun='java org.antlr.v4.gui.TestRig'

之後會用到的通常是=antlr4=這支程式

因為它用來產生 parser

2. 開始

我們需要建立一個檔案叫=xxx.g4=,而裡頭的 grammar 就必須是=grammar xxx;=

舉例來說=JSON.g4=就會是

grammar JSON;

接下來我們談=ANLTR=的語法還有它如何運作

首先如果你接觸過=v3=以前的=antlr=,那麼你一定知道=embbed action=

不過這個版本的=antlr=並不需要全都使用=embbed action=來實現程式邏輯

反之它加入了=xxxBaseListener=來處理大部分的翻譯過程

你也可以選擇=Visitor=來實作,但是=visitor=需要顯式的調用=Context=,並不適合大型複雜的文法

=Listener=則能應付絕大多數的情況,它的=API=都是=enterXxx=跟=exitXxx=的格式,名稱相當直觀

3. 約定

ANTLR 要求=Token=使用大寫英文字母開頭,=grammar=則使用小寫

例如:

NUM : [0-9]+ ;
ID : [a-z]+ ;

stat : ID '=' expr
    | expr
    ;

expr : NUM
    | ID
    ;

=ID=跟=NUM=都是=token=,=stat=跟=expr=則是文法規則

| 表示不同的可能

; 表示規則結束

可以看到如果我們想要辨別符號,必須用=''=包起來,除了符號,關鍵字也要這樣處理,像這樣

Class : 'class' ;

+ 表示一個或無限多個

* 表示沒有或無限多個

? 表示有或沒有

定義=ID=跟=NUM=時,我都使用了正規表達式來處理,這是為了方便而放入的功能

你也可以選擇

NUM : ('0' .. '9')+ ;

這種寫法

最後就是產生=parser=

antlr4 -Dlanguage=Cpp JSON.g4

-Dlanguage 指定產生什麼語言的=parser=

這裡是=C++=

如果不指定,那麼預設是=Java=

目前支援=Java=, C#, Python2|3, JavaScript, Go, C++, Swift

儘管選擇你習慣的那個

為什麼要學 Antlr?

事實上編譯技術在很多地方都有用途

例如=Firefox=團隊為了加速=JavaScript= =eval=函式的執行速率,在編譯到=eval=時會進行預處理,讓=JavaScript=真的執行到這邊時已經少了許多工作

簡單一些的應用可能有:編寫=DSL=簡化開發工作

例如新增網路服務=API=,如果用特製的語言將工作進行簡化

routes:
    get "/":
	resp Page1

那麼我們實際上需要負擔的工作量就大幅縮小了吧!

而且亦便於未來的維護工作,而=DSL=最棒的要點就在於,我們往往無須實現完整的通用語言

比如我們可以在回傳的區塊回到=Java=語言

routes:
    get "/":
	@java {
	    // ... Your java code
	}

這樣我們就不需要實現太過麻煩的東西

而一樣能享受=DSL=的方便度

Date: 2017-09-03 Sun 00:00

Author: Lîm Tsú-thuàn