当前位置:网站首页>go Antlr重构脚本解释器如何实现
go Antlr重构脚本解释器如何实现
2022-08-09 08:52:00 【亿速云】
go Antlr重构脚本解释器如何实现
这篇文章主要介绍“go Antlr重构脚本解释器如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“go Antlr重构脚本解释器如何实现”文章能帮助大家解决问题。
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: ("(") 0DECIMAL_LITERAL ("2") 1PLUS ("+") 2DECIMAL_LITERAL ("3") 3 (")") 4MULT ("*") 6DECIMAL_LITERAL ("2") 8
Antlr
会自动将我们的表达式解析为 token
,遍历 token
时还能拿到该 token
所在的代码行数、位置等信息,在编译期间做语法检查非常有用。
要实现这些我们只需要编写词法、语法规则文件即可。
刚才的示例所对应的词法、语法规则如下:
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
而我们要实现具体的语法逻辑时只需要实现相关的接口,Antlr
会自动遍历 AST
(当然也可以手动控制),同时在访问不同的 AST
节点时会回调我们自己实现的接口,这样我们就能编写自己的语法规则了。
以这里的新增的取模运算为例:
func (v *GScriptVisitor) VisitModExpr(ctx *parser.ModExprContext) interface{} { lhs := v.Visit(ctx.GetLhs()) rhs := v.Visit(ctx.GetRhs()) return lhs.(int) % rhs.(int)}
当 Antlr
回调 VisitModExpr
方法时,便能获取到 % 符号左右两侧的数据,这时只需要做相关运算即可。
基于这个模式这次新增了一个 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
借助 GScript
提供的 statement
,xjson
也提供了有些有意思的写法:
因为 xjson
的四则运算语法没有使用 Antlr
生成,所以为了能支持 GScript
提供的 statement
需要手写许多词法代码。
这也体现了 Antlr
这类前端工具的重要性,效率提升是非常明显的。
关于“go Antlr重构脚本解释器如何实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。
边栏推荐
猜你喜欢
Database MySQL installation and uninstallation
requests之防盗链学习
OpenHarmony Light Smart Product Development Live Notes
【场景化解决方案】搭建数据桥梁,Dslink打通泛微系统连接流
Redis缓存设计
QT设置exe可执行文件的图标
get一个小技巧,教你如何在typora写文章上传图片到博客上
+ 6000 words, help you understand the Internet architecture evolution.
Notes on OpenHarmony Open Source Meeting (Nanjing Station)
leetcode 33. 搜索旋转排序数组 (二分经典题)
随机推荐
XCTF College War "Epidemic" Network Security Sharing Competition Misc wp
nyoj58 最少步数(DFS)
内存中的swap机制
nyoj306 走迷宫(搜索+二分)
BUUCTF MISC Writing Notes (1)
Introduction to Network Layer Protocols
makefile - 学习小结
【GNN】2022 G-Mixup: Graph Data Augmentation for Graph Classification
Account and Permission Management
eTS UI development learning
gin清晰简化版curd接口例子
[Vulnerability reproduction] CVE-2018-7490 (path traversal)
数据解析之bs4学习
PoPW代币分配机制或将点燃下一个牛市
图像识别后将识别结果整理成列表,点击列表可跳转到搜索页面
makefile 遗漏分割符 您的意思是用TAB代替8个空格?
100句话,是否会触动你?
epoll LT和ET 问题总结
深度学习时代的视频理解综述
firefox e.path无效