Skip to content
adqlGrammar.jj 74.4 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-2019 - UDS/Centre de Donné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 6.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)
*/

							/* ########### */
							/* # OPTIONS # */
							/* ########### */
options {
	STATIC = false;
	IGNORE_CASE = 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;

/**
* Parses an ADQL query thanks to the {@link ADQLParser#Query()} function.
* <p>
*   This parser is able, thanks to a {@link QueryChecker} object, to check each
*   {@link 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>Here are the key functions to use:</p>
* <ul>
* 	<li>{@link #parseQuery(java.lang.String)} (or any of its alternatives)
* 		to parse an input ADQL query String and get its corresponding ADQL tree
*   </li>
*   <li>{@link #tryQuickFix(java.lang.String)} to try fixing the most common
* 		issues with ADQL queries (e.g. Unicode confusable characters,
* 		unescaped ADQL identifiers, SQL reserved keywords, ...)</li>
* </ul>
* <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)
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 {@link 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;
	
	/**
	* 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
	* {@link QueryChecker} and a {@link ADQLQueryFactory}.
	* @param checker	The object to use to check each {@link 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
	* {@link QueryChecker}.
	* @param checker	The object to use to check each {@link ADQLQuery}.
	public ADQLParser(QueryChecker checker) {
	* Builds an ADQL parser without a query to parse but with a
	* {@link 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 {@link 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) {
Loading full blame...