在ANTLR 4中写入顺序不是可选的

时间:2018-05-22 18:54:56

标签: java antlr antlr4

我正在编写ANTLR以创建我的查询语法,因此脚本波纹管应该正确并通过:

select * from Person
select name,age from Person
select _id,name,age from Person
select  name,age,adress.age from Person
select name , age from Person
select  name, age ,adress.age from Person
select  name, age ,adress.age from Person order by name
select  name, age ,adress.age from Person order by name asc
select  name, age ,adress.age from Person order by name desc
select  name, age ,adress.age from Person order by name asc age asc
select  name, age ,adress.age from Person order by name desc age
select  name, age ,adress.age from Person order by name desc age desc
select  name, age ,adress.age from Person
select  * from Person start 10
select  name, age ,adress.age from Person start 20 order by name desc 
age desc
select  name, age ,adress.age from Person start 20 limit 10 order by 
name desc age desc
select  name, age ,adress.age from Person limit 10 order by name desc 
age desc

这些应该返回语法错误:

* from Person
select *, name from Person
select name, *
select name,
select name from *
select  * from Person order by
select  * from Person order by asc
select  * from Person order by asc age
select  * from Person start
select  name, age ,adress.age from Person order by name desc age desc 
start 20
select  name, age ,adress.age from Person limit qwe  start 12 order by 
name desc age desc
select  name, age ,adress.age from Person start -20 limit 5 order by 
name desc age desc
select  name, age ,adress.age from Person limit order by name desc age 
desc

所以,我创建了我的Select.g4

grammar Select;
query   : 'select' fields 'from' entity start? limit? order_clause?;


fields: star | name (',' name)*;
star: '*';
order_clause: 'order by' order_name (',' order_name)*;
order_name: name | name 'asc' | name 'desc';
start: 'start at' INT;
limit: 'limit' INT;
name: ANY_NAME;
entity: ANY_NAME;
INT: [0-9]+;
ANY_NAME: [a-zA-Z_.] [a-zA-Z._0-9]*;
WS  : [ \t\r\n]+ -> skip ;

所有应该通过的都是有效的,但是,这三个应该返回错误,但它没有。

select  * from Person start
select  name, age ,adress.age from Person order by name desc age desc 
start 20
select  name, age ,adress.age from Person start -20 limit 5 order by 
name desc age desc//cannot be a negative number

1 个答案:

答案 0 :(得分:2)

如果您不是通过在末尾匹配query来锚定EOF规则,则可以匹配输入的前缀,然后将其余内容保留在输入流中。

因此,对于输入select * from Person start,您的query规则将解析select * from Person,然后在输入流中保留start

要防止这种情况发生,请在最后添加EOF

query   : 'select' fields 'from' entity start? limit? order_clause? EOF;

PS:让关键字中包含空格(例如'start at''order by')非常罕见。相反,我建议将其分为两个关键字(即'start' 'at''order' 'by')。这样,每个单词之间允许任意数量的空格,而不是只需要一个空格。