1

I'm writing the ANTLR to create my query syntax, so the script bellows should be right and pass:

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

And these should return a syntax error:

* 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

So, I create my 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 ;

All that should pass is working, however, there are these three that should return an error, but it doesn't.

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
Otávio Santana
  • 318
  • 2
  • 12

1 Answers1

2

If you don't anchor your query rule by matching EOF at the end, it can match prefixes of the input and then leave the rest in the input stream.

So for the input select * from Person start, your query rule will parse select * from Person and then leave start in the input stream.

To prevent this, just add EOF at the end:

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

PS: It is pretty uncommon to have keywords with spaces in them (like 'start at' and 'order by'). Instead I would recommend turning those into two keywords each (i.e. 'start' 'at' and 'order' 'by'). That way an arbitrary amount of white space will be allowed between each word, instead of requiring exactly one space.

sepp2k
  • 363,768
  • 54
  • 674
  • 675