如何使用ANTLRv4解析来自日志文件和网络协议的sql查询
我需要解析可以使用网络协议(例如MySQL协议)提交或存储在日志文件中的SQL查询 我基于ANTLRv4构建了一个解析器 以下文本在此语法中有效:如何使用ANTLRv4解析来自日志文件和网络协议的sql查询,sql,parsing,antlr4,Sql,Parsing,Antlr4,我需要解析可以使用网络协议(例如MySQL协议)提交或存储在日志文件中的SQL查询 我基于ANTLRv4构建了一个解析器 以下文本在此语法中有效: select 1 select 2 select 3 选择1选择2选择3 同时,它们对于网络协议应该无效,因为xSQL服务器将删除\n,并且最终查询将等于select 1 select 2 select 3 是否有可能创建一个同时处理这两种情况的语法?或者我应该创建并支持两个语法:第一个语法用于解析日志,第二个语法用于解析网络查询? 我可以用语义谓
select 1
select 2
select 3
选择1选择2选择3
同时,它们对于网络协议应该无效,因为xSQL服务器将删除\n
,并且最终查询将等于select 1 select 2 select 3
是否有可能创建一个同时处理这两种情况的语法?或者我应该创建并支持两个语法:第一个语法用于解析日志,第二个语法用于解析网络查询?
我可以用语义谓词来解决这个问题吗?我想出了两种方法:
- 在语法中使用代码片段:
- Delcare
标记位于textMode
部分@lexer::members
- 将
令牌替换为以下令牌:SPACE
ANTLR 空白:[\t]->通道(隐藏); 换行符:'\r'?'\不 {if(文本模式) 通道(隐藏); 其他的 AddParseError(); }
- 检查无语法修改的标记:
- 标记化导入。在此步骤之后,我们有以下令牌:
选择WS()编号(1)WS(\n)选择WS()编号(2)WS(\n)选择WS()编号(2)WS(\n)
- 循环标记并对每个标记执行以下操作:
- 如果激活了“文本模式”,只需忽略隐藏标记(空格和换行符)
在这一步之后,我们有以下标记:
,它传递给解析器selectnumber(1)selectnumber(2)selectnumber(2)
- 如果激活了“网络协议模式”,请在带有换行符值的
令牌上添加自定义错误(WS
或\r
)\n
- 如果激活了“文本模式”,只需忽略隐藏标记(空格和换行符)
在这一步之后,我们有以下标记:
您可以使两个语法中的所有内容都相同,然后使用
import
构造只包含不同的部分。我在医疗HL7文件中使用过这种方法,它使用并重用了许多公共段。这两种方法都不能解决主要问题:select 1 select 2 select 3
将被解析为有效查询,但它不是真的。