我目前正在研究一种接受sql语句的ANTLR语法。我想使用这个语法允许程序员创建mysql查询,应用程序将自动将查询更改为所需数据库的正确格式。
例如,如果在查询中使用LIMIT 0,5,它会自动将此查询转换为mssql的正确格式
到目前为止这是我的语法
grammar sql2;
query
: select ';'? EOF
;
select
: 'SELECT' top? select_exp 'FROM' table ('WHERE' compare_exp)? limit?
;
compare_exp
: field CompareOperator param (BooleanOperator compare_exp)?
;
param
: '@' ID
;
top
: 'TOP' INT
;
limit
: 'LIMIT' INT (',' INT)?
;
select_exp
: field (',' select_exp)?
;
table
: '`' ID '`' ('.`' ID '`')?
| ID ('.' ID)?
;
field
: table
;
ID : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
CompareOperator
: ( '=' | '<>' )
;
BooleanOperator
: ('AND' | 'OR')
;
INT : '0'..'9'+
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
如果我用输入
进行测试SELECT TOP 5 bla_asdf, bal, lab FROM `x`.`y` WHERE xdf = @tf AND bla = @b LIMIT 0, 5
它停止在AND bla = @b解析我的查询,此时它给了我一个NoViableAltException ... 如果我输入
SELECT TOP 5 bla_asdf, bal, lab FROM `x`.`y` WHERE xdf = @tf LIMIT 0, 5
它不会给我任何问题。
我绝对不是ANTLR的专家,但这也意味着我不知道我在这里做错了什么。
有人可以帮我吗?
干杯
答案 0 :(得分:1)
AND被标记为ID,因为匹配最长输入片段的第一个词法分析器规则获胜。
所以你应该在ID之前定义BooleanOperator。