我的编程空间,编程开发者的网络收藏夹
学习永远不晚

golang怎么整合antlr语法校验

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

golang怎么整合antlr语法校验

本篇内容介绍了“golang怎么整合antlr语法校验”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1. 背景

在项目中我们可能会遇到表达式检索的场景,例如,输入以下表达式检索,需要解析表达式并得到检索结果。

ip="192.168.1.3" && (port="80" || protocol="http")

此时,我们需要对语法进行校验、解析,应当如何做呢?

下面给大家推荐一种使用语法校验工具Antlr

Antlr是一个语法分析器,本身是用java实现的,然是Runtime的库也支持Golang、Java、Python等。

2. goland安装antlr插件

打开goland,File --> Settings --> Plugins, 搜索antlr,安装 antlr4

golang怎么整合antlr语法校验

插件安装完成后,可以看到ANTLR Preview窗口,一会我们可以在这个窗口进行简单的语法校验。

golang怎么整合antlr语法校验

3. 编写语法校验规则

创建工程,引入包

go get -u github.com/antlr/antlr4/runtime/Go/antlr/v4

在工程中新建一个antlr目录,创建一个后缀名为 .g4 的文件,作为规则文件。此处我们创建Rule.g4

// 定义语法名称,需要和文件名匹配grammar Rule;// DECIMAL, IDENTIFIER, COMMENTS, WS are set using regular expressions// key 为表达式中可支持的检索字段,可以是固定值(每个值中间用 | 隔开,是”或“的意思),也可以是正则表达式// value 使用正则表达式KEY : 'ip' | 'port' | 'protocol';//VALUE :'"' ( '""' | ~["\r\n] )* '"' ;//KEY : ('A' .. 'Z' | 'a' .. 'z' |  '_') + ;VALUE :'"' ( '\\"' | ~["] )* '"' ;// COMMENT and WS are stripped from the output token stream by sending// to a different channel 'skip'COMMENT : '//' .+? ('\n'|EOF) -> skip ;WS : [ \r\t\u000C\n]+ -> skip ;// 语法校验的入口start : logicalExpr* EOF;// 语法支持的结构logicalExpr    : comparisonExpr // 示例: key == value 表示支持 == 和 != 的表达式    | logicalExpr operator logicalExpr // 示例: key1 == value1 && key2 != value2 表示支持 && 和 || 运算符连接表达式    | lparen logicalExpr rparen // 示例: (key1 == value1 && key2 != value2) 表示支持 () 连接表达式    ;comparisonExpr    : KEY compare VALUE    ;compare    : '='    | '!='    ;operator    : '&&'    | '||'    ;lparen    :  '('    ;rparen    :  ')'    ;

初始化校验语法

选中Rule.g4 文件,鼠标右键,选择 Configure ANTLR Tool…

配置输出路径,和Rule.g4 同目录;配置语言,使用Go

golang怎么整合antlr语法校验

选中Rule.g4 文件,鼠标右键,选择 Generate ANTLR Recognizer,完成规则初始化

golang怎么整合antlr语法校验

树状图校验

golang怎么整合antlr语法校验

4. 语法校验

自定义listener

