成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用 Antlr 重構(gòu)腳本解釋器

開發(fā) 開發(fā)工具
Antlr 就是做幫我們解決這些問題的常用工具,利用它我們只需要編寫詞法文件,然后就可以自動(dòng)生成詞法、語法解析器,并且可以生成不同語言的代碼。

前言

實(shí)現(xiàn)的腳本解釋器 GScript? 中實(shí)現(xiàn)了基本的四則運(yùn)算以及 AST 的生成。

圖片

當(dāng)我準(zhǔn)備再新增一個(gè) % 取模的運(yùn)算符時(shí),會(huì)發(fā)現(xiàn)工作很繁瑣而且?guī)缀醵际侵貜?fù)的;主要是兩步:

  • 需要在詞法解析器中新增對(duì)% 符號(hào)的支持。
  • 在語法解析器遍歷 AST 時(shí)對(duì)% token 實(shí)現(xiàn)具體邏輯。

其中的詞法解析和遍歷 AST 完全是重復(fù)工作,所以我們可否能夠簡化這兩步呢?

Antlr

Antlr 就是做幫我們解決這些問題的常用工具,利用它我們只需要編寫詞法文件,然后就可以自動(dòng)生成詞法、語法解析器,并且可以生成不同語言的代碼。

下面以 GScript 的示例來看看 antlr 是如何幫我們生成詞法分析器的。

func TestGScriptVisitor_Visit_Lexer(t *testing.T) {
expression := "(2+3) * 2"
input := antlr.NewInputStream(expression)
lexer := parser.NewGScriptLexer(input)
for {
t := lexer.NextToken()
if t.GetTokenType() == antlr.TokenEOF {
break
}
fmt.Printf("%s (%q) %d\n",
lexer.SymbolicNames[t.GetTokenType()], t.GetText(),t.GetColumn())
}
}
//output:
("(") 0
DECIMAL_LITERAL ("2") 1
PLUS ("+") 2
DECIMAL_LITERAL ("3") 3
(")") 4
MULT ("*") 6
DECIMAL_LITERAL ("2") 8

Antlr ?會(huì)自動(dòng)將我們的表達(dá)式解析為 token?,遍歷 token? 時(shí)還能拿到該 token 所在的代碼行數(shù)、位置等信息,在編譯期間做語法檢查非常有用。

要實(shí)現(xiàn)這些我們只需要編寫詞法、語法規(guī)則文件即可。

剛才的示例所對(duì)應(yīng)的詞法、語法規(guī)則如下:

expr
: '(' expr ')' #NestedExpr
| liter=literal #Liter
| lhs=expr bop=( MULT | DIV ) rhs=expr #MultDivExpr
| lhs=expr bop=MOD rhs=expr #ModExpr
| lhs=expr bop=( PLUS | SUB ) rhs=expr #PlusSubExpr
| expr bop=(LE | GE | GT | LT ) expr # GLe
| expr bop=(EQUAL | NOTEQUAL) expr # EqualOrNot
;
DECIMAL_LITERAL: ('0' | [1-9] (Digits? | '_'+ Digits)) [lL]?;

完整規(guī)則:https://github.com/crossoverJie/gscript/blob/main/GScript.g4

運(yùn)行:

antlr -Dlanguage=Go -o parser -visitor -no-listener GScript.g4

就可以幫我們生成 Go? 的代碼(默認(rèn)是 Java?),關(guān)于 Antlr 的詞法、文法規(guī)則以及安裝步驟請(qǐng)參考官網(wǎng)。

而我們要實(shí)現(xiàn)具體的語法邏輯時(shí)只需要實(shí)現(xiàn)相關(guān)的接口,Antlr? 會(huì)自動(dòng)遍歷 AST?(當(dāng)然也可以手動(dòng)控制),同時(shí)在訪問不同的 AST 節(jié)點(diǎn)時(shí)會(huì)回調(diào)我們自己實(shí)現(xiàn)的接口,這樣我們就能編寫自己的語法規(guī)則了。

以這里的新增的取模運(yùn)算為例:

func (v *GScriptVisitor) VisitModExpr(ctx *parser.ModExprContext) interface{} {
lhs := v.Visit(ctx.GetLhs())
rhs := v.Visit(ctx.GetRhs())
return lhs.(int) % rhs.(int)
}

