org.geolatte.common.cql.cql.grammar Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of geolatte-common Show documentation
Show all versions of geolatte-common Show documentation
This GeoLatte-common library contains the transformer framework and other common classes used by other
GeoLatte modules.
Package org.geolatte.common.cql;
Helpers
/* These are not defined in CQL */
tab = 9;
cr = 13;
lf = 10;
eol = cr lf | cr | lf;
blank = (' ' | tab | eol)+;
all = [0 .. 0xFFFF];
simple_latin_upper_case_letter = 'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z';
simple_latin_lower_case_letter = 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z';
simple_latin_letter = simple_latin_upper_case_letter | simple_latin_lower_case_letter;
/* Case insensitive letters */
a = 'a' | 'A';
b = 'b' | 'B';
c = 'c' | 'C';
d = 'd' | 'D';
e = 'e' | 'E';
f = 'f' | 'F';
g = 'g' | 'G';
h = 'h' | 'H';
i = 'i' | 'I';
j = 'j' | 'J';
k = 'k' | 'K';
l = 'l' | 'L';
m = 'm' | 'M';
n = 'n' | 'N';
o = 'o' | 'O';
p = 'p' | 'P';
q = 'q' | 'Q';
r = 'r' | 'R';
s = 's' | 'S';
t = 't' | 'T';
u = 'u' | 'U';
v = 'v' | 'V';
w = 'w' | 'W';
x = 'x' | 'X';
y = 'y' | 'Y';
z = 'z' | 'Z';
digit = '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9';
space = ' ';
doublequote = '"';
quote = ''';
asterisk = '*';
comma = ',';
hyphen = '-';
colon = ':';
plus_sign = '+';
minus_sign = '-';
sign = plus_sign | minus_sign;
underscore = '_';
nonquotecharacter = [all - quote];
quotesymbol = quote quote;
datetimeseparator = 'T';
timespanseparator = '/';
durationsymbol = 'P';
geometry_allowed_symbol = '(' | ' ' | digit | ')';
States /* We use states because we don't want to parse wkt strings directly. We need to tokenize them manually via a Lexer extension. */
normal, wkt;
Tokens /* Terminals */
/* WKT markers */ /* Place these tokens in front, otherwise they are not recognized. Not sure why but probably another token matches */
{normal->wkt, wkt} wkt_point_literal = p o i n t;
{normal->wkt, wkt} wkt_line_string_literal = l i n e s t r i n g;
{normal->wkt, wkt} wkt_polygon_literal = p o l y g o n;
//{normal->wkt, wkt} wkt_polyhedral_surface_literal = p o l y h e d r a l s u r f a c e;
//{normal->wkt, wkt} wkt_triangle_literal = t r i a n g l e;
//{normal->wkt, wkt} wkt_tin_literal = t i n;
{normal->wkt, wkt} wkt_multi_point_literal = m u l t i p o i n t;
{normal->wkt, wkt} wkt_multi_line_string_literal = m u l t i l i n e s t r i n g;
{normal->wkt, wkt} wkt_multi_polygon_literal = m u l t i p o l y g o n;
{normal->wkt, wkt} wkt_geometry_collection_literal = g e o m e t r y c o l l e c t i o n;
{normal->wkt, wkt} wkt_empty_set_literal = e m p t y;
blank = blank;
space = space;
newline = eol;
sign = sign;
left_paren = '(';
right_paren = ')';
period = '.';
colon = colon;
comma = comma;
/* COMPARISON OPERATORS */
{normal} less_than_operator = '<';
{normal} equals_operator = '=';
{normal} greater_than_operator = '>';
{normal} not_equals_operator = '<>';
{normal} greater_than_or_equals_operator = '>=';
{normal} less_than_or_equals_operator = '<=';
/* BOOLEAN OPERATORS */
{normal} boolean_not_operator = n o t;
{normal} boolean_and_operator = a n d;
{normal} boolean_or_operator = o r;
/* TEXT OPERATORS */
{normal} text_like_operator = l i k e;
{normal} text_ilike_operator = i l i k e;
/* EXISTENCE OPERATORS */
{normal} exists_operator = e x i s t s;
{normal} doesnotexist_operator = d o e s '-' n o t '-' e x i s t;
/* TEMPORAL OPERATORS */
{normal} temporal_before_operator = b e f o r e;
{normal} temporal_beforeorduring_operator = b e f o r e space o r space d u r i n g;
{normal} temporal_during_operator = d u r i n g;
{normal} temporal_duringorafter_operator = d u r i n g space o r space a f t e r;
{normal} temporal_after_operator = a f t e r;
/* NULL OPERATORS */
{normal} null_is_operator = i s;
{normal} null_not_operator = n o t;
/* GEO OPERATORS */
{normal} geo_equals_operator = e q u a l s;
{normal} geo_disjoint_operator = d i s j o i n t;
{normal} geo_intersects_operator = i n t e r s e c t s;
{normal} geo_touches_operator = t o u c h e s;
{normal} geo_crosses_operator = c r o s s e s;
{normal} geo_within_operator = w i t h i n;
{normal} geo_contains_operator = c o n t a i n s;
{normal} geo_overlaps_operator = o v e r l a p s;
{normal} geo_relate_operator = r e l a t e;
{normal} relgeo_dwithin_operator = d w i t h i n;
{normal} relgeo_beyond_operator = b e y o n d;
/* BOOLEAN CONSTANTS */
{normal} boolean_true = t r u e;
{normal} boolean_false = f a l s e;
{normal} boolean_unknown = u n k n o w n;
/* NULL CONSTANT */
{normal} null_constant = n u l l;
signed_numeric_literal = sign? digit* '.'? digit+;
unsigned_integer = digit+;
{normal} character_string_literal = quote (nonquotecharacter | quotesymbol)+ quote;
// Not according to the spec for the moment, should allow things like 'A', 'abc', 'a23', 'a:b:c'
{normal} identifier = simple_latin_letter (simple_latin_letter | underscore | digit)*; // ::= | } ]
{normal} duration_date_time_separator = datetimeseparator;
{normal} duration_symbol = durationsymbol;
{normal} time_span_separator = timespanseparator;
{normal} datetime = digit digit digit digit hyphen digit digit hyphen digit digit datetimeseparator digit digit colon digit digit colon digit digit ('.' digit+)?;
//year_digits = ('19' | '20' | '21') digit digit; // 1900 -> 2199
//month_digits = '0'['1'-'9'] | '1'('0' | '1' | '2'); // 01 -> 12
//day_digits = ['0'-'2']['1'-'9'] | '3'('0' | '1'); // 01 -> 31
{normal} dur_day_symbol = 'D';
{normal} dur_month_symbol = 'M';
{normal} dur_year_symbol = 'Y';
{normal} dur_second_symbol = 'S';
{normal} dur_minute_symbol = 'M';
{normal} dur_hour_symbol = 'H';
Ignored Tokens
blank,
space,
newline;
Productions /* Non-terminals, precede a token by T and a production by P in case of ambiguity */
/* Query capabilities */
// ::=
search_condition {-> expr} =
boolean_value_expression {-> boolean_value_expression.expr};
// ::= | OR
boolean_value_expression {-> expr} =
{boolean_term} boolean_term {-> boolean_term.expr}
| {boolean_value_expression} [left]:boolean_value_expression boolean_or_operator [right]:boolean_term {-> New expr.or(left.expr, right.expr)};
// ::= | AND
boolean_term {-> expr} =
{boolean_primary} boolean_primary {-> boolean_primary.expr}
| {boolean_factor} boolean_factor {-> boolean_factor.expr}
| {boolean_term} [left]:boolean_term boolean_and_operator [right]:boolean_factor {-> New expr.and(left.expr, right.expr)};
// ::= [ NOT ]
boolean_factor {-> expr} =
{boolean_factor} [term]:boolean_primary {-> term.expr}
| {boolean_factor_not} boolean_not_operator [term]:boolean_primary {-> New expr.not(term.expr)};
// ::= | | |
boolean_primary {-> expr} =
{predicate} predicate {-> predicate.expr}
| {routine_invocation} routine_invocation {-> routine_invocation.expr}
| {nested_search_condition} left_paren search_condition right_paren {-> search_condition.expr};
routine_invocation {-> expr} =
geo_equals_operator left_paren [attr]:attribute_name comma geometry_literal right_paren {-> New expr.geo_equals(attr.attr, geometry_literal.geometry_literal)};
// ::= | | | | |
predicate {-> expr} =
{comparison_predicate} comparison_predicate {-> comparison_predicate.expr}
| {text_predicate} text_predicate {-> text_predicate.expr}
| {null_predicate} null_predicate {-> null_predicate.expr}
| {existence_predicate} existence_predicate {-> existence_predicate.expr}
| {temporal_predicate} temporal_predicate {-> temporal_predicate.expr};
comparison_predicate {-> expr} =
{equals} [attr]:attribute_name equals_operator [lit]:literal {-> New expr.eq(attr.attr, lit.literal)}
| {not_equals} [attr]:attribute_name not_equals_operator [lit]:literal {-> New expr.neq(attr.attr, lit.literal)}
| {less_than} [attr]:attribute_name less_than_operator [lit]:literal {-> New expr.lt(attr.attr, lit.literal)}
| {greater_than} [attr]:attribute_name greater_than_operator [lit]:literal {-> New expr.gt(attr.attr, lit.literal)}
| {less_than_or_equals} [attr]:attribute_name less_than_or_equals_operator [lit]:literal {-> New expr.lte(attr.attr, lit.literal)}
| {greater_than_or_equals} [attr]:attribute_name greater_than_or_equals_operator [lit]:literal {-> New expr.gte(attr.attr, lit.literal)};
null_predicate {-> expr} =
{isnull} [attr]:attribute_name null_is_operator null_constant {-> New expr.is_null(attr.attr)}
| {isnotnull} [attr]:attribute_name null_is_operator null_not_operator null_constant {-> New expr.is_not_null(attr.attr)};
// ::= [ NOT ] LIKE
text_predicate {-> expr} =
{like} [attr]:attribute_name text_like_operator [lit]:string_literal {-> New expr.like(attr.attr, lit)}
| {notlike} [attr]:attribute_name boolean_not_operator text_like_operator [lit]:string_literal {-> New expr.not_like(attr.attr, lit)}
| {ilike} [attr]:attribute_name text_ilike_operator [lit]:string_literal {-> New expr.ilike(attr.attr, lit)}
| {notilike} [attr]:attribute_name boolean_not_operator text_ilike_operator [lit]:string_literal {-> New expr.not_ilike(attr.attr, lit)};
existence_predicate {-> expr} =
{exists} [attr]:attribute_name exists_operator {-> New expr.exists(attr.attr)}
| {does_not_exist} [attr]:attribute_name doesnotexist_operator {-> New expr.does_not_exist(attr.attr)};
// ::= BEFORE | BEFORE OR DURING | DURING | DURING OR AFTER | AFTER
temporal_predicate {-> expr} =
{before} [attr]:attribute_name temporal_before_operator datetime_literal {-> New expr.before(attr.attr, datetime_literal.datetime_literal)}
| {after} [attr]:attribute_name temporal_after_operator datetime_literal {-> New expr.after(attr.attr, datetime_literal.datetime_literal)}
| {during} [attr]:attribute_name temporal_during_operator timespan_literal {-> New expr.during(attr.attr, timespan_literal.timespan_literal)}
| {before_or_during} [attr]:attribute_name temporal_beforeorduring_operator timespan_literal {-> New expr.before_or_during(attr.attr, timespan_literal.timespan_literal)}
| {during_or_after} [attr]:attribute_name temporal_duringorafter_operator timespan_literal {-> New expr.during_or_after(attr.attr, timespan_literal.timespan_literal)};
/* End query capabilities */
literal {-> literal} =
{num} numeric_literal {-> New literal.numeric(numeric_literal.numeric_literal)}
| {gen} general_literal {-> general_literal.literal};
general_literal {-> literal} =
{string} string_literal {-> New literal.string(string_literal.string_literal)}
| {date} datetime_literal {-> New literal.datetime(datetime_literal.datetime_literal)}
| {boolean} boolean_literal {-> New literal.boolean(boolean_literal.boolean_literal)};
//| {geometry} geometry_literal {-> New literal.geometry(geometry_literal.geometry_literal)}; // do not allow this for the moment
numeric_literal {-> numeric_literal} =
signed_numeric_literal {-> New numeric_literal.default(signed_numeric_literal)};
string_literal {-> string_literal} =
character_string_literal {-> New string_literal.default(character_string_literal)};
boolean_literal {-> boolean_literal} =
{true} boolean_true {-> New boolean_literal.true()}
| {false} boolean_false {-> New boolean_literal.false()}
| {unknown} boolean_unknown {-> New boolean_literal.unknown()};
datetime_literal {-> datetime_literal} =
datetime {-> New datetime_literal.default(datetime)};
duration_literal {-> duration_literal} =
duration_symbol [year_digits]:unsigned_integer dur_year_symbol [month_digits]:unsigned_integer dur_month_symbol [day_digits]:unsigned_integer dur_day_symbol [hour_digits]:unsigned_integer dur_hour_symbol [minute_digits]:unsigned_integer dur_minute_symbol [second_digits]:unsigned_integer dur_second_symbol {-> New duration_literal.default(year_digits, month_digits, day_digits, hour_digits, minute_digits, second_digits)};
timespan_literal {-> timespan_literal} =
{from_to} [from]:datetime time_span_separator [to]:datetime {-> New timespan_literal.from_to(from, to)}
| {from_duration} datetime time_span_separator duration_literal {-> New timespan_literal.from_duration(datetime, duration_literal.duration_literal)}
| {duration_to} duration_literal time_span_separator datetime {-> New timespan_literal.duration_to(duration_literal.duration_literal, datetime)};
geometry_literal {-> geometry_literal} =
{point} wkt_point_literal {-> New geometry_literal.point(wkt_point_literal)}
| {line_string} wkt_line_string_literal {-> New geometry_literal.line_string(wkt_line_string_literal)}
| {polygon} wkt_polygon_literal {-> New geometry_literal.polygon(wkt_polygon_literal)}
//| {polyhedral_surface} wkt_polyhedral_surface_literal {-> New geometry_literal.polyhedral_surface(wkt_polyhedral_surface_literal)}
//| {triangle_literal} wkt_triangle_literal {-> New geometry_literal.triangle(wkt_triangle_literal)}
//| {tin_literal} wkt_tin_literal {-> New geometry_literal.tin(wkt_tin_literal)}
| {multi_point_literal} wkt_multi_point_literal {-> New geometry_literal.multi_point(wkt_multi_point_literal)}
| {multi_line_string_literal} wkt_multi_line_string_literal {-> New geometry_literal.multi_line_string(wkt_multi_line_string_literal)}
| {multi_polygon_literal} wkt_multi_polygon_literal {-> New geometry_literal.multi_polygon(wkt_multi_polygon_literal)}
| {geometry_collection_literal} wkt_geometry_collection_literal {-> New geometry_literal.geometry_collection(wkt_geometry_collection_literal)};
attribute_name {-> attr} =
{simple_attribute} identifier {-> New attr.id(identifier)}
| {compound_attribute} identifier period attribute_name {-> New attr.compound_id(identifier, attribute_name.attr)};
Abstract Syntax Tree
expr = // General comparisons
{gt} [left]:attr [right]:literal
| {lt} [left]:attr [right]:literal
| {gte} [left]:attr [right]:literal
| {lte} [left]:attr [right]:literal
| {eq} [left]:attr [right]:literal
| {neq} [left]:attr [right]:literal
// Text comparisons
| {like} [left]:attr [right]:string_literal
| {not_like} [left]:attr [right]:string_literal
| {ilike} [left]:attr [right]:string_literal
| {not_ilike} [left]:attr [right]:string_literal
// Null comparisons
| {is_null} [attr]:attr
| {is_not_null} [attr]:attr
// Comparison concatenation
| {or} [left]:expr [right]:expr
| {and} [left]:expr [right]:expr
| {not} [expr]:expr
// Attribute existence
| {exists} [attr]:attr
| {does_not_exist} [attr]:attr
// Temporal comparisons
| {before} [attr]:attr [date_time]:datetime_literal
| {after} [attr]:attr [date_time]:datetime_literal
| {during} [attr]:attr [time_span]:timespan_literal
| {before_or_during} [attr]:attr [time_span]:timespan_literal
| {during_or_after} [attr]:attr [time_span]:timespan_literal
| {geo_equals} [left]:attr [right]:geometry_literal;
attr =
{id} identifier
| {compound_id} identifier attr;
literal =
{numeric} numeric_literal
| {string} string_literal
| {boolean} boolean_literal
| {datetime} datetime_literal
| {timespan} timespan_literal;
//| {geometry} geometry_literal // not sure how to implement comparisons between all kinds of geometries, so we don't allow it
numeric_literal =
{default} signed_numeric_literal;
string_literal =
{default} character_string_literal;
boolean_literal =
{true}
| {false}
| {unknown};
datetime_literal =
{default} datetime;
duration_literal =
{default} [years]:unsigned_integer [months]:unsigned_integer [days]:unsigned_integer [hours]:unsigned_integer [minutes]:unsigned_integer [seconds]:unsigned_integer;
timespan_literal =
{from_to} [from]:datetime [to]:datetime
| {from_duration} [from]:datetime [duration]:duration_literal
| {duration_to} [duration]:duration_literal [to]:datetime;
geometry_literal =
{point} wkt_point_literal
| {line_string} wkt_line_string_literal
| {polygon} wkt_polygon_literal
//| {polyhedral_surface} wkt_polyhedral_surface_literal
//| {triangle_literal} wkt_triangle_literal
//| {tin_literal} wkt_tin_literal
| {multi_point} wkt_multi_point_literal
| {multi_line_string} wkt_multi_line_string_literal
| {multi_polygon} wkt_multi_polygon_literal
| {geometry_collection} wkt_geometry_collection_literal;