这篇文章主要介绍“go Antlr重构脚本解释器如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“go Antlr重构脚本解释器如何实现”文章能帮助大家解决问题。
Antlr
Antlr
GScript
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 tokentokentoken
要实现这些我们只需要编写词法、语法规则文件即可。
刚才的示例所对应的词法、语法规则如下:
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]?;
完整规则:github.com/crossoverJi…
运行:
antlr -Dlanguage=Go -o parser -visitor -no-listener GScript.g4
AntlrASTAST
以这里的新增的取模运算为例:
func (v *GScriptVisitor) VisitModExpr(ctx *parser.ModExprContext) interface{} { lhs := v.Visit(ctx.GetLhs()) rhs := v.Visit(ctx.GetRhs()) return lhs.(int) % rhs.(int) }
AntlrVisitModExpr
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 还有其他各种优势,比如可以解决:
左递归。
二义性。
优先级。
等问题。
这里也推荐在 IDE 中安装 Antlr 的插件,这样就可以直观的查看 AST 语法树,可以帮我们更好的调试代码。
升级 xjson
GScriptstatementxjson
xjsonAntlrGScriptstatement
Antlr