Skip to content
adqlGrammar.jj 74.4 KiB
Newer Older
				if (fct.image.equalsIgnoreCase("contains"))
					gf = queryFactory.createContains(gvf1, gvf2);
				else
					gf = queryFactory.createIntersects(gvf1, gvf2);
			})
		// non_predicate_geometry_function
		|	(fct=<AREA> <LEFT_PAR> gvf1=GeometryExpression() end=<RIGHT_PAR>) {gf = queryFactory.createArea(gvf1);}
		|	(fct=<COORD1> <LEFT_PAR> (p1=Point() {gf = queryFactory.createCoord1(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord1(col1);}) end=<RIGHT_PAR>)
		|	(fct=<COORD2> <LEFT_PAR> (p1=Point() {gf = queryFactory.createCoord2(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord2(col1);}) end=<RIGHT_PAR>)
				<LEFT_PAR>
				(p1=Point()|col1=Column()) 
				{
					if (p1 != null)
						gvp1 = new GeometryValue<PointFunction>(p1);
						gvp1 = new GeometryValue<PointFunction>(col1);
				}
				<COMMA>
				(p2=Point()|col2=Column())
				{
					if (p2 != null)
						gvp2 = new GeometryValue<PointFunction>(p2);
						gvp2 = new GeometryValue<PointFunction>(col2);
				{gf = queryFactory.createDistance(gvp1, gvp2);}
			)
		)
	}catch(Exception ex){
		throw generateParseException(ex);
	}
	
	{
	  gf.setPosition(new TextPosition(fct, end));
	  return gf;
	}
ADQLOperand CoordinateSystem(): { ADQLOperand coordSys=null;}{
	coordSys=StringExpression()
GeometryFunction GeometryValueFunction(): {Token fct=null, end=null; ADQLOperand coordSys; ADQLOperand width, height; ADQLOperand[] coords, tmp; Vector<ADQLOperand> vCoords; ADQLOperand op=null; GeometryValue<GeometryFunction> gvf = null; GeometryFunction gf = null;} {
		((fct=<BOX> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
				<COMMA> coords=Coordinates() // coordinates
				<COMMA> width=NumericExpression() <COMMA> height=NumericExpression() end=<RIGHT_PAR>)
		 {gf = queryFactory.createBox(coordSys, coords[0], coords[1], width, height);}
		 
		// CENTROID:
		| (fct=<CENTROID> <LEFT_PAR> gvf=GeometryExpression() end=<RIGHT_PAR>) {gf = queryFactory.createCentroid(gvf);}
		| (fct=<CIRCLE> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
				<COMMA> coords=Coordinates() // coordinates
				<COMMA> width=NumericExpression() end=<RIGHT_PAR>) // radius
		 {gf = queryFactory.createCircle(coordSys, coords[0], coords[1], width);}
		
		// POINT: 
		| gf=Point()
		
		// POLYGON:
		| (fct=<POLYGON> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
				{ vCoords = new Vector<ADQLOperand>(); } // coordinates
				<COMMA> tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);}
				<COMMA> tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);}
				<COMMA> tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);}
				(<COMMA> tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);})*
		  { gf = queryFactory.createPolygon(coordSys, vCoords); }
		  
		// REGION:
		| (fct=<REGION> <LEFT_PAR> op=StringExpression() end=<RIGHT_PAR>) {gf = queryFactory.createRegion(op);})
	}catch(Exception ex){
		throw generateParseException(ex);
	}
	
	{
	  if (fct != null && end != null) // = !(gf instanceof Point)
	  	gf.setPosition(new TextPosition(fct, end));
	  return gf;
	}
PointFunction Point(): {Token start, end; ADQLOperand coordSys; ADQLOperand[] coords;} {
	start=<POINT> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
			<COMMA> coords=Coordinates() end=<RIGHT_PAR> // coordinates
			PointFunction pf = queryFactory.createPoint(coordSys, coords[0], coords[1]);
			pf.setPosition(new TextPosition(start, end));
			return pf;
		}catch(Exception ex){
			throw generateParseException(ex);
		}
	}
}

