如何使用ANTLRv4从日志文件和网络协议中解析SQL查询

时间:2017-05-23 04:54:57

标签: sql parsing antlr4

我需要解析可以使用网络协议(例如MySQL协议)提交或存储在日志文件中的SQL查询。

我构建了一个基于ANTLRv4 Tsql grammar的解析器。

以下文字在此语法中有效:

select 1
select 2
select 3

select 1 select 2 select 3

同时,它们不应对网络协议有效,因为xSQL-server将删除\n,最终查询将等于select 1 select 2 select 3

是否可以创建一个可以处理这两种情况的语法?或者我应该创建和支持两个语法:第一个解析日志的语法,第二个解析网络查询? 我可以使用语义谓词来解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

我提出了两种方法:

  • 在语法中使用代码片段:
    1. textMode部分的Delcare @lexer::members旗帜。
    2. SPACE令牌替换为以下内容: ANTLR Whitespace: [ \t] -> channel(HIDDEN); Linebreak: '\r'? '\n' { if (textMode) channel(HIDDEN); else AddParseError(); }
  • 检查令牌而不进行语法修改:
    1. Tokenize导入。完成此步骤后,我们将拥有以下令牌: SELECT WS( ) NUMBER(1) WS(\n) SELECT WS( ) NUMBER(2) WS(\n) SELECT WS( ) NUMBER(2) WS(\n)
    2. 遍历令牌并为每个令牌执行操作:
      • 如果"文字模式"激活只是忽略HIDDEN TOKENS(空格和换行符) 完成此步骤后,我们将使用以下标记:SELECT NUMBER(1) SELECT NUMBER(2) SELECT NUMBER(2)传递给解析器。
      • 如果"网络协议模式"已激活使用换行符值WS\r\n令牌上添加自定义错误。

答案 1 :(得分:0)

你在帖子的最后提出三个问题,但我只提供一个对我有用的答案:只需创建两个语法。它没有听起来那么糟糕,可以澄清事情。

您可以使两个语法中的所有内容相同,然后仅包含import <mysegment>构造的不同部分。我已将此方法用于医疗HL7文件,该文件使用并重用了许多常见的段。