/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* EJBQL.g
*
* Created on November 12, 2001
*/
{
import antlr.MismatchedTokenException;
import antlr.MismatchedCharException;
import antlr.NoViableAltException;
import antlr.NoViableAltForCharException;
import antlr.TokenStreamRecognitionException;
}
//===== Lexical Analyzer Class Definitions =====
/**
* This class defines the lexical analysis for the EJBQL compiler.
*
* @author Michael Bouschen
* @author Shing Wai Chan
*/
class EJBQLLexer extends Lexer;
{
k = 2;
exportVocab = EJBQL;
caseSensitiveLiterals = false;
}
tokens {
// keywords
// aggregate functions
// order by
// relational operators
GE;
GT;
LE;
LT;
// arithmetic operators
PLUS;
STAR;
DIV;
// literals
// other token types
DOT;
// lexer internal token types
WS;
}
{
/**
* The width of a tab stop.
* This value is used to calculate the correct column in a line
* conatining a tab character.
*/
protected static final int TABSIZE = 4;
/** */
/** I18N support. */
protected final static ResourceBundle msgs =
/**
*
*/
public void tab()
{
}
/** */
{
}
/** Report lexer exception errors caught in nextToken(). */
public void reportError(RecognitionException e)
{
}
/** Lexer error-reporting function. */
public void reportError(String s)
{
}
/** Lexer warning-reporting function. */
public void reportWarning(String s)
{
throw new EJBQLException(s);
}
/**
*
*/
{
if (ex instanceof MismatchedCharException) {
//TBD: bundle key
}
else {
}
return;
}
}
else if (ex instanceof MismatchedTokenException) {
//TBD: bundle key
}
else {
}
return;
}
}
else if (ex instanceof NoViableAltException) {
//TBD: bundle key
}
else {
}
return;
}
}
else if (ex instanceof NoViableAltForCharException) {
}
else if (ex instanceof TokenStreamRecognitionException) {
}
// no special handling from aboves matches the exception if this line is reached =>
// make it a syntax error
int line = 0;
int column = 0;
if (ex instanceof RecognitionException) {
}
}
}
// OPERATORS
LPAREN : '(' ;
RPAREN : ')' ;
COMMA : ',' ;
//DOT : '.' ;
EQUAL : '=' ;
LT : '<' ;
PLUS : '+' ;
DIV : '/' ;
MINUS : '-' ;
STAR : '*' ;
// Whitespace -- ignored
: ( ' '
| '\t'
| '\f'
)
;
: ( "\r\n" //NOI18N
| '\r'
| '\n'
)
{
newline();
}
;
// input parameter
: '?' ('1'..'9') ('0'..'9')*
;
// string literals
;
// escape sequence -- note that this is protected; it can only be called
// from another lexer rule -- it will not ever directly return a token to
// the parser
// There are various ambiguities hushed in this rule. The optional
// '0'...'9' digit matches should be matched here rather than letting
// them go back to STRING_LITERAL to be matched. ANTLR does the
// right thing by matching immediately; hence, it's ok to shut off
// the FOLLOW ambig warnings.
protected
: '\\'
( options { warnWhenFollowAmbig = false; }
: 'n'
| 'r'
| 't'
| 'b'
| 'f'
| '"' //NOI18N
// Note, EJBQL uses a quote to escape a quote
// | '\''
| '\\'
| ('0'..'3')
(
options {
warnWhenFollowAmbig = false;
}
: ('0'..'7')
(
options {
warnWhenFollowAmbig = false;
}
: '0'..'7'
)?
)?
| ('4'..'7')
(
options {
warnWhenFollowAmbig = false;
}
: ('0'..'7')
)?
)?
;
// hexadecimal digit
protected
: ('0'..'9'|'A'..'F'|'a'..'f')
;
// a numeric literal
{
boolean isDecimal=false;
int tokenType = DOUBLE_LITERAL;
}
(EXPONENT)?
( ('x'|'X')
( // hex
// the 'e'|'E' and float suffix stuff look
// like hex digits, hence the (...)+ doesn't
// know when to stop: ambig. ANTLR resolves
// it correctly by matching immediately. It
// is therefor ok to hush warning.
options {
warnWhenFollowAmbig=false;
}
)+
| ('0'..'7')+ // octal
)?
)
// only check to see if it's a float if looks like decimal so far
| {isDecimal}?
{tokenType = DOUBLE_LITERAL;}
)
)?
;
// a couple protected methods to assist in matching floating point numbers
protected
: ('e'|'E') ('+'|'-')? ('0'..'9')+
;
protected
;
// an identifier. Note that testLiterals is set to true! This means
// that after we match the rule, we look in the literals table to see
// if it's a literal or really an identifer
: ( 'a'..'z'
| 'A'..'Z'
| '_'
| '$'
{
}
}
)
( 'a'..'z'
| 'A'..'Z'
| '_'
| '$'
| '0'..'9'
{
}
}
)*
;
protected
{
try {
// problems using ANTLR feature $setText => use generated code
}
catch (NumberFormatException ex) {
}
}
;
//===== Parser Class Definitions =====
/**
* This class defines the syntax analysis (parser) of the EJBQL compiler.
*
* @author Michael Bouschen
*/
class EJBQLParser extends Parser;
options {
k = 2; // two token lookahead
exportVocab = EJBQL;
buildAST = true;
}
{
// root
// special from clause tokenes
// special dot expresssion
// identifier
// operators
}
{
/** I18N support. */
protected final static ResourceBundle msgs =
/** ANTLR method called when an error was detected. */
{
}
/** ANTLR method called when an error was detected. */
public void reportError(String s)
{
}
/** */
{
}
/** ANTLR method called when a warning was detected. */
public void reportWarning(String s)
{
throw new EJBQLException(s);
}
/**
* This method wraps the root rule in order to handle
* ANTLRExceptions thrown during parsing.
*/
public void query ()
{
try {
root();
}
catch (ANTLRException ex) {
}
}
}
// ----------------------------------
// rules
// ----------------------------------
root!
{
// switch the order of subnodes: the fromClause should come first,
// because it declares the identification variables used in the
// selectClause and the whereClause
if (#o != null) {
}
}
;
;
: p:pathExpr
{
#p.getText()));
}
}
;
;
;
;
{
}
;
| // empty rule
{
// Add where true in the case the where clause is omitted
}
;
;
;
;
: ( NOT^ )? conditionalPrimary
;
: ( betweenExpr )=> betweenExpr
| ( nullComparisonExpr )=> nullComparisonExpr
;
{
// map NOT BETWEEN to single operator NOT_BETWEEN
if (#n != null)
}
;
{
// map NOT LIKE to single operator NOT_LIKE
if(#n != null)
}
;
| // empty rule
;
{
// map NOT BETWEEN to single operator NOT_IN
if (#n != null)
}
;
{
// map NOT NULL to single operator NOT_NULL
if (#n != null)
}
;
{
// map IS NOT EMPTY to single operator NOT_EMPTY
if (#n != null)
}
;
{
// map NOT MEMBER to single operator NOT_MEMBER
if (#n != null)
}
;
;
;
;
;
: pathExpr
| literal
| function
;
;
;
| // empty rule
;
;
: ASC
| DESC
| // empty rule
{
// ASC is added as default
}
;
: literal
;
: TRUE
| FALSE
;
: s:STRING_LITERAL
{
// strip quotes from the token text
}
;