亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

go Antlr重構(gòu)腳本解釋器實現(xiàn)示例

 更新時間:2022年08月08日 15:54:32   作者:crossoverJie  
這篇文章主要為大家介紹了go Antlr重構(gòu)腳本解釋器實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

在上一個版本實現(xiàn)的腳本解釋器 GScript 中實現(xiàn)了基本的四則運算以及 AST 的生成。

當我準備再新增一個 % 取模的運算符時,會發(fā)現(xiàn)工作很繁瑣而且?guī)缀醵际侵貜偷?;主要是兩步?/p>

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

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

Antlr

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

下面以 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 會自動將我們的表達式解析為 token,遍歷 token 時還能拿到該 token 所在的代碼行數(shù)、位置等信息,在編譯期間做語法檢查非常有用。

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

剛才的示例所對應的詞法、語法規(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ī)則:github.com/crossoverJi…

運行:

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

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

以這里的新增的取模運算為例:

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

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

基于這個模式這次新增了一個 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)勢,比如可以解決:

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

等問題。

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

升級 xjson

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

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

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

總結(jié)

借助于 Antlr 后續(xù) GScript 會繼續(xù)支持函數(shù)調(diào)用、更完善的類型系統(tǒng)、面向?qū)ο蟮忍匦?;感興趣的朋友請持續(xù)關注。

源碼地址:

github.com/crossoverJi…

github.com/crossoverJi…

以上就是go Antlr重構(gòu)腳本解釋器實現(xiàn)示例的詳細內(nèi)容,更多關于go Antlr腳本解釋器的資料請關注腳本之家其它相關文章!

相關文章

  • golang http使用踩過的坑與填坑指南

    golang http使用踩過的坑與填坑指南

    這篇文章主要介紹了golang http使用踩過的坑與填坑指南,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go語言面試題之select和channel的用法

    Go語言面試題之select和channel的用法

    金九銀十面試季到了(PS:貌似今年一年都是面試季),就業(yè)環(huán)境很差,導致從業(yè)人員不得不卷。本文將重點講解一下Go面試進階知識點之select和channel,需要的可以參考一下
    2022-09-09
  • Golang使用JWT進行認證和加密的示例詳解

    Golang使用JWT進行認證和加密的示例詳解

    JWT是一個簽名的JSON對象,通常用作Oauth2的Bearer?token,JWT包括三個用.分割的部分。本文將利用JWT進行認證和加密,感興趣的可以了解一下
    2023-02-02
  • 如何使用go-zero開發(fā)線上項目

    如何使用go-zero開發(fā)線上項目

    這篇文章主要介紹了如何使用go-zero開發(fā)線上項目,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Go語言配置數(shù)據(jù)庫連接池的實現(xiàn)

    Go語言配置數(shù)據(jù)庫連接池的實現(xiàn)

    本文內(nèi)容我們將解釋連接池背后是如何工作的,并探索如何配置數(shù)據(jù)庫能改變或優(yōu)化其性能。文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • go語言中sort包的實現(xiàn)方法與應用詳解

    go語言中sort包的實現(xiàn)方法與應用詳解

    golang中也實現(xiàn)了排序算法的包sort包,所以下面這篇文章主要給大家介紹了關于go語言中sort包的實現(xiàn)方法與應用的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友們可以參考借鑒,下面隨著小編來一起學習學習吧。
    2017-11-11
  • 一文帶你了解Go中的內(nèi)存對齊

    一文帶你了解Go中的內(nèi)存對齊

    一旦涉及到較為底層的編程,特別是與硬件交互,內(nèi)存對齊是一個必修的課題,所以這篇文章小編就想來和大家聊一聊Go語言中的內(nèi)存對齊,希望對大家有所幫助
    2023-10-10
  • golang如何用type-switch判斷interface變量的實際存儲類型

    golang如何用type-switch判斷interface變量的實際存儲類型

    這篇文章主要介紹了golang如何用type-switch判斷interface變量的實際存儲類型,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 深入了解Go語言的基本語法與常用函數(shù)

    深入了解Go語言的基本語法與常用函數(shù)

    這篇文章主要為大家詳細介紹一下Go語言中的基本語法與常用函數(shù),文中的示例代碼講解詳細,對我們學習Go語言有一定的幫助,需要的可以參考一下
    2022-07-07
  • golang基礎之Gocurrency并發(fā)

    golang基礎之Gocurrency并發(fā)

    這篇文章主要介紹了golang基礎之Gocurrency并發(fā),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07

最新評論