GeometryFunction ExtractCoordSys(): {Token start, end; GeometryValue<GeometryFunction> gvf;} {
	start=<COORDSYS> <LEFT_PAR> gvf=GeometryExpression() end=<RIGHT_PAR>
			GeometryFunction gf = queryFactory.createExtractCoordSys(gvf);
			gf.setPosition(new TextPosition(start, end));
			return gf;
		}catch(Exception ex){
			throw generateParseException(ex);
		}
	}
}

/* ***************** */
/* NUMERIC FUNCTIONS */
/* ***************** */
ADQLFunction NumericFunction(): {ADQLFunction fct;} {
	(fct=MathFunction()
	| fct=TrigFunction()
	| fct=GeometryFunction()
	| fct=UserDefinedFunction() { ((UserDefinedFunction)fct).setExpectedType('N'); })
MathFunction MathFunction(): {Token fct=null, end; ADQLOperand param1=null, param2=null; NumericConstant integerValue = null;} {
		((fct=<ABS> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<CEILING> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<DEGREES> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<EXP> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<FLOOR> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<LOG> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<LOG10> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<MOD> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<PI> <LEFT_PAR> end=<RIGHT_PAR>)
		| (fct=<POWER> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<RADIANS> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<RAND> <LEFT_PAR> (param1=NumericExpression())? end=<RIGHT_PAR>)
		| (fct=<ROUND> <LEFT_PAR> param1=NumericExpression() (<COMMA> param2=SignedInteger())? end=<RIGHT_PAR>)
		| (fct=<SQRT> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
		| (fct=<TRUNCATE> <LEFT_PAR> param1=NumericExpression() (<COMMA> param2=SignedInteger())? end=<RIGHT_PAR>))
			MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
			mf.setPosition(new TextPosition(fct, end));
			return mf;
		}
	}catch(Exception ex){
		throw generateParseException(ex);
	}
}

MathFunction TrigFunction(): {Token fct=null, end; ADQLOperand param1=null, param2=null;} {
	((fct=<ACOS> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
	| (fct=<ASIN> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
	| (fct=<ATAN> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
	| (fct=<ATAN2> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() end=<RIGHT_PAR>)
	| (fct=<COS> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
	| (fct=<COT> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
	| (fct=<SIN> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
	| (fct=<TAN> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>))
			MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
			mf.setPosition(new TextPosition(fct, end));
			return mf;
		}catch(Exception ex){
			throw generateParseException(ex);
		}
	}
}

UserDefinedFunction UserDefinedFunction(): {Token fct, end; Vector<ADQLOperand> params = new Vector<ADQLOperand>(); ADQLOperand op;} {
	fct=<REGULAR_IDENTIFIER_CANDIDATE> <LEFT_PAR> (op=ValueExpression() {params.add(op);} (<COMMA> op=ValueExpression() {params.add(op);})*)? end=<RIGHT_PAR>
		// Ensure the given function name is valid: 
		if (!isRegularIdentifier(fct.image))
			throw new ParseException("Invalid (User Defined) Function name: \""+fct.image+"\"!", new TextPosition(fct));
		
		//System.out.println("INFO [ADQLParser]: \""+fct.image+"\" (from line "+fct.beginLine+" and column "+fct.beginColumn+" to line "+token.endLine+" and column "+(token.endColumn+1)+") is considered as an user defined function !");
			ADQLOperand[] parameters = new ADQLOperand[params.size()];
			for(int i=0; i<params.size(); i++)
				parameters[i] = params.get(i);
			UserDefinedFunction udf = queryFactory.createUserDefinedFunction(fct.image, parameters);
			udf.setPosition(new TextPosition(fct, end));
			return udf;
		}catch(UnsupportedOperationException uoe){
		  	/* This catch clause is just for backward compatibility:
		  	 * if the createUserDefinedFunction(...) is overridden and
		  	 * the function can not be identified a such exception may be thrown). */
			throw new ParseException(uoe.getMessage(), new TextPosition(fct, token));
		}catch(Exception ex){
			throw generateParseException(ex);
		}
	}
}