/* * GeoTools - The Open Source Java GIS Tookit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ options { STATIC=false; NODE_SCOPE_HOOK=true; //JJTree generates calls to two user-defined parser methods on the entry and exit of every node scope NODE_DEFAULT_VOID=true; MULTI=false; BUILD_NODE_FILES=false; // Generate sample implementations for SimpleNode and any other nodes used in the grammar NODE_PACKAGE="org.geotools.filter.text.generated.parsers"; SANITY_CHECK=true; VISITOR=false; // debug DEBUG_TOKEN_MANAGER=false; DEBUG_PARSER=false; } PARSER_BEGIN(CQLParser) package org.geotools.filter.text.generated.parsers; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; /** * CQLParser is the result of a javacc jjtree grammar. * * @author Ian Schneider * @author Mauricio Pazos - Axios Engineering * @since 2.5 * @version $Id: CQLGrammar.jjt 24966 2007-03-30 11:33:47Z vmpazos $ */ public class CQLParser { public void jjtreeOpenNodeScope(Node n) throws ParseException { } public void jjtreeCloseNodeScope(Node n) throws ParseException { } private static final Logger LOGGER = Logger.getLogger(CQLParser.class.getName()); /** * initialize geooperations */ // the following were deprecated in CSW specification v 2.0.2 protected static final Set GEOOP_DEPRECATED= new HashSet(); static{ GEOOP_DEPRECATED.add("EQUAL"); GEOOP_DEPRECATED.add("INTERSECT"); GEOOP_DEPRECATED.add("TOUCH"); GEOOP_DEPRECATED.add("CROSS"); GEOOP_DEPRECATED.add("OVERLAP"); } protected static final Set GEOOP = new HashSet(); static { GEOOP.add("EQUALS"); GEOOP.add("DISJOINT"); GEOOP.add("INTERSECTS"); GEOOP.add("TOUCHES"); GEOOP.add("CROSSES"); GEOOP.add("WITHIN"); GEOOP.add("CONTAINS"); GEOOP.add("OVERLAPS"); GEOOP.add("RELATE"); GEOOP.add("BBOX"); GEOOP.addAll(GEOOP_DEPRECATED); } protected boolean isGeoOp() { String tokenImage = getToken(1).image.toUpperCase(); boolean OK = "(".equals(getToken(2).image) && GEOOP.contains(tokenImage); if(OK) warning(tokenImage); return OK; } protected void warning(String images){ if(images.equals("EQUAL")){ LOGGER.warning("EQUAL is deprecated syntax, you should use EQUALS"); } if(images.equals("INTERSECT")){ LOGGER.warning("INTERSECT is deprecated syntax, you should use INTERSECTS"); } if(images.equals("TOUCH")){ LOGGER.warning("TOUCH is deprecated syntax, you should use TOUCHES"); } if(images.equals("CROSS")){ LOGGER.warning("CROSS is deprecated syntax, you should use CROSSES"); } if(images.equals("OVERLAP")){ LOGGER.warning("OVERLAP is deprecated syntax, you should use OVERLAPS"); } } protected static final Set RELGEOOP = new HashSet(); static { RELGEOOP.add("DWITHIN"); RELGEOOP.add("BEYOND"); } protected boolean isRelGeoOp() { return "(".equals(getToken(2).image) && RELGEOOP.contains(getToken(1).image.toUpperCase()); } } PARSER_END(CQLParser) SKIP : /* WHITE SPACE */ { " " | "\t" | "\n" | "\r" | "\f" } /* * */ TOKEN: { < STRING_LITERAL: "'" ( "''" | ~["'"] )* "'" > : DEFAULT } /* * keywords */ TOKEN [IGNORE_CASE]: /* keywords */ { < AND: "and" | "&&"> | < OR: "or"> | < NOT: "not" | "!"> | < EQ: "eq" | "==" | "="> | < NEQ: "neq" | "<>" > | < GT: "gt" | ">" > | < LT: "lt" | "<" > | < GTE: "gte" | ">="> | < LTE: "lte" | "<="> | < TRUE: "true"> | < FALSE: "false"> | < UNKNOWN: "unknown"> | < LIKE: "like" > | < BETWEEN: "between"> | < IS: "is" > | < NULL: "null" > } TOKEN [IGNORE_CASE]: /* include all and exclude all filters */ { < INCLUDE: "include"> | < EXCLUDE: "exclude"> } TOKEN [IGNORE_CASE]: /* geometry markers */ { < POINT: "point"> | < LINESTRING: "linestring"> | < POLYGON: "polygon"> | < MULTIPOINT: "multipoint"> | < MULTILINESTRING: "multilinestring"> | < MULTIPOLYGON: "multipolygon"> | < GEOMETRYCOLLECTION: "geometrycollection"> | < ENVELOPE: "envelope"> } TOKEN [IGNORE_CASE]: /* temporal expression*/ { | | | } TOKEN [IGNORE_CASE]: /* existence predicate*/ { | } TOKEN [IGNORE_CASE]: { < EQUALS: "equal" | "equals" > | < DISJOINT: "disjoint"> | | < TOUCHES: "touch"| "touches"> | < CROSSES: "cross" | "crosses"> | < WITHIN: "within"> | < CONTAINS: "contains"> | < OVERLAPS: "overlap" | "overlaps"> | < RELATE: "relate"> | < BBOX: "bbox"> } TOKEN [IGNORE_CASE]: /* relgeoop name */ { < DWITHIN: "dwithin"> | < BEYOND: "beyond"> } TOKEN [IGNORE_CASE]: { | | | | } TOKEN: { < LP: "("> | < RP: ")"> | < LSP: "["> | < RSP: "]"> | < COMMA: ","> | < SENTENCE_SEPARATOR: ";"> | < PERIOD: "."> | < SLASH: "/"> | // < PERIOD_SEP: > | // < DIV: > | < COLON: ":"> | < MULT: "*"> | < PLUS: "+"> | < MINUS: "-" > } // Note, because float and int can technically have the same grammar, // put int first to make token manager have preference for it... // The same case occurs between identifier and duration tokens, // then DURATION has preference over IDENTIFIER TOKEN [IGNORE_CASE]: /* Literals */ { < INTEGER_LITERAL: ("-")? ()+ > | < FLOATING_LITERAL: ("-")? ( ( )* "." ( )+ ()? ) | ( ( )+ ("." ( )*)? ()? ) > | < #DUR_DAY: ()+ "D" > | < #DUR_MONTH: ()+ "M" ()? > | < #DUR_YEAR: ()+ "Y" ()? > | < #DUR_DATE: ( | | ) ("T" )?> | < #DUR_HOUR: ()+ "H" ()?> | < #DUR_MINUTE:()+ "M" ()? > | < #DUR_SECOND:()+ "S" > | < #DUR_TIME: ( | | ) > | < DURATION: ("P" | "T" ) > | < #FULL_DATE: "-" "-" > | < #UTC_TIME: ":" ":" ("." ()+)? "Z" > | < DATE_TIME : "T" > | < IDENTIFIER: ( (|)*) > | < LETTER: [ "a"-"z", "A"-"Z" , "_"] > | < DIGIT: [ "0"-"9"] > | < #EXPONENT: ["e","E"] (["+","-"])? ()+ > } /* * Program structuring syntax to parse a single filter. */ Node FilterCompilationUnit() : {} { SearchCondition() {return jjtree.rootNode();} } /* * Program structuring syntax to parse a single expression. */ Node ExpressionCompilationUnit() : {} { Expression() {return jjtree.rootNode();} } /* * Program structuring syntax to parse a list of filters. */ Node FilterListCompilationUnit() : {} { SequenceOfSearchConditions() {return jjtree.rootNode();} } void SearchCondition() #void: {} { BooleanValueExpression() } /* * ::= * * | ; */ void SequenceOfSearchConditions() #void: {} { SearchCondition() ( SearchCondition())* } /* * ::= * * | OR */ void BooleanValueExpression() #void: {} { BooleanTerm()( BooleanTerm() #Boolean_Or_Node )* } /* * ::= * * | AND */ void BooleanTerm() #void : {} { (BooleanFactor()( BooleanFactor() #Boolean_And_Node(2) )*) } void BooleanFactor() #void: {} { BooleanPrimary() #Boolean_Not_Node | BooleanPrimary() } void BooleanPrimary() #void: {} { LOOKAHEAD(Predicate()) Predicate() | IncludeExcludePredicate() | SearchCondition() | SearchCondition() | RoutineInvocation() } /* * ::= * | * | * | * | (*not supported*) * | * | (*extension*) * | (*extension*) */ void Predicate() #void: {} { Attribute() ( LOOKAHEAD(3)TextPredicate() | LOOKAHEAD(3)NullPredicate() | LOOKAHEAD(3)ExistencePredicate() | LOOKAHEAD(3)TemporalPredicate() | LOOKAHEAD(3)BetweenPredicate() | ComparissonPredicate() ) } /* ---------------------------------------- * * * ---------------------------------------- * /* * ::= * * | * | */ void RoutineInvocation() #void: {} { LOOKAHEAD({ isGeoOp() }) RoutineInvocationGeoOp() | LOOKAHEAD({ isRelGeoOp() }) RoutineInvocationRelGeoOp() | RoutineInvocationGeneric() } void RoutineInvocationGeoOp() #void: {} { GeoRoutineArgumentList() #RoutineInvocation_GeoOp_Equal_Node | GeoRoutineArgumentList() #RoutineInvocation_GeoOp_Disjoint_Node | GeoRoutineArgumentList() #RoutineInvocation_GeoOp_Intersect_Node | GeoRoutineArgumentList() #RoutineInvocation_GeoOp_Touch_Node | GeoRoutineArgumentList() #RoutineInvocation_GeoOp_Cross_Node | GeoRoutineArgumentList() #RoutineInvocation_GeoOp_Within_Node | GeoRoutineArgumentList() #RoutineInvocation_GeoOp_Contain_Node | GeoRoutineArgumentList() #RoutineInvocation_GeoOp_Overlap_Node | GeoRoutineArgumentList() #RoutineInvocation_GeoOp_Relate_Node | BBoxArgumentList() } /* * ::= * * */ void GeoRoutineArgumentList() #void: {} { Attribute() GeometryLiteral() } /* * ::= * "(" "," * "," * "," * "," * * [, srs] ")" * * ::= * ::= * ::= * ::= * ::= */ void BBoxArgumentList() #void: {} { Attribute() SignedNumericLiteral() SignedNumericLiteral() SignedNumericLiteral() SignedNumericLiteral() ( #RoutineInvocation_GeoOp_BBOX_Node | StringLiteral() #RoutineInvocation_GeoOp_BBOX_SRS_Node) } /* * ::= DWITHIN | BEYOND */ void RoutineInvocationRelGeoOp() #void: {} { RelGeoRoutineArgumentList() #RoutineInvocation_RelOp_DWITHIN_Node | RelGeoRoutineArgumentList() #RoutineInvocation_RelOp_BEYOND_Node } /* * ::= * */ void RelGeoRoutineArgumentList() #void: {} { Attribute() GeometryLiteral() Tolerance() } /* * ::= */ void Tolerance() : {} { UnsignedNumericLiteral() #Tolerance_Node DistanceUnits() } void UnsignedNumericLiteral(): {} { SignedNumericLiteral() // TODO must be redefined for number token to handle sign correctly } /** * ::= * 'feet' | 'meters' | 'statute miles' | * 'nautical miles' | 'kilometers' * * TODO this set of units is just an example. The real list of distance unit must be developed */ void DistanceUnits() #DistanceUnits_Node: {} { | | | | } /* * ::= * * | * | * | * | * | * | * | */ void GeometryLiteral() #void: {} { PointTaggedText() | LineStringTaggedText() | PolygonTaggedText() | MultiPointTaggedText() | MultiLineStringTaggedText() | MultiPolygonTaggedText() | GeometryCollectionTaggedText() | EnvelopeTaggedText() } /* * ::= * | * * [] * ::= * [ { }... ] * * ::= * * | * | (*Extension*) * | (*Extnsion*) */ void RoutineInvocationGeneric() #void: {} { Function() } /* ---------------------------------------- * * End * ---------------------------------------- * /* ---------------------------------------- * * * ---------------------------------------- * /* * ::= * | */ void IncludeExcludePredicate() #void: {} { #Include_Node | #Exclude_Node } /* ---------------------------------------- * * * ---------------------------------------- * /* * ::= * */ void ComparissonPredicate() : {} { Expression() #ComparissonPredicate_EQ_Node | Expression() #ComparissonPredicate_GT_Node | Expression() #ComparissonPredicate_LT_Node | Expression() #ComparissonPredicate_GTE_Node | Expression() #ComparissonPredicate_LTE_Node | Expression() #ComparissonPredicate_Not_Equal_Node } /* * ::= IS [ NOT ] NULL */ void NullPredicate() : {} { LOOKAHEAD(3) #NullPredicateNode | #NotNullPredicateNode } /* ---------------------------------------- * * * ---------------------------------------- * * ::= * BEFORE * | BEFORE OR DURING * | DURING * | DURING OR AFTER * | AFTER */ void TemporalPredicate() #void: {} { TemporalPredicateBefore() | TemporalPredicateAfter() | TemporalPredicateDuring() } void TemporalPredicateBefore()#void: {} { DateTimeExpression() #TPBefore_DateTime_Node | Period() #TPBefore_Or_During_Period_Node } void TemporalPredicateAfter() #TPAfter_DateTime_Node: {} { DateTimeExpression() } void TemporalPredicateDuring()#void: {} { Period() #TPDuring_Period_Node | Period() #TPDuring_Or_After_Period_Node } /* * | */ void DateTimeExpression()#void: {} { LOOKAHEAD(2) Period() | DateTime() } /* * ::= * "/" * | "/" * | "/" */ void Period() #void: {} { LOOKAHEAD(2) DateTime() PeriodTail() | Duration() DateTime() #Period_With_Duration_Date_Node } void PeriodTail()#void: {} { Duration() #Period_With_Date_Duration_Node | DateTime() #Period_Between_Dates_Node } void DateTime()#DateTime_Node: {} { } /* * ::= "P" | * ::= | | [] * ::= ... "D" * ::= ... "M" [] * ::= ... "Y" [] */ void Duration()#void: {} { #Duration_Date_Node } /* ---------------------------------------- * * End * ---------------------------------------- */ /* ---------------------------------------- * * * ---------------------------------------- */ /* * ::= EXISTS * | DOES-NOT-EXIST */ void ExistencePredicate() #void: {} { #Existence_Predicate_Exists_Node | #Existence_Predicate_DoesNotExist_Node } /* ---------------------------------------- * * end * ---------------------------------------- */ void TextPredicate() #void: {} { LOOKAHEAD(2) CharacterPattern() #Not_Like_Node | CharacterPattern() #Like_Node } void CharacterPattern() #void: {} { StringLiteral() } /* * Cql Extension * * ::= ["NOT"] "BETWEEN" expression "AND" expression */ void BetweenPredicate() #void: {} { LOOKAHEAD(2) Expression() Expression() #Not_Between_Node | Expression() Expression() #Between_Node } /* * cql extension */ void Expression() #void: {} { BinaryExpression() } void BinaryExpression() #void: {} { MultiplicativeExpression() ( MultiplicativeExpression() #AddNode(2) | MultiplicativeExpression() #SubtractNode(2) )* } void MultiplicativeExpression() #void : {} { UnaryExpression() ( UnaryExpression() #MulNode(2) | UnaryExpression() #DivNode(2) )* } void UnaryExpression() #void: {} { LOOKAHEAD(Function()) Function() | LOOKAHEAD(Attribute()) Attribute() | Literal() | Expression() | Expression() } void Evaluate() #void: {} { LOOKAHEAD(Function()) Function() | Attribute() } /* * ::= [ { | }... ] */ void Identifier() #Identifier_Node: {} { IdentifierPart() ( | IdentifierPart() )* } void IdentifierPart() #Identifier_Part_Node: {} { } /* * ::= * * | * * ::= * [{}*] * * ::= */ void Attribute() #void: {} { SimpleAttributeName() AttributeTail() } /* * ::= */ void SimpleAttributeName() #Simple_Attribute_Node: {} { Identifier() } void AttributeTail() #Compound_Attribute_Node: {} { ( SimpleAttributeName() )* } /* * ::= * * | */ void Literal() #void : {} { SignedNumericLiteral() | GeneralLiteral() } void SignedNumericLiteral() #void : {} { IntegerLiteral() | FloatingLiteral() } /* * ::= * * | * | * | } void FloatingLiteral() #FloatingNode: {} { } void BooleanLiteral() #void : {} { #TrueNode | #FalseNode } void StringLiteral() #StringNode : {} { } /* ---------------------------------------- * * * ---------------------------------------- */ /* * ::= "(" [,]*) */ void Function() #Function_Node: {} { FunctionName() ( FunctionArg() ( FunctionArg() )* )? } void FunctionName() #FunctionName_Node: {} { } /* * ::= * * | * | (*extension: expression includes literal and attributes*) */ void FunctionArg() #FunctionArg_Node: {} { Expression() } /* ---------------------------------------- * * end * ---------------------------------------- */ /* * := */ void Point() #void: {} { NumericLiteral() NumericLiteral() } /* * := EMPTY * | {} ... */ void LineStringText() #void: {} { ( Point() ( Point() )* )? } void PointTaggedText() #WKTNode: {} { jjtThis.token = PointText() } /* * := EMPTY | */ void PointText() #void: {} { ( Point() )? } void LineStringTaggedText() #WKTNode: {} { jjtThis.token = LineStringText() } /* * := POLYGON */ void PolygonTaggedText() #WKTNode: {} { jjtThis.token = PolygonText() } /* * := EMPTY * | {}* */ void PolygonText()#void: {} { ( LineStringText() ( LineStringText())* )? } /* * ::= MULTIPOINT */ void MultiPointTaggedText() #WKTNode: {} { jjtThis.token = MultiPointText() } /* * := EMPTY * | ( {, }* ) */ void MultiPointText() #void: {} { ( PointText() ( PointText() )* )? } /* * := MULTILINESTRING */ void MultiLineStringTaggedText() #WKTNode: {} { jjtThis.token = MultiLineStringText() } /* * := * EMPTY * | ( {, < LineString Text > }* ) */ void MultiLineStringText() #void: {} { ( LineStringText() ( LineStringText())* )? } /* * :: =MULTIPOLYGON */ void MultiPolygonTaggedText() #WKTNode: {} { jjtThis.token = MultiPolygonText() } /* * := EMPTY * | {}* */ void MultiPolygonText() #void: {} { ( PolygonText() ( PolygonText() )* )? } void GeometryCollectionTaggedText() #WKTNode: {} { jjtThis.token = GeometryCollectionText() } /* * := EMPTY * | ( {, }* ) */ void GeometryCollectionText() #void: {} { ( GeometryLiteral() ( GeometryLiteral() )* )? } /* * ::= ENVELOPE */ void EnvelopeTaggedText() #EnvelopeTaggedText_Node: {} { jjtThis.token = EnvelopText() } /* * := EMPTY * | * * * * * * := numeric literal * := numeric literal * := numeric literal * := numeric literal */ void EnvelopText() #void: {} { ( NumericLiteral() NumericLiteral() NumericLiteral() NumericLiteral() )? } void NumericLiteral() #void: {} { | }