grammar Cql; options { output=AST; ASTLabelType=CommonTree; language=Java; //backtrack=true; } @parser::header { package gr.uoa.di.driver.cql; } @lexer::header { package gr.uoa.di.driver.cql; } /* root element -- print tree as debug */ cql returns [CqlQuery query] : q=cqlquery { System.out.println("query tree: " + $cqlquery.tree.toStringTree() ); $query = q.query; } ; /* Ignore query scope */ cqlquery returns [CqlQuery query] : qscope! q=cqlquery { $query = q.query; } | c=scopedClause { $query = new CqlQuery(c.clause); } ; /***********************************************/ /* Ignored rules -- keep for syntax validation */ qscope : '>' prefix '=' uri | '>' uri ; prefix : term ; uri : term ; /***********************************************/ scopedClause returns [CqlClause clause] : left=searchClause { $clause = left.clause; } (op=booleanGroup^ right=searchClause { $clause = new CqlBoolean($clause, op.value, right.clause); } )* ; /* Ingore modifiers */ booleanGroup returns [String value] : b=bool (modifierList)? { $value = b.value; } ; bool returns [String value] : 'and' { $value = "and"; } | 'or' { $value = "or"; } | 'not' { $value = "not"; } | 'prox' { $value = "prox"; }; /***********************************************/ /* Ignored rules -- keep for syntax validation */ modifierList : (modifier)+ ; modifier : '/' modifierName comparitorSymbol modifierValue | '/' modifierName ; modifierName : term ; modifierValue : term ; /***********************************************/ searchClause returns [CqlClause clause] : '('! q=cqlquery ')'! { $clause = q.query.root; } | i=index r=relation^ v=searchTerm { $clause = new CqlRelation(i.value, r.value, v.value); } | t=searchTerm { $clause = new CqlTerm(t.value); } ; index returns [String value] : t=term { $value = t.value; } ; /* Ignore modifiers */ relation returns [String value] : c=comparitor { $value = c.value; } (modifierList)? ; comparitor returns [String value] : s=comparitorSymbol { $value = s.value; } | n=namedComparitor { $value = n.value; } ; comparitorSymbol returns [String value] : '=' { $value = "="; } | '>' { $value = ">"; } | '<' { $value = "<"; } | '>=' { $value = ">="; } | '<=' { $value = "<="; } | '<>' { $value = "<>"; } ; namedComparitor returns [String value] : i=identifier { $value = i.value; } ; searchTerm returns [String value] : t=term { $value = t.value; } ; term returns [String value] : i=identifier { $value = $i.value; } | 'and' { $value = "and"; } | 'or' { $value = "or"; } | 'not' { $value = "not"; } | 'prox' { $value = "prox"; } ; identifier returns [String value] : IDENTIFIER { $value = $IDENTIFIER.text; } | STRING { $value = $STRING.text; } ; QUOTE : '"' ; WHITESPACE : ( ' ' | '\t' | '\r' | '\n' | '\f' ) {skip();} ; /* STRING is double quotes followed by a sequence of any characters except double quotes, where backslash (\) escapes the following character (include double quote characters). The resultant value includes all backslash characters except those releasing a double quotes character. This allows other systems to interpret the backslash characters. The surrounding double quotes are also not included. */ STRING : QUOTE! ( '\\'! QUOTE | ~(QUOTE) )* QUOTE! ; /* IDENTIFIER is any sequence of characters excluding whitespace characers (as defined by the current character set), '(', ')', '=', '<', '>', and '"' (double quotes). If the final sequence is a reserved word, that token is returned instead. (Note that '.' is part of an identifier, and a series of digits is also an identifier.) Reserved words are 'and', 'or', 'not', and 'prox' (case insensitive). When a reserved word is used in term, the term value is the word, in the exact case as specified in a query. */ IDENTIFIER : ( ~(' ' | '\t' | '\r' | '\n' | '\f' | '(' | ')' | '=' | '<' | '>' | '/' | '"') )+ ;