Antlr告诉我NoViableAltException,我很无能为力

时间:2012-08-07 20:24:51

标签: antlr dsl parser-generator

我目前正在研究一种接受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的专家,但这也意味着我不知道我在这里做错了什么。

有人可以帮我吗?

干杯

1 个答案:

答案 0 :(得分:1)

AND被标记为ID,因为匹配最长输入片段的第一个词法分析器规则获胜。

所以你应该在ID之前定义BooleanOperator。