Goland 中Antlr4插件
在goland中安裝Antlr4插件,用于識別輸入的字符在在語法檔案中生成的語法樹的樣子,大概就是如下的摸樣

下載步驟:
1.點擊檔案中的設定選項

2.在插件目錄下輸入Antlr4搜索插件

3.點擊安裝即可
撰寫自己的語言語法檔案
撰寫語法之前,我們首先要構思一下自己的DSL都有什么關鍵字,這是個重要的步驟,就像我們學習java或者Golang一樣,首先知道這個語法里面都有那些關鍵字,
我定義的DSL中有四則運算,有比較運算,還有邏輯運算,變數可以有數字、字串、時間格式
關鍵字
四則運算
| 作用 | 符號 |
|---|---|
| 乘法 | * |
| 除法 | / |
| 加法 | + |
| 減法 | - |
比較運算
| 作用 | 符號 |
|---|---|
| 等于 | = |
| 不等于 | <> |
| 大于 | > |
| 大于等于 | >= |
| 小于 | < |
| 小于等于 | <= |
邏輯運算
| 作用 | 符號 |
|---|---|
| 且 | && |
| 或 | || |
| 如果 | if |
| 否則 | else |
變數
| 作用 | 符號 |
|---|---|
| 數字 | ('0' | [1-9] ('_'? [0-9])*) |
| 文本 | [\p{Nd}] |
| 字串 | LETTER (LETTER |
| 日期 | ([0-9]{4}/[0-1]{0,1}[0-9]/[0-3]{0,1}[0-9]) |
常量輔助符號
| 作用 | 符號 |
|---|---|
| 點 | . |
| 逗號 | , |
| 左括號 | ( |
| 右括號 | ) |
| 分號 | ; |
| 多行注釋 | '/*' .*? '*/' |
上述就是我們的Token串列,可以創建一個文法檔案單獨寫Token,文法檔案申明:lexer grammar Lexer;
撰寫語法
撰寫語法之前,我們需要構思一下,我們的DSL可以支持那些語法操作,例如四則運算可以支持字串運算嗎?日期支持四則運算嗎?我們可以從基礎開始撰寫,例如我們把變數使用算則模式撰寫成一個語法規則,
simpleStmt:NUMBER|TEXT|STRING|DATE
我的DSL中支持任何資料的四則運算,那么我就可以使用simpleStmt和四則運算子號組成四則運算
expression:
simpleStmt #SimpleExpression
|expression op = (MUL|DIV) expression #MulDiv
|expression op = (ADD|SUB) expression #AddSub
;
這時候我們就定義了支持四則運算的語法規則,我們來試一下語法定義的對不對,

發現我們輸入的加法運算和乘法運算都可以被決議,說明我們的語法定義正確,接下來我們添加比較運算
我定義的DLS支持所有資料做比較運算,那么我直接在上面的expression中添加比較運算就可以了,這里需要注意的是比較運算如果希望有優先級,需要先定義優先級高的比較符號,我這里沒有優先級操作,所以都是平級的,
添加比較運算子號
expression:
simpleStmt #SimpleExpression
|expression op = (MUL|DIV) expression #MulDiv
|expression op = (ADD|SUB) expression #AddSub
|expression op = (EQ|NE|LT|LE|GT|GE) expression #Compare
;
驗證一下比較運算語法定義的是否正確,

發現沒有錯誤,正確決議出樹就代表語法定義的正確,接下來大家可以自己構思一下剩下的語法規則,或者添加自己的語法規則了,大概思路就是先想一個語法希望是什么樣,然后撰寫語法規則,然后輸入希望的格式驗證語法規則,
撰寫Listener
還是老樣子,撰寫號語法檔案,我們執行Antlr4生成運行時語言為Go的命令:
java -jar 'C:\Program Files\Java\antlr\antlr-4.12.0-complete.jar' -Dlanguage=Go -no-visitor -package parser *.g4
撰寫監聽器類
type CalcListener struct{
*parser.BaseCalcListener //繼承Listener基類
*antlr.DefaultErrorListener //繼承錯誤基類
}
//發生錯誤時,處理錯誤
func (l *CalcLister) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
}
//退出MulDiv語法時
func (l *CalcLister) ExitMulDiv(c *parser.MulDivContext) {
}
//退出AddSub語法時
func (l *CalcLister) ExitAddSub(c *parser.AddSubContext) {
}
//退出數字語法時
func (l *CalcLister) ExitNumber(c *parser.NumberContext) {
}
這里細心的小伙伴已經發現,在語法檔案中使用“#”指定的節點名稱在監聽器中回生成一個節點方法,在Antlr4中,“#”號代表手動指定語法規則名稱,需要注意的是,不要跟Token和規則名稱重復,
遍歷語法樹

Antlr4遍歷語法樹時,使用DFS方式遍歷樹
監聽模式和訪問模式
Antlr4提供了兩種遍歷語法樹的方式,監聽模式和訪問模式,默認是監聽模式,如果希望使用訪問模式的話,需要修改命令:
java -jar 'C:\Program Files\Java\antlr\antlr-4.12.0-complete.jar' -Dlanguage=Go -visitor -package parser *.g4
這樣會生成訪問者模式和監聽者模式
calc_base_listener.go //監聽者模式基類檔案
calc_base_visitor.go //訪問者模式基類檔案
訪問者模式:先遍歷父節點,然后遍歷子節點
監聽者模式:Enter先進入父節點,Exit最后退出父節點
個人建議還是使用監聽者模式,在Enter控制子節點訪問,Exit做父節點子樹執行邏輯,訪問者模式控制能力更強,監聽者模式需要遍歷整個樹,
至此,使用golang+Antlr4就可以定義一個屬于自己的語法規則的決議器了,如果有哪里不同的可以給小編留言,我們共同學習!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548442.html
標籤:Go
上一篇:👉??👈使用Apikit輕松管理和測驗你的API,我和女票已經get到了!
下一篇:非看不可的Redis持久化
