mysql - 使用ANTLR4解析SQL CREATE TABLE语句

标签 mysql parsing antlr4

Lexer文件代码如下:

lexer grammar CreateLexer;

CREATE
   : 'create' | 'CREATE'
   ;

NUMBER_OF_SHARDS:'number_of_shards' | 'NUMBER_OF_SHARDS';


NUMBER_OF_REPLICAS:'number_of_replicas' | 'NUMBER_OF_REPLICAS';


ID
  : ( 'a' .. 'z' | 'A' .. 'Z' | '_' | '\u4e00' .. '\u9fa5' | '-')+
  ;


INT
  : [0-9]+
  ;


NEWLINE
  : '\r'? '\n' -> skip
  ;


WS
  : [\t\r\n]+ -> skip
  ;


INDEX
  : 'index' | 'INDEX'
  ;

TABLE:'table';

解析器文件代码也如下:

parser grammar CreateParser;

options
   { tokenVocab = CreateLexer; }
stat
   : create_clause
   ;

create_clause
   : CREATE INDEX index_name shards? replicas?
   ;

index_name
   : (ID)*(INT)*
   ;

shards
   : NUMBER_OF_SHARDS INT
   ;

replicas
   : NUMBER_OF_REPLICAS INT
   ;

这是我的测试代码演示了我如何使用上面的模块:

String sql = "create index A number_of_shards 1 number_of_replicas 1";
CreateLexer createLexer = new CreateLexer(new ANTLRInputStream(sql));
createLexer.removeErrorListeners();

CreateParser parser = new CreateParser(new CommonTokenStream(createLexer));
ParseTree tree = parser.stat();
System.out.println(tree.toStringTree(parser));

当我运行上面的测试代码时,出现错误:

line 1:7 missing INDEX at 'index'
(stat (create_clause create <missing INDEX> (index_name index A) (shards number_of_shards 1) (replicas number_of_replicas 1)))

在我将paser文件中的“create_clause”处的“INDEX”替换为“TABLE”,并在测试代码中将“index”替换为“table”后,如下所示:

测试代码:

String sql = "create table A number_of_shards 1 number_of_replicas 1";

帕瑟文件:

create_clause
   : CREATE TABLE index_name shards? replicas?
   ;

我再次运行它,仍然出现相同的错误:

line 1:7 missing 'table' at 'table'
(stat (create_clause create <missing 'table'> (index_name table A) (shards number_of_shards 1) (replicas number_of_replicas 1)))

但是,当我删除解析器文件中的关键字 TABLE 后,如下所示:

create_clause
   : CREATE index_name shards? replicas?
   ;

奇怪的事情发生了,我没有收到错误:

(stat (create_clause create (index_name table A) (shards number_of_shards 1) (replicas number_of_replicas 1)))

谁能告诉我为什么像“CREATE TABLE”这样的SQL语句无法解析?我错过了什么吗?提前致谢!

最佳答案

Antlr 通常首先根据文本匹配长度来匹配词法分析器规则,然后根据语法中的顺序进行匹配。因此,您的 INDEXTABLE 规则永远不会匹配。相反,文本以 ID 标记呈现。

通过删除对显式 INDEX token 的要求,您消除了错误的原因。

作为一般规则,始终转储 token 流,以便您可以看到词法分析器实际在做什么。

关于mysql - 使用ANTLR4解析SQL CREATE TABLE语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38551119/

相关文章:

java - 解析java源文件,然后使用ANTLR4修改原始源

python - 整数在SQlite中记录良好,但在MySQL中记录为0

c - 解析读入文件并将其存储在二叉树中

go - 如何在 antlr 的 go target 中编写自定义错误报告器

c# - 解析字符串输入 C#

jQuery 在多个级别上解析 JSON

antlr - 简单 antlr4 语法中的不匹配输入错误

linux - Unix 中 mysql 的自动备份脚本

mySQL - 我应该反规范化吗?

mysql - SQL NOT IN 结果不符合预期