Skip to content
adqlGrammar.jj 53.6 KiB
Newer Older
/*
 * This file is part of ADQLLibrary.
 * 
 * ADQLLibrary 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, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * ADQLLibrary 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.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Copyright 2012-2014 - UDS/Centre de DonnM-CM-)es astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institute (ARI)
 */

/*
*  This JavaCC file implements the BNF definition of ADQL v2.0 (IVOA Recommendation 30 Oct 2008 - http://www.ivoa.net/Documents/cover/ADQL-20081030.html).
*  To generate the parser with this file use JavaCC. This .jj file has been successfully tested with JavaCC 5.0.
*  
*  The generated parser checks the syntax of the given ADQL query and generates an object representation but no coherence with any database is done.
*  If the syntax is not conform to the ADQL definition an error message is printed else it will be the message "Correct syntax".
*
*  Author:  Gr&eacute;gory Mantelet (CDS;ARI) - gmantele@ari.uni-heidelberg.de
*  Version: 1.2 (03/2014)
*/

							/* ########### */
							/* # OPTIONS # */
							/* ########### */
options {
	STATIC = false;
	IGNORE_CASE = true;
	DEBUG_PARSER = true;
}

							/* ########## */
							/* # PARSER # */
							/* ########## */
PARSER_BEGIN(ADQLParser)

package adql.parser;

import java.util.Stack;
import java.util.Vector;
import java.util.ArrayList;
import java.util.Collection;

import java.io.FileReader;
import java.io.IOException;

import adql.db.exception.UnresolvedIdentifiersException;

import adql.parser.IdentifierItems.IdentifierItem;

import adql.parser.ADQLQueryFactory.JoinType;

import adql.query.*;
import adql.query.from.*;
import adql.query.constraint.*;

import adql.query.operand.*;

import adql.query.operand.function.*;

import adql.query.operand.function.geometry.*;
import adql.query.operand.function.geometry.GeometryFunction.GeometryValue;

import adql.translator.PostgreSQLTranslator;
import adql.translator.TranslationException;

/**
* <p>Parses an ADQL query thanks to the {@link ADQLParser#Query()} function. </p>
* 
* <p>This parser is able, thanks to a {@link QueryChecker} object, to check each ADQLQuery just after its generation.
* It could be used to check the consistency between the ADQL query to parse and the "database" on which the query must be executed.
* By default, there is no {@link QueryChecker}. Thus you must extend {@link QueryChecker} to check semantically all generated ADQLQuery objects.</p>
* 
* <p>To create an object representation of the given ADQL query, this parser uses a {@link ADQLQueryFactory} object. So if you want customize some object (ie. CONTAINS) of this representation
* you just have to extend the corresponding default object (ie. ContainsFunction) and to extend the corresponding function of {@link ADQLQueryFactory} (ie. createContains(...)).</p>
* 
* <p><b><u>WARNING:</u> To modify this class it's strongly encouraged to modify the .jj file in the section between <i>PARSER_BEGIN</i> and <i>PARSER_END</i> and to re-compile it with JavaCC.</b></p>
*
* @see QueryChecker
* @see ADQLQueryFactory
*
* @author Gr&eacute;gory Mantelet (CDS;ARI) - gmantele@ari.uni-heidelberg.de
* @version 1.2 (03/2014)
*/
public class ADQLParser {
	
	/** Tools to build the object representation of the ADQL query. */
	private ADQLQueryFactory queryFactory = new ADQLQueryFactory();
	
	/** The stack of queries (because there may be some sub-queries). */
	private Stack<ADQLQuery> stackQuery = new Stack<ADQLQuery>();
	
	/** The object representation of the ADQL query to parse. (ONLY USED DURING THE PARSING, else it is always <i>null</i>). */
	private ADQLQuery query = null;
	
	/** Checks each ADQLQuery (sub-query or not) just after their generation. */
	private QueryChecker queryChecker = null;
	
	/** The first token of a table/column name. This token is extracted by {@link #Identifier()}. */
	private Token currentIdentifierToken = null;
	
	/** List of all allowed coordinate systems. */
	private ArrayList<String> allowedCoordSys = new ArrayList<String>();
	
	/**
	* Builds an ADQL parser without a query to parse.
	*/
	public ADQLParser(){
		this(new java.io.ByteArrayInputStream("".getBytes()));
	}
	
	/**
	* Builds an ADQL parser without a query to parse but with a QueryChecker and a ADQLQueryFactory.
	*
	* @param checker	The object to use to check each ADQLQuery.
	* @param factory	The object to use to build an object representation of the given ADQL query.
	*/
	public ADQLParser(QueryChecker checker, ADQLQueryFactory factory) {
		this();
		
		queryChecker = checker;
			
		if (factory != null)
			queryFactory = factory;
	}
	
	/**
	* Builds an ADQL parser without a query to parse but with a QueryChecker.
	*
	* @param checker	The object to use to check each ADQLQuery.
	*/
	public ADQLParser(QueryChecker checker) {
		this(checker, null);
	}
	
	/**
	* Builds an ADQL parser without a query to parse but with a ADQLQueryFactory.
	*
	* @param factory	The object to use to build an object representation of the given ADQL query.
	*/
	public ADQLParser(ADQLQueryFactory factory) {
		this((QueryChecker)null, factory);
	}
	
	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream		The stream in which the ADQL query to parse is given.
	* @param checker	The object to use to check each ADQLQuery.
	* @param factory	The object to use to build an object representation of the given ADQL query.
	*/
	public ADQLParser(java.io.InputStream stream, QueryChecker checker, ADQLQueryFactory factory) {
		this(stream);
		
		queryChecker = checker;
		
		if (factory != null)
			queryFactory = factory;
	}
	
	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream		The stream in which the ADQL query to parse is given.
	* @param checker	The object to use to check each ADQLQuery.
	*/
	public ADQLParser(java.io.InputStream stream, QueryChecker checker) {
		this(stream, checker, null);
	}
	
	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream		The stream in which the ADQL query to parse is given.
	* @param factory	The object to use to build an object representation of the given ADQL query.
	*/
	public ADQLParser(java.io.InputStream stream, ADQLQueryFactory factory) {
		this(stream, (QueryChecker)null, factory);
	}
	
	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream			The stream in which the ADQL query to parse is given.
	* @param encoding		The supplied encoding.
	* @param checker		The object to use to check each ADQLQuery.
	* @param factory		The object to use to build an object representation of the given ADQL query.
	*/
	public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker, ADQLQueryFactory factory) {
		this(stream, encoding);
		
Loading full blame...