首页 > 其他分享 >使用golang+antlr4构建一个自己的语言解析器(完结篇)

使用golang+antlr4构建一个自己的语言解析器(完结篇)

时间:2023-03-28 15:02:30浏览次数:44  
标签:解析器 完结篇 运算 四则运算 模式 golang Antlr4 语法 expression

Goland 中Antlr4插件

在goland中安装Antlr4插件,用于识别输入的字符在在语法文件中生成的语法树的样子,大概就是如下的摸样

下载步骤:
1.点击文件中的设置选项
image
2.在插件目录下输入Antlr4搜索插件
image
3.点击安装即可

编写自己的语言语法文件

编写语法之前,我们首先要构思一下自己的DSL都有什么关键字,这是个重要的步骤,就像我们学习java或者Golang一样,首先知道这个语法里面都有那些关键字。
我定义的DSL中有四则运算,有比较运算,还有逻辑运算,变量可以有数字、字符串、时间格式

关键字

四则运算

作用 符号
乘法 *
除法 /
加法 +
减法 -

比较运算

作用 符号
等于 =
不等于 <>
大于 >
大于等于 >=
小于 <
小于等于 <=

逻辑运算

作用 符号
&&
||
如果 if
否则 else

变量

作用 符号
数字 ('0' | [1-9] ('_'? [0-9])*)
文本 [\p{Nd}]
字符串 LETTER (LETTER
日期 ([0-9]{4}/[0-1]{0,1}[0-9]/[0-3]{0,1}[0-9])

常量辅助符号

作用 符号
.
逗号 ,
左括号 (
右括号 )
分号 ;
多行注释 '/*' .*? '*/'

上述就是我们的Token列表,可以创建一个文法文件单独写Token,文法文件申明:lexer grammar Lexer;

编写语法

编写语法之前,我们需要构思一下,我们的DSL可以支持那些语法操作,例如四则运算可以支持字符串运算吗?日期支持四则运算吗?我们可以从基础开始编写,例如我们把变量使用算则模式编写成一个语法规则,

simpleStmt:NUMBER|TEXT|STRING|DATE

我的DSL中支持任何数据的四则运算,那么我就可以使用simpleStmt和四则运算符号组成四则运算

expression:
simpleStmt #SimpleExpression
|expression op = (MUL|DIV) expression #MulDiv
|expression op = (ADD|SUB) expression #AddSub
;

这时候我们就定义了支持四则运算的语法规则,我们来试一下语法定义的对不对。
image
发现我们输入的加法运算和乘法运算都可以被解析,说明我们的语法定义正确。接下来我们添加比较运算

我定义的DLS支持所有数据做比较运算,那么我直接在上面的expression中添加比较运算就可以了,这里需要注意的是比较运算如果希望有优先级,需要先定义优先级高的比较符号,我这里没有优先级操作,所以都是平级的。

添加比较运算符号

expression:
simpleStmt #SimpleExpression
|expression op = (MUL|DIV) expression #MulDiv
|expression op = (ADD|SUB) expression #AddSub
|expression op = (EQ|NE|LT|LE|GT|GE) expression #Compare
;

验证一下比较运算语法定义的是否正确。
image
发现没有错误,正确解析出树就代表语法定义的正确。接下来大家可以自己构思一下剩下的语法规则,或者添加自己的语法规则了。大概思路就是先想一个语法希望是什么样,然后编写语法规则,然后输入希望的格式验证语法规则。

编写Listener

还是老样子,编写号语法文件,我们执行Antlr4生成运行时语言为Go的命令:
java -jar 'C:\Program Files\Java\antlr\antlr-4.12.0-complete.jar' -Dlanguage=Go -no-visitor -package parser *.g4
编写监听器类

type CalcListener struct{
	*parser.BaseCalcListener //继承Listener基类
	*antlr.DefaultErrorListener //继承错误基类
}

//发生错误时,处理错误
func (l *CalcLister) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {

}

//退出MulDiv语法时
func (l *CalcLister) ExitMulDiv(c *parser.MulDivContext) {

}
//退出AddSub语法时
func (l *CalcLister) ExitAddSub(c *parser.AddSubContext) {

}
//退出数字语法时
func (l *CalcLister) ExitNumber(c *parser.NumberContext) {

}

这里细心的小伙伴已经发现,在语法文件中使用“#”指定的节点名称在监听器中回生成一个节点方法,在Antlr4中,“#”号代表手动指定语法规则名称,需要注意的是,不要跟Token和规则名称重复。

遍历语法树

image
Antlr4遍历语法树时,使用DFS方式遍历树

监听模式和访问模式

Antlr4提供了两种遍历语法树的方式,监听模式和访问模式,默认是监听模式,如果希望使用访问模式的话,需要修改命令:
java -jar 'C:\Program Files\Java\antlr\antlr-4.12.0-complete.jar' -Dlanguage=Go -visitor -package parser *.g4
这样会生成访问者模式和监听者模式

calc_base_listener.go //监听者模式基类文件
calc_base_visitor.go //访问者模式基类文件

访问者模式:先遍历父节点,然后遍历子节点
监听者模式:Enter先进入父节点,Exit最后退出父节点
个人建议还是使用监听者模式,在Enter控制子节点访问,Exit做父节点子树执行逻辑。访问者模式控制能力更强,监听者模式需要遍历整个树。

至此,使用golang+Antlr4就可以定义一个属于自己的语法规则的解析器了,如果有哪里不同的可以给小编留言,我们共同学习!!!

标签:解析器,完结篇,运算,四则运算,模式,golang,Antlr4,语法,expression
From: https://www.cnblogs.com/thirteenAnimation/p/17265163.html

相关文章

  • 05 Golang 流程控制
    一、条件判断1.条件判断简介条件语句是用来判断给定的条件是否满足(表达式值是否为true或者false),并根据判断的结果决定执行情况的语句。go语言中的条件语句主要包含如......
  • windows系统下golang安装教程
    go下载软件地址:https://studygolang.com/dl/golang/go1.19.5.windows-amd64.msiwindow安装软件,点下一步下一步安装即可记得有一步是将go加入系统环境变量,需要点击一下。......
  • linux系统下golang安装教程
     Linux下安装Golang系统:centos7.8mkdir/home/srcwgethttps://golang.google.cn/dl/go1.19.5.linux-amd64.tar.gz解压tar-xf go1.19.5.linux-amd64.tar.gz  ......
  • golang 实现的零依赖、高性能、并发 mysqldump 工具。
    mysqldumpgolang中实现的零依赖、高性能、并发mysqldump工具。项目地址:https://github.com/dengjiawen8955/mysqldump/blob/master/README-zh.md文章地址:https:/......
  • 【golang实现即时通讯系统】(一)
    即时通讯系统1.基础server构建创建一个Server的结构体,结构体应该包含服务端的IP和端口写一个创建Server的方法创建一个启动Server函数创建一个业务链接函数serve......
  • golang pprof 监控系列(1) —— go trace 统计原理与使用
    golangpprof监控系列(1)——gotrace统计原理与使用服务监控系列文章服务监控系列视频关于gotooltrace的使用,网上有相当多的资料,但拿我之前初学golang的经验来......
  • golang相关介绍
    前言:golang的语言介绍,发展介绍,相关网站正文:golang介绍Go语言(或Golang)起源于2007年,并在2009年正式对外发布。是由Google公司开发的一种静态强类型、编译型、并发......
  • (转)golang beego后端开发框架(二):配置、路由和控制器
    原文:https://www.dianjilingqu.com/178381.html1.beego参数配置beego目前支持INI、XML、JSON、YAML格式的配置文件解析,但是默认采用了INI格式解析,用户可以通过简单的配......
  • golang 异常捕获和处理(panic/recover)
    1.异常处理Golang没有结构化异常,使用panic抛出错误,recover捕获错误。异常的使用场景简单描述:Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后......
  • ElasticSearch 实现分词全文检索 - SpringBoot 完整实现 Demo 附源码【完结篇】
    可以先看下列文章目录ElasticSearch实现分词全文检索-概述ElasticSearch实现分词全文检索-ES、Kibana、IK安装ElasticSearch实现分词全文检索-Restful基本操......