當(dāng) Antlr? 回調(diào) VisitModExpr 方法時(shí),便能獲取到 % 符號(hào)左右兩側(cè)的數(shù)據(jù),這時(shí)只需要做相關(guān)運(yùn)算即可。

基于這個(gè)模式這次新增了一個(gè) statement,具體語法如下:

func TestGScriptVisitor_VisitIfElse8(t *testing.T) {
expression := `
if(3!=(1+2)){
return 1+3
} else {
return false
}`
input := antlr.NewInputStream(expression)
lexer := parser.NewGScriptLexer(input)
stream := antlr.NewCommonTokenStream(lexer, 0)
parser := parser.NewGScriptParser(stream)
parser.BuildParseTrees = true
tree := parser.Prog()
visitor := GScriptVisitor{}
var result = visitor.Visit(tree)
fmt.Println(expression, " result:", result)
assert.Equal(t, result, false)
}

Antlr 還有其他各種優(yōu)勢(shì),比如可以解決:

  • 左遞歸。
  • 二義性。
  • 優(yōu)先級(jí)。

等問題。

這里也推薦在 IDE 中安裝 Antlr 的插件,這樣就可以直觀的查看  AST 語法樹,可以幫我們更好的調(diào)試代碼。

圖片

圖片

升級(jí) xjson

借助 GScript? 提供的 statement,xjson? 也提供了有些有意思的寫法:

圖片

因?yàn)?nbsp;xjson? 的四則運(yùn)算語法沒有使用 Antlr? 生成,所以為了能支持 GScript? 提供的 statement 需要手寫許多詞法代碼。

圖片

這也體現(xiàn)了 Antlr 這類前端工具的重要性,效率提升是非常明顯的。

責(zé)任編輯:武曉燕 來源: crossoverJie
相關(guān)推薦

2019-07-24 13:42:34

Python編程語言代碼

2016-09-12 14:05:27

PythonPython解釋器Web

2009-07-14 15:20:25

Jython腳本Jython解釋器

2022-06-29 09:02:31

go腳本解釋器

2009-06-08 10:30:00

ASP腳本服務(wù)器

2010-03-19 13:04:12

Pyhon腳本解釋器

2009-12-22 14:52:54

ADO.NET腳本

2014-08-12 13:41:10

歐朋瀏覽器

2018-12-04 13:30:28

Javascript編譯原理前端

2020-10-13 14:27:11

算法可視化路線

2014-01-02 15:16:42

PythonLinux服務(wù)器服務(wù)器監(jiān)控

2020-11-09 08:20:33

解釋器模式

2023-10-18 10:48:44

Python解釋器

2010-02-01 17:11:45

Python 解釋器

2023-05-15 08:51:46

解釋器模式定義

2010-02-03 15:01:33

Python 解釋器

2019-06-26 18:50:16

匯編器編譯器解釋器

2022-06-21 14:41:38

播放器適配西瓜視頻

2022-10-27 10:06:16

Presto SQLAntlr大數(shù)據(jù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 黄色成人免费在线观看 | 国产精品久久久久久久久久久免费看 | 犬夜叉在线观看 | 99久久久国产精品 | 成人欧美一区二区三区在线播放 | 国产在线精品一区二区三区 | 国产第一页在线播放 | 蜜桃传媒一区二区 | 欧美婷婷 | 国产亚洲欧美在线视频 | 日本精品在线播放 | 免费观看www7722午夜电影 | 中文字幕成人av | 国久久 | 国产精品一区二区视频 | 日韩在线观看中文字幕 | 久久成人精品视频 | 国产视频精品视频 | 中文字幕成人av | 91精品国产综合久久婷婷香蕉 | 精品欧美一区二区久久久伦 | 日韩视频免费看 | 国产成人精品久久二区二区91 | 久久久激情 | 亚洲精品一区二区三区蜜桃久 | a久久久久久 | 久久一二区 | 五月天激情综合网 | 日韩靠逼 | 国产91丝袜在线18 | 草草草影院| 五月槐花香| 本地毛片 | 欧美一区不卡 | 夜夜爽99久久国产综合精品女不卡 | 日本成人中文字幕在线观看 | 欧美不卡 | 国产一区二区视频免费在线观看 | 噜啊噜在线 | 成年人国产在线观看 | 国产1区2区 |