package parserimport ("github.com/antlr/antlr4/runtime/Go/antlr/v4""strings")type MyRuleListener struct {*BaseRuleListenerQueue    []interface{}QueueStr []string}// 注意:方法名必须是这个名字func (s *MyRuleListener) EnterComparisonExpr(ctx *ComparisonExprContext) {key := ctx.GetChild(0).(antlr.ParseTree).GetText()operator := ctx.GetChild(1).(antlr.ParseTree).GetText()value := ctx.GetChild(2).(antlr.ParseTree).GetText()if strings.HasPrefix(value, "\"") {value = value[1:]}if strings.HasSuffix(value, "\"") {value = value[:len(value)-1]}keyValue := map[string]string{}keyValue["key"] = keykeyValue["operator"] = operatorkeyValue["value"] = values.PushStr(ctx.GetText())s.Push(keyValue)}// EnterKeyValue is called when production KeyValue is entered.func (s *MyRuleListener) ExitOperator(ctx *OperatorContext) {s.Push(ctx.GetText())s.PushStr(ctx.GetText())}// EnterKeyValue is called when production KeyValue is entered.func (s *MyRuleListener) ExitLparen(ctx *LparenContext) {s.Push(ctx.GetText())s.PushStr(ctx.GetText())}// EnterKeyValue is called when production KeyValue is entered.func (s *MyRuleListener) ExitRparen(ctx *RparenContext) {s.Push(ctx.GetText())s.PushStr(ctx.GetText())}func (s *MyRuleListener) Push(i interface{}) {s.Queue = append(s.Queue, i)}func (s *MyRuleListener) PushStr(i string) {s.QueueStr = append(s.QueueStr, i)}

获取解析异常的错误信息

package parserimport "github.com/antlr/antlr4/runtime/Go/antlr/v4"type RuleErrorListener struct {antlr.ErrorListenerMsg string}func (l *RuleErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {l.Msg = msg}

校验

package mainimport (parser "antlr-demo/antlr""errors""fmt""github.com/antlr/antlr4/runtime/Go/antlr/v4")func main() {expre := "ip=\"192.168.1.3\" && (port=\"80\" || protocol=\"http\")"err := checkExpre(expre)if err != nil {fmt.Println(err)}}func checkExpre(expre string) error {input := antlr.NewInputStream(expre)var lexerErr parser.RuleErrorListenerlexer := parser.NewRuleLexer(input)lexer.AddErrorListener(&lexerErr)stream := antlr.NewCommonTokenStream(lexer, 0)ruleParser := parser.NewRuleParser(stream)ruleParser.BuildParseTrees = truevar ruleErr parser.RuleErrorListenerruleParser.AddErrorListener(&ruleErr)tree := ruleParser.Start()listener := new(parser.MyRuleListener)antlr.ParseTreeWalkerDefault.Walk(listener, tree)if lexerErr.Msg != "" || ruleErr.Msg != "" {return errors.New("输入的语法不正确")}expreList := listener.QueueStrfmt.Println("expreList--->", expreList)expreMap := listener.Queuefmt.Println("expreMap--->", expreMap)return nil}

结果验证

正确表达式

golang怎么整合antlr语法校验

key不在支持的语法内

golang怎么整合antlr语法校验

缺少key

golang怎么整合antlr语法校验

运算符不在支持的语法内

golang怎么整合antlr语法校验

缺少括号

golang怎么整合antlr语法校验

“golang怎么整合antlr语法校验”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

golang怎么整合antlr语法校验

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

golang怎么整合antlr语法校验

本篇内容介绍了“golang怎么整合antlr语法校验”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. 背景在项目中我们可能会遇到表达式检
2023-07-05

golang整合antlr语法校验解析

Antlr是一个语法分析器,本身是用java实现的,然是Runtime的库也支持Golang、Java、Python等,本文给大家讲解使用golang整合antlr进行语法解析,感兴趣的朋友一起看看吧
2023-02-28

怎么使用Java校验SQL语句的合法性

这篇文章主要介绍“怎么使用Java校验SQL语句的合法性”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Java校验SQL语句的合法性”文章能帮助大家解决问题。方案一:使用JDBC API中提
2023-07-05

Springboot整合Shiro怎么实现登录与权限校验

这篇文章主要介绍“Springboot整合Shiro怎么实现登录与权限校验”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Springboot整合Shiro怎么实现登录与权限校验”文章能帮助大家解决问
2023-06-30

怎么通过自定义spring invalidator注解校验数据合法性

今天小编给大家分享一下怎么通过自定义spring invalidator注解校验数据合法性的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来
2023-07-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录