当前位置:网站首页>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") 8Antlr 会自动将我们的表达式解析为 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重构脚本解释器如何实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。
边栏推荐
猜你喜欢

VMware virtual machine cannot be connected to the Internet after forced shutdown

QT程序生成独立exe程序(避坑版)

Where does detection go forward?

VLAN的原理及配置

图像识别后将识别结果整理成列表,点击列表可跳转到搜索页面

eTS UI development learning

QT设置exe可执行文件的图标

The difference between big-endian and little-endian storage is easy to understand at a glance
![[Vulnerability reproduction] CVE-2018-12613 (remote file inclusion)](/img/0b/707eb4266cb5099ca1ef58225642bf.png)
[Vulnerability reproduction] CVE-2018-12613 (remote file inclusion)

加密技术和电子竞技如何促进彼此的发展
随机推荐
XCTF College War "Epidemic" Network Security Sharing Competition Misc wp
腾讯云服务器修改为root登录安装宝塔面板
1. LVGL 8.3 在 Visual Studio 2019 模拟器中的环境搭建
Dark Horse 2022 latest redis course notes and knowledge points (for interview)
Programming a washing machine: garbled characters after string output
长辈相亲
Process synchronization and mutual exclusion problem
requests之数据解析Xpath介绍
[V&N2020 Open] Memory Forensics
数据解析之bs4学习
gin中改进版curd接口例子
elder blind date
vim 按了Ctrl+S后 卡死
Regular Expressions for Shell Programming
QT program generates independent exe program (pit-avoiding version)
VLAN的原理及配置
Introduction to Network Layer Protocols
A watch - article HongMeng development practical experience
eTS UI development learning
网络层协议介绍