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égory Mantelet (CDS;ARI)
* Version: 1.5-2 (10/2020)
*/
/* ########### */
/* # OPTIONS # */
/* ########### */
options {
STATIC = false;
IGNORE_CASE = true;
DEBUG_PARSER = true;
}
/* ########## */
/* # PARSER # */
/* ########## */
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>
Grégory Mantelet
committed
*
* <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égory Mantelet (CDS;ARI)
* @version 1.5-2 (10/2020)
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.
*/
this(new java.io.ByteArrayInputStream("".getBytes()));
setDebug(false);
* 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) {
this(checker, null);
}
/**
* 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) {
gmantele
committed
setDebug(false);
Loading full blame...