使用 ANTLR4 解析 SQL CREATE TABLE 语句
Parsing SQL CREATE TABLE statement using 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文件代码也如下:
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'处用'TABLE'替换了'INDEX',并在测试代码中用'table'替换了'index'之后:
测试码:
String sql = "create table A number_of_shards 1 number_of_replicas 1";
paser 文件:
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)))
谁能告诉我为什么 SQL 像 'CREATE TABLE' 这样的语句无法解析?我想念什么吗?提前致谢!
Antlr 通常首先根据文本匹配长度匹配词法分析器规则,然后根据语法中的顺序匹配词法分析器规则。因此,您的 INDEX
和 TABLE
规则将永远不会匹配。相反,文本以 ID
个标记呈现。
通过删除对显式 INDEX
标记的要求,您消除了错误的原因。
作为一般规则,始终转储令牌流,以便您可以看到词法分析器实际在做什么。
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文件代码也如下:
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'处用'TABLE'替换了'INDEX',并在测试代码中用'table'替换了'index'之后:
测试码:
String sql = "create table A number_of_shards 1 number_of_replicas 1";
paser 文件:
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)))
谁能告诉我为什么 SQL 像 'CREATE TABLE' 这样的语句无法解析?我想念什么吗?提前致谢!
Antlr 通常首先根据文本匹配长度匹配词法分析器规则,然后根据语法中的顺序匹配词法分析器规则。因此,您的 INDEX
和 TABLE
规则将永远不会匹配。相反,文本以 ID
个标记呈现。
通过删除对显式 INDEX
标记的要求,您消除了错误的原因。
作为一般规则,始终转储令牌流,以便您可以看到词法分析器实际在做什么。