Написать в заказ не обязательно в ANTLR 4 - PullRequest
0 голосов
/ 22 мая 2018

Я пишу 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 голосов
/ 22 мая 2018

Если вы не привязываете свое правило 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').Таким образом, между каждым словом будет разрешено произвольное количество пробелов, вместо того, чтобы требовать ровно один пробел.

...