grammar EQL; @parser::members { @Override public void reportError(RecognitionException e) { throw new RuntimeException("Error in grammer - " + e.getMessage()); } } @lexer::members { @Override public void reportError(RecognitionException e) { throw new RuntimeException("Error in grammer - " + e.getMessage()); } } select_statement : select_clause? fetch_clause* where_clause? orderby_clause? limit_clause? ; select_clause : 'select' distinct? '(' fetch_property_group ')' ; distinct : 'distinct' ; fetch_clause : fetch_path ; where_clause : 'where' conditional_expression ; orderby_clause : 'order' 'by' orderby_property (',' orderby_property)* ; orderby_property : PATH_VARIABLE asc_desc? nulls_firstlast? ; nulls_firstlast : 'nulls' 'first' | 'nulls' 'last' ; asc_desc : 'asc' | 'desc' ; limit_clause : 'limit' NUMBER_LITERAL offset_clause? ; offset_clause : 'offset' NUMBER_LITERAL ; fetch_path : 'fetch' fetch_option? PATH_VARIABLE fetch_property_set? ; fetch_property_set : '(' fetch_property_group ')' ; fetch_property_group : fetch_property (',' fetch_property)* ; fetch_property : PATH_VARIABLE | fetch_query_hint | fetch_lazy_hint ; fetch_query_hint : '+' fetch_query_option ; fetch_lazy_hint : '+' fetch_lazy_option ; fetch_option : fetch_query_option | fetch_lazy_option ; fetch_query_option : 'query' fetch_batch_size? ; fetch_lazy_option : 'lazy' fetch_batch_size? ; fetch_batch_size : '(' NUMBER_LITERAL ')' ; conditional_expression : conditional_term ('or' conditional_term)* ; conditional_term : conditional_factor ('and' conditional_factor)* ; conditional_factor : 'not'? conditional_primary ; conditional_primary : any_expression | '(' conditional_expression ')' ; any_expression : comparison_expression | like_expression | between_expression | propertyBetween_expression | in_expression | isNull_expression | isNotNull_expression | isEmpty_expression | isNotEmpty_expression | '(' any_expression ')' ; in_expression : PATH_VARIABLE 'in' in_value ; in_value : INPUT_VARIABLE | '(' value_expression (',' value_expression)* ')' ; between_expression : PATH_VARIABLE 'between' value_expression 'and' value_expression ; propertyBetween_expression : value_expression 'between' PATH_VARIABLE 'and' PATH_VARIABLE ; isNull_expression : PATH_VARIABLE 'is' 'null' | PATH_VARIABLE 'isNull' ; isNotNull_expression : PATH_VARIABLE 'is' 'not' 'null' | PATH_VARIABLE 'isNotNull' | PATH_VARIABLE 'notNull' ; isEmpty_expression : PATH_VARIABLE 'is' 'empty' | PATH_VARIABLE 'isEmpty' ; isNotEmpty_expression : PATH_VARIABLE 'is' 'not' 'empty' | PATH_VARIABLE 'isNotEmpty' | PATH_VARIABLE 'notEmpty' ; like_expression : PATH_VARIABLE like_op value_expression ; like_op : 'like' | 'ilike' | 'contains' | 'icontains' | 'startsWith' | 'istartsWith' | 'endsWith' | 'iendsWith' ; comparison_expression : PATH_VARIABLE comparison_operator value_expression | value_expression comparison_operator PATH_VARIABLE ; comparison_operator : '=' | 'eq' | '>' | 'gt' | '>=' | 'ge' | 'gte' | '<' | 'lt' | '<=' | 'le' | 'lte' | '<>' | '!=' | 'ne' | 'ieq' ; value_expression : literal | INPUT_VARIABLE ; literal : STRING_LITERAL | BOOLEAN_LITERAL | NUMBER_LITERAL ; INPUT_VARIABLE : ':' ('a' .. 'z' | 'A' .. 'Z' | '_') ('a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_')* ; PATH_VARIABLE : ('a' .. 'z' | 'A' .. 'Z' | '_') ('a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' | '.')* ; BOOLEAN_LITERAL : 'true' | 'false' ; NUMBER_LITERAL : '-'? DOUBLE | '-'? INT | ZERO ; DOUBLE : [0-9]+ '.' [0-9]*; INT : [1-9] [0-9]*; ZERO : '0'; STRING_LITERAL : '\'' ( ~'\'' | '\'\'' )* '\'' ; WS : [ \t\r\n] -> skip ;