HQLParser.java

// $ANTLR 2.7.7 (20060906): "hql.g" -> "HQLParser.java"$

/*
** Module   : HQLParser.java
**            HQLParserTokenTypes.java
**            HQLLexer.java
** Abstract : 
**
** Copyright (c) 2006-2023, Golden Code Development Corporation.
**
** -#- -I- --Date-- --JPRM-- -----------------------------Description-----------------------------
** 001 ECF 20060314   @25235 WARNING, THIS IS A GENERATED FILE!!!
**                           DO NOT EDIT THIS FILE. The original source file is hql.g!
*/

package com.goldencode.p2j.persist.hql;

import java.util.*;
import java.util.List;
import java.text.*;
import java.io.*;
import antlr.*;
import com.goldencode.p2j.uast.*;
import com.goldencode.p2j.util.logging.*;

import antlr.TokenBuffer;
import antlr.TokenStreamException;
import antlr.TokenStreamIOException;
import antlr.ANTLRException;
import antlr.LLkParser;
import antlr.Token;
import antlr.TokenStream;
import antlr.RecognitionException;
import antlr.NoViableAltException;
import antlr.MismatchedTokenException;
import antlr.SemanticException;
import antlr.ParserSharedInputState;
import antlr.collections.impl.BitSet;
import antlr.collections.AST;
import java.util.Hashtable;
import antlr.ASTFactory;
import antlr.ASTPair;
import antlr.collections.impl.ASTArray;

/**
 * Creates an Abstract Syntax Tree (AST) representation of an HQL expression
 * in infix notation from an input stream of tokens (provided by the
 * {@link HQLLexer}).  More specifically, the parser does the following:
 * <ul>
 *    <li> Drives the lexer by calling its' <code>nextToken</code> method.
 *         This method tokenizes the lexer's input stream of characters and
 *         returns the next found <code>Token</code> object.
 *    <li> Provides the {@link #expression} method as an entry point.
 *    <li> Builds an AST (&quot;intermediate form representation&quot;) of
 *         all the recognized tokens. This AST is designed for subsequent
 *         processing by the {@link com.goldencode.p2j.persist.FQLPreprocessor
 *         FQLPreprocessor}.
 *    <li> Handles the context sensitive aspects of symbol resolution.
 *    <li> To the extent that is possible while still generating a well
 *         structured tree, the parser has been structured to enforce
 *         syntactic correctness.
 * </ul>
 * <p>
 * This grammar is highly specific to ANTLR 2.7.4 and it may not be valid
 * in future versions of ANTLR.  This is due to the fact that the generated
 * code and the grammar syntax of ANTLR can change between versions.  These
 * factors are the most important constraints defining the structure of the
 * resulting grammar.  As a result, it is possible that the grammar will
 * require changes to run in future versions of ANTLR.
 * <p> 
 * <b>Please note that this is a generated file using ANTLR 2.7.4 and a
 * grammar specified in <code>hql.g</code>.</b>
 *
 * @author ECF
 * @author GES
 */
public class HQLParser extends antlr.LLkParser       implements HQLParserTokenTypes
 {

   /** Logger. */
   private static final CentralLogger LOG = CentralLogger.get(HQLParser.class);

   /** Name of the specialized AST class to use when parsing. */
   private static final Class AST_CLASS = HQLAst.class;
   
   /** Provides an efficient reverse lookup of names to token types. */
   private static Map tokenLookup = null;
   
   /** Next index value to be assigned to a query substitution node */
   private int nextSubstitutionIndex = 0;
   
   /**
    * Simple walker to print out the contents of an AST for debugging.
    *
    * @param    ast
    *           The current node to print.
    * @param    level
    *           The number of levels down from the root (0 == root node),
    *           which determines the indention level to print.
    */
   public static void visit(CommonAST ast, int level)
   {
      int          spaces = level * 3;
      StringBuffer sb     = new StringBuffer();
      
      // generate the indent based on the level from the root
      for (int i = 0; i < spaces; i++)
      {
         sb.append(' ');
      }
      
      // add our current node's text
      sb.append("[ ");
      sb.append(ast.getText());
      sb.append(" ] <");
      sb.append(_tokenNames[ast.getType()]);
      sb.append(">");
      
      // print out the current node
      System.out.println(sb.toString());
   
      CommonAST child = (CommonAST) ast.getFirstChild();
      level++;
      
      // now visit all children
      while (child != null)
      {
         visit(child, level);
         child = (CommonAST) child.getNextSibling();
      }
   }
   
   /**
    * Translates a text representation of a parser token type into the
    * actual integer value.
    *
    * @param    tokenName
    *           The text representation of the parser token type.
    *
    * @return   A valid parser-defined integer token type value or -1 if
    *           no match was found.
    */
   public static int lookupTokenType(String tokenName)
   {
      // initialize map if necessary
      if (tokenLookup == null)
      {
         int len = _tokenNames.length;
         
         tokenLookup = new HashMap();
         
         // load the map with our lowercased symbolic name as the key and
         // the wrapped int token type as the value
         for ( int i = 0; i < len; i++ )
         {
            tokenLookup.put(_tokenNames[i].toLowerCase(), i);
         }
      }
      
      Integer result = (Integer) tokenLookup.get(tokenName.toLowerCase());
      
      return (result == null ? -1 : result.intValue());
   }
   
   /**
    * Translates an integer value of a parser token type into the associated 
    * human readable text representation.
    *
    * @param    type
    *           The integer token type.
    *
    * @return   A valid parser-defined symbolic name or <code>null</code> if
    *           no match was found.
    */
   public static String lookupTokenName(int type)
   {
      if (type < 0 || type >= _tokenNames.length)
      {
         return null;
      }
      
      return _tokenNames[type];
   }
   
   /**
    * Implements special processing for <code>NULL</code> equality and
    * inequality tests.  If a <code>NULL</code> token is detected on either
    * side of either of the operators, the result will be rooted at an
    * <code>IS_NULL</code> (equality) or <code>NOT_NULL</code> (inequality)
    * node.  The operand that is <code>NULL</code> will be dropped and the
    * other operand will be the only child.    
    * <p>
    * This is separated from the main processing and really is a kind of
    * post-processing of the entire tree.
    */
   public void convertNullTest(CommonAST ast)
   {
      int type = ast.getType();
      
      // process the current node, only equality and inequality are of
      // interest
      if (type == EQUALS || type == NOT_EQ)
      {
         CommonAST first  = (CommonAST) ast.getFirstChild();
         CommonAST second = (CommonAST) first.getNextSibling();
         
         int ftype = first.getType(); 
         int stype = second.getType();
      
         // detect comparisons with NULL and rewrite the sub-expression
         if (ftype == NULL || stype == NULL)
         {
            // special case that can be optimized easily
            if (ftype == NULL && stype == NULL)
            {
               ast.setType(type == EQUALS ? BOOL_TRUE : BOOL_FALSE);
               ast.removeChildren();
            }
            else
            {
               // normal case: rewrite the token as our artificial unary
               // operator
               ast.setType(type == EQUALS ? IS_NULL : NOT_NULL);
               
               // only leave the non-NULL child behind as the single operand
               if (first.getType() == NULL)
               {
                  ast.setFirstChild(second);
               }
               else
               {
                  first.setNextSibling(null);
               }
            }
         }
      }
      
      // either way, process all children using a recursive call 
      CommonAST child = (CommonAST) ast.getFirstChild();
      
      while (child != null)
      {
         convertNullTest(child);
         child = (CommonAST) child.getNextSibling();
      }
   }
   
   /**
    * Parser error-reporting function.
    *
    * TODO:  reimplement to use logging...
    */
   public void reportError(RecognitionException exc)
   {
      super.reportError(exc);
   }
   
   /**
    * Provides a command line interface for an end user to drive and/or test
    * the HQLParser class.
    * <p>
    * Syntax:
    * <pre>
    *    java HQLParser &lt;expression&gt;
    * </pre>
    *
    * @param   args
    *          List of command line arguments.
    */
   public static void main(String[] args)
   {
      if (args.length != 1)
      {
         LOG.severe("Syntax: java HQLParser <expression>");
         System.exit(-1);
      }
         
      try
      {
         StringReader     expr       = new StringReader(args[0]);
         HQLLexer         lexer      = new HQLLexer(expr);
         HQLParser        parser     = new HQLParser(lexer);
         
         BaseAST.setVerboseStringConversion(true, _tokenNames);
         
         parser.expression();
         
         HQLAst result = (HQLAst) parser.getAST();
         
         result.fixups(null, null);
         
         // print out report
         visit(result, 0);
      }
       
      catch (Exception excpt)
      {
         LOG.severe("", excpt);
      }
   }

protected HQLParser(TokenBuffer tokenBuf, int k) {
  super(tokenBuf,k);
  tokenNames = _tokenNames;
  buildTokenTypeASTClassMap();
  astFactory = new ASTFactory(getTokenTypeToASTClassMap());
}

public HQLParser(TokenBuffer tokenBuf) {
  this(tokenBuf,3);
}

protected HQLParser(TokenStream lexer, int k) {
  super(lexer,k);
  tokenNames = _tokenNames;
  buildTokenTypeASTClassMap();
  astFactory = new ASTFactory(getTokenTypeToASTClassMap());
}

public HQLParser(TokenStream lexer) {
  this(lexer,3);
}

public HQLParser(ParserSharedInputState state) {
  super(state,3);
  tokenNames = _tokenNames;
  buildTokenTypeASTClassMap();
  astFactory = new ASTFactory(getTokenTypeToASTClassMap());
}

/**
 * Parses an HQL expression and creates an AST that is suitable for further
 * processing.  This is the main "entry point" for HQL expression parsing.
 * The AST node class is set here (to {@link HQLAst}).
 * <p>
 * The AST is structured with operator nodes as the root nodes and each
 * operator (unary or binary) has the matching number of child nodes (1 or
 * 2 respectively).  Each child node is an operand and the semantics of
 * left and right operands (for binary operators) is maintained.
 * <p>
 * Non-operator nodes in the tree can be literals or HQL functions.  The list
 * of literals can be seen in the {@link #literal} rule.
 * <p>
 * All of the following operators are supported and the precedence order
 * follows that of SQL, which we assume is the same precedence order used by
 * HQL (TODO:  confirm this with Hibernate sources).
 * <pre>
 * lowest  logical OR              :  or
 *    |    conditional AND         :  and
 *    |    equality                :  =
 *    |    relational              :  &lt;, &gt;, &le;, &ge;
 *    |    additive                :  +, -
 *    |    multiplicative          :  *, /
 *    |    unary operators         :  -, not
 *    |    function call           :  function_name(...)
 * highest parentheses             :  (...)
 * </pre>
 * <p>
 * To handle the precedence issue, each precedence level (see the table
 * above) is handled in a separate rule.  Starting at in this top level
 * entry point, the lowest precedence rule is referenced. This reference is
 * made with an optional <code>OR</code> operator.  If this operator is
 * present, it is the root of the resulting tree.  This means it is the
 * last operator to be evaluated since its operands will be processed
 * first.  This is the proper definition of lowest precedence.  If this
 * operator is present, then a second operand is expected.
 * <p>
 * Each precedence level is similarly constructed, the left operand being
 * required, all operators being optional and each operator choice an equal 
 * alternative. If any of the operators exists, then it is the root of the
 * subtree and a right operand is expected.  This holds true for all rules
 * that process binary operators.  Please note that this left-mandatory
 * and optional right side (operator + right operand) is critical for
 * allowing an expression to be as simple as a single variable, function
 * call or literal. Alternatively, it can expand into a highly nested set of
 * recursively parsed expressions that all evaluate to a single scalar result.
 * <p>
 * At the bottom of the hierarchy of rules are unary operators, these
 * are implemented as an optional prefix operator and a mandatory right
 * operand.
 * <p>
 * The final level is the primary expression.  This is where the precedence
 * operator parenthesis is handled.  It also is where we allow a single
 * literal, alias, or function reference.
 * <p>
 * The {@link #expr} rule is called as the only rule reference.
 * <p>
 */
	public final void expression() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst expression_AST = null;
		HQLAst e_AST = null;
		
		try {      // for error handling
			
			astFactory.setASTNodeClass(AST_CLASS);
			
			{
			expr();
			e_AST = (HQLAst)returnAST;
			astFactory.addASTChild(currentAST, returnAST);
			}
			expression_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_0);
		}
		returnAST = expression_AST;
	}
	
/**
 * Implements the lowest (1st) precedence level of expressions:
 * <code>OR</code> (the logical OR operator).  Valid expressions can contain
 * sub-expressions and this entry point is properly recursive without causing
 * any ambiguity.
 * <p>
 * This rule is designed to allow recursion (the highest precedence levels
 * {@link #function} and {@link #primary_expr} reference this rule again,
 * allowing infinite nesting of sub-expressions, with proper parsing,
 * evaluation and tree building.
 * <p>
 * This method is called by the top level {@link #expression} rule.  This
 * method calls the {@link #log_and_expr} rule.
 * <p>
 * Implements special processing for <code>NULL</code> equality and inequality
 * tests.  If a <code>NULL</code> token is detected on either side of either
 * of the operators, the result will be rooted at an <code>IS_NULL</code>
 * (equality) or <code>NOT_NULL</code> (inequality) node.  The operand that
 * is <code>NULL</code> will be dropped and the other operand will be the
 * only child.  This must be implemented after the entire tree is created 
 * and the method {@link #convertNullTest} is used to implement this
 * processing.
 * (TODO:  is this necessary?)
 */
	public final void expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst expr_AST = null;
		
		try {      // for error handling
			{
			log_and_expr();
			astFactory.addASTChild(currentAST, returnAST);
			{
			_loop6:
			do {
				if ((LA(1)==OR) && (_tokenSet_1.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
					HQLAst tmp1_AST = null;
					tmp1_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.makeASTRoot(currentAST, tmp1_AST);
					match(OR);
					log_and_expr();
					astFactory.addASTChild(currentAST, returnAST);
				}
				else {
					break _loop6;
				}
				
			} while (true);
			}
			}
			expr_AST = (HQLAst)currentAST.root;
			
			// convert all equality and inequality tests against the null
			// literal into a special operator
			convertNullTest((CommonAST) expr_AST);
			
			expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = expr_AST;
	}
	
/**
 * Implements the 2nd lowest precedence level of expressions: <code>AND</code>
 * (the logical AND operator).
 * <p>
 * This is only called by the {@link #expr} rule.  This method calls the
 * {@link #equality_expr} rule.
 */
	public final void log_and_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst log_and_expr_AST = null;
		
		try {      // for error handling
			equality_expr();
			astFactory.addASTChild(currentAST, returnAST);
			{
			_loop9:
			do {
				if ((LA(1)==AND) && (_tokenSet_1.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
					HQLAst tmp2_AST = null;
					tmp2_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.makeASTRoot(currentAST, tmp2_AST);
					match(AND);
					equality_expr();
					astFactory.addASTChild(currentAST, returnAST);
				}
				else {
					break _loop9;
				}
				
			} while (true);
			}
			log_and_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = log_and_expr_AST;
	}
	
/**
 * Implements the 3rd lowest precedence level of expressions - the equality
 * operators.
 * <p>
 * This is only called by the {@link #log_and_expr} rule.  This method
 * calls the {@link #compare_expr} rule.
 * <p>
 * Provides the following operators:
 * <pre>
 *    =        (equality)
 *    !=       (inequality)
 * </pre>
 */
	public final void equality_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst equality_expr_AST = null;
		Token  i = null;
		HQLAst i_AST = null;
		
		try {      // for error handling
			compare_expr();
			astFactory.addASTChild(currentAST, returnAST);
			{
			_loop15:
			do {
				if ((LA(1)==EQUALS||LA(1)==NOT_EQ) && (_tokenSet_1.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
					{
					{
					switch ( LA(1)) {
					case EQUALS:
					{
						HQLAst tmp3_AST = null;
						tmp3_AST = (HQLAst)astFactory.create(LT(1));
						astFactory.makeASTRoot(currentAST, tmp3_AST);
						match(EQUALS);
						break;
					}
					case NOT_EQ:
					{
						HQLAst tmp4_AST = null;
						tmp4_AST = (HQLAst)astFactory.create(LT(1));
						astFactory.makeASTRoot(currentAST, tmp4_AST);
						match(NOT_EQ);
						break;
					}
					default:
					{
						throw new NoViableAltException(LT(1), getFilename());
					}
					}
					}
					compare_expr();
					astFactory.addASTChild(currentAST, returnAST);
					}
				}
				else if ((LA(1)==IS) && (LA(2)==NOT||LA(2)==NULL) && (_tokenSet_4.member(LA(3)))) {
					i = LT(1);
					i_AST = (HQLAst)astFactory.create(i);
					astFactory.makeASTRoot(currentAST, i_AST);
					match(IS);
					i_AST.setType(IS_NULL);
					{
					switch ( LA(1)) {
					case NOT:
					{
						match(NOT);
						i_AST.setType(NOT_NULL);
						break;
					}
					case NULL:
					{
						break;
					}
					default:
					{
						throw new NoViableAltException(LT(1), getFilename());
					}
					}
					}
					match(NULL);
				}
				else {
					break _loop15;
				}
				
			} while (true);
			}
			equality_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = equality_expr_AST;
	}
	
/**
 * Implements the 4th lowest precedence level of expressions - the comparison
 * operators.
 * <p>
 * This is only called by the {@link #equality_expr} rule. This method calls
 * the {@link #concat_expr} rule.
 * <p>
 * Provides the following operators:
 * <pre>
 *    &gt;    (greater than)
 *    &lt;    (less than)
 *    &ge;   (greater than or equal to)
 *    &le;   (less than or equal to)
 *    like
 * </pre>
 */
	public final void compare_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst compare_expr_AST = null;
		
		try {      // for error handling
			
			boolean isLike = false;
			
			concat_expr();
			astFactory.addASTChild(currentAST, returnAST);
			{
			if ((LA(1)==IN) && (LA(2)==LPARENS) && (_tokenSet_1.member(LA(3)))) {
				HQLAst tmp7_AST = null;
				tmp7_AST = (HQLAst)astFactory.create(LT(1));
				astFactory.makeASTRoot(currentAST, tmp7_AST);
				match(IN);
				match(LPARENS);
				expr();
				astFactory.addASTChild(currentAST, returnAST);
				{
				_loop19:
				do {
					if ((LA(1)==COMMA)) {
						match(COMMA);
						expr();
						astFactory.addASTChild(currentAST, returnAST);
					}
					else {
						break _loop19;
					}
					
				} while (true);
				}
				match(RPARENS);
			}
			else if (((LA(1) >= GT && LA(1) <= LIKE)) && (_tokenSet_1.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
				{
				switch ( LA(1)) {
				case GT:
				{
					HQLAst tmp11_AST = null;
					tmp11_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.makeASTRoot(currentAST, tmp11_AST);
					match(GT);
					break;
				}
				case LT:
				{
					HQLAst tmp12_AST = null;
					tmp12_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.makeASTRoot(currentAST, tmp12_AST);
					match(LT);
					break;
				}
				case GTE:
				{
					HQLAst tmp13_AST = null;
					tmp13_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.makeASTRoot(currentAST, tmp13_AST);
					match(GTE);
					break;
				}
				case LTE:
				{
					HQLAst tmp14_AST = null;
					tmp14_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.makeASTRoot(currentAST, tmp14_AST);
					match(LTE);
					break;
				}
				case LIKE:
				{
					HQLAst tmp15_AST = null;
					tmp15_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.makeASTRoot(currentAST, tmp15_AST);
					match(LIKE);
					isLike = true;
					break;
				}
				default:
				{
					throw new NoViableAltException(LT(1), getFilename());
				}
				}
				}
				concat_expr();
				astFactory.addASTChild(currentAST, returnAST);
				{
				if (((LA(1)==ESCAPE) && (LA(2)==STRING) && (_tokenSet_3.member(LA(3))))&&( isLike )) {
					HQLAst tmp16_AST = null;
					tmp16_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.addASTChild(currentAST, tmp16_AST);
					match(ESCAPE);
					HQLAst tmp17_AST = null;
					tmp17_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.addASTChild(currentAST, tmp17_AST);
					match(STRING);
				}
				else if ((_tokenSet_3.member(LA(1))) && (_tokenSet_5.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
				}
				else {
					throw new NoViableAltException(LT(1), getFilename());
				}
				
				}
			}
			else if ((_tokenSet_3.member(LA(1))) && (_tokenSet_5.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
			}
			else {
				throw new NoViableAltException(LT(1), getFilename());
			}
			
			}
			compare_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = compare_expr_AST;
	}
	
/**
 * Implements the 5th lowest precedence level of expressions - concatenation.
 * <p>
 * This is only called by the {@link #compare_expr} rule. This method calls
 * the {@link #sum_expr} rule.
 * <p>
 * Provides the following operator:
 * <pre>
 *    ||   (concatenation of two string operands)
 * </pre>
 */
	public final void concat_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst concat_expr_AST = null;
		
		try {      // for error handling
			sum_expr();
			astFactory.addASTChild(currentAST, returnAST);
			{
			_loop24:
			do {
				if ((LA(1)==CONCAT) && (_tokenSet_1.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
					HQLAst tmp18_AST = null;
					tmp18_AST = (HQLAst)astFactory.create(LT(1));
					astFactory.makeASTRoot(currentAST, tmp18_AST);
					match(CONCAT);
					sum_expr();
					astFactory.addASTChild(currentAST, returnAST);
				}
				else {
					break _loop24;
				}
				
			} while (true);
			}
			concat_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = concat_expr_AST;
	}
	
/**
 * Implements the 5th lowest precedence level of expressions - the additive
 * operators.
 * <p>
 * This is only called by the {@link #compare_expr} rule. This method calls
 * the {@link #prod_expr} rule.
 * <p>
 * Provides the following operators:
 * <pre>
 *    + (binary plus)
 *    - (binary minus)
 * </pre>
 */
	public final void sum_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst sum_expr_AST = null;
		
		try {      // for error handling
			prod_expr();
			astFactory.addASTChild(currentAST, returnAST);
			{
			_loop28:
			do {
				if ((LA(1)==PLUS||LA(1)==MINUS) && (_tokenSet_1.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
					{
					switch ( LA(1)) {
					case PLUS:
					{
						HQLAst tmp19_AST = null;
						tmp19_AST = (HQLAst)astFactory.create(LT(1));
						astFactory.makeASTRoot(currentAST, tmp19_AST);
						match(PLUS);
						break;
					}
					case MINUS:
					{
						HQLAst tmp20_AST = null;
						tmp20_AST = (HQLAst)astFactory.create(LT(1));
						astFactory.makeASTRoot(currentAST, tmp20_AST);
						match(MINUS);
						break;
					}
					default:
					{
						throw new NoViableAltException(LT(1), getFilename());
					}
					}
					}
					prod_expr();
					astFactory.addASTChild(currentAST, returnAST);
				}
				else {
					break _loop28;
				}
				
			} while (true);
			}
			sum_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = sum_expr_AST;
	}
	
/**
 * Implements the 6th lowest precedence level of expressions - the
 * multiplicative operators.
 * <p>
 * This is only called by the {@link #sum_expr} rule. This method calls
 * the {@link #un_expr} rule.
 * <p>
 * Provides the following operators:
 * <pre>
 *    * (multiply)
 *    / (divide)
 * </pre>
 */
	public final void prod_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst prod_expr_AST = null;
		
		try {      // for error handling
			un_expr();
			astFactory.addASTChild(currentAST, returnAST);
			{
			_loop32:
			do {
				if ((LA(1)==MULTIPLY||LA(1)==DIVIDE) && (_tokenSet_1.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
					{
					switch ( LA(1)) {
					case MULTIPLY:
					{
						HQLAst tmp21_AST = null;
						tmp21_AST = (HQLAst)astFactory.create(LT(1));
						astFactory.makeASTRoot(currentAST, tmp21_AST);
						match(MULTIPLY);
						break;
					}
					case DIVIDE:
					{
						HQLAst tmp22_AST = null;
						tmp22_AST = (HQLAst)astFactory.create(LT(1));
						astFactory.makeASTRoot(currentAST, tmp22_AST);
						match(DIVIDE);
						break;
					}
					default:
					{
						throw new NoViableAltException(LT(1), getFilename());
					}
					}
					}
					un_expr();
					astFactory.addASTChild(currentAST, returnAST);
				}
				else {
					break _loop32;
				}
				
			} while (true);
			}
			prod_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = prod_expr_AST;
	}
	
/**
 * Implements the 7th lowest precedence level of expressions - the unary
 * operators.
 * <p>
 * This is only called by the {@link #prod_expr} rule. This method calls
 * the {@link #primary_expr} rule.
 * <p>
 * Provides the following operators:
 * <pre>
 *    -                  unary minus
 *    not                logical NOT
 * </pre>
 */
	public final void un_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst un_expr_AST = null;
		Token  m = null;
		HQLAst m_AST = null;
		
		try {      // for error handling
			
			String cls = null;
			
			{
			{
			switch ( LA(1)) {
			case MINUS:
			{
				m = LT(1);
				m_AST = (HQLAst)astFactory.create(m);
				astFactory.makeASTRoot(currentAST, m_AST);
				match(MINUS);
				m_AST.setType( UN_MINUS );
				break;
			}
			case NOT:
			{
				HQLAst tmp23_AST = null;
				tmp23_AST = (HQLAst)astFactory.create(LT(1));
				astFactory.makeASTRoot(currentAST, tmp23_AST);
				match(NOT);
				break;
			}
			case BOOL_FALSE:
			case BOOL_TRUE:
			case CASE:
			case CAST:
			case DEC_LITERAL:
			case FROM:
			case NULL:
			case SELECT:
			case LPARENS:
			case STRING:
			case SYMBOL:
			case NUM_LITERAL:
			case LONG_LITERAL:
			case SUBST:
			{
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			primary_expr();
			astFactory.addASTChild(currentAST, returnAST);
			}
			un_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = un_expr_AST;
	}
	
/**
 * Implements the 8th and highest precedence level of expressions, the
 * parenthesis precedence operators, {@link #literal}, {@link #function},
 * {@link #ternary}, {@link #property}, {@link #subselect}, and {@link
 * #parentheses} rules.
 * <p>
 * This rule is different in structure from the previous levels, as the
 * there is just a set of alternatives and one of them allows direct recursion
 * back to the <code>expr</code> expression entry point.
 * <p>
 * This is only called by the {@link #un_expr} rule.
 * <p>
 * See the rule {@link #expr} for more details.
 */
	public final void primary_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst primary_expr_AST = null;
		
		try {      // for error handling
			{
			switch ( LA(1)) {
			case BOOL_FALSE:
			case BOOL_TRUE:
			case DEC_LITERAL:
			case NULL:
			case STRING:
			case NUM_LITERAL:
			case LONG_LITERAL:
			case SUBST:
			{
				literal();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			case CAST:
			{
				cast();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			case CASE:
			{
				ternary();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			case FROM:
			case SELECT:
			{
				subselect();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			case LPARENS:
			{
				parentheses();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			default:
				if ((LA(1)==SYMBOL) && (LA(2)==LPARENS)) {
					function();
					astFactory.addASTChild(currentAST, returnAST);
				}
				else if ((LA(1)==SYMBOL) && (_tokenSet_6.member(LA(2)))) {
					property();
					astFactory.addASTChild(currentAST, returnAST);
				}
			else {
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			primary_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = primary_expr_AST;
	}
	
/**  
 * Matches all variations of expression literals (constants).  This includes:
 * <pre>
 *    NUM_LITERAL
 *    LONG_LITERAL
 *    DEC_LITERAL
 *    STRING
 *    BOOL_TRUE
 *    BOOL_FALSE
 *    NULL
 *    SUBST
 * </pre>
 */
	public final void literal() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst literal_AST = null;
		
		try {      // for error handling
			{
			switch ( LA(1)) {
			case NUM_LITERAL:
			{
				HQLAst tmp24_AST = null;
				tmp24_AST = (HQLAst)astFactory.create(LT(1));
				astFactory.addASTChild(currentAST, tmp24_AST);
				match(NUM_LITERAL);
				break;
			}
			case LONG_LITERAL:
			{
				HQLAst tmp25_AST = null;
				tmp25_AST = (HQLAst)astFactory.create(LT(1));
				astFactory.addASTChild(currentAST, tmp25_AST);
				match(LONG_LITERAL);
				break;
			}
			case DEC_LITERAL:
			{
				HQLAst tmp26_AST = null;
				tmp26_AST = (HQLAst)astFactory.create(LT(1));
				astFactory.addASTChild(currentAST, tmp26_AST);
				match(DEC_LITERAL);
				break;
			}
			case STRING:
			{
				HQLAst tmp27_AST = null;
				tmp27_AST = (HQLAst)astFactory.create(LT(1));
				astFactory.addASTChild(currentAST, tmp27_AST);
				match(STRING);
				break;
			}
			case BOOL_TRUE:
			{
				HQLAst tmp28_AST = null;
				tmp28_AST = (HQLAst)astFactory.create(LT(1));
				astFactory.addASTChild(currentAST, tmp28_AST);
				match(BOOL_TRUE);
				break;
			}
			case BOOL_FALSE:
			{
				HQLAst tmp29_AST = null;
				tmp29_AST = (HQLAst)astFactory.create(LT(1));
				astFactory.addASTChild(currentAST, tmp29_AST);
				match(BOOL_FALSE);
				break;
			}
			case NULL:
			{
				HQLAst tmp30_AST = null;
				tmp30_AST = (HQLAst)astFactory.create(LT(1));
				astFactory.addASTChild(currentAST, tmp30_AST);
				match(NULL);
				break;
			}
			case SUBST:
			{
				substitution();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			literal_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = literal_AST;
	}
	
/**
 * Matches HQL function signatures:  a SYMBOL followed by a parameter list in
 * parentheses.  The list may contain zero or more parameters, separated by
 * commas.  This rule is called by the {@link #primary_expr} rule.
 */
	public final void function() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst function_AST = null;
		Token  s = null;
		HQLAst s_AST = null;
		
		try {      // for error handling
			{
			s = LT(1);
			s_AST = (HQLAst)astFactory.create(s);
			astFactory.makeASTRoot(currentAST, s_AST);
			match(SYMBOL);
			match(LPARENS);
			{
			switch ( LA(1)) {
			case BOOL_FALSE:
			case BOOL_TRUE:
			case CASE:
			case CAST:
			case DEC_LITERAL:
			case FROM:
			case NOT:
			case NULL:
			case SELECT:
			case LPARENS:
			case STRING:
			case MINUS:
			case SYMBOL:
			case NUM_LITERAL:
			case LONG_LITERAL:
			case SUBST:
			{
				expr();
				astFactory.addASTChild(currentAST, returnAST);
				{
				_loop42:
				do {
					if ((LA(1)==COMMA)) {
						match(COMMA);
						expr();
						astFactory.addASTChild(currentAST, returnAST);
					}
					else {
						break _loop42;
					}
					
				} while (true);
				}
				break;
			}
			case RPARENS:
			{
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			match(RPARENS);
			s_AST.setType(FUNCTION);
			}
			function_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_7);
		}
		returnAST = function_AST;
	}
	
/**
 * Matches HQL cast signatures: the 'cast' token and LPARAM, followed by an expression, the 'as' token and a
 * SQL type. It end with parentheses. This rule is called by the {@link #primary_expr} rule.
 */
	public final void cast() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst cast_AST = null;
		HQLAst t_AST = null;
		
		try {      // for error handling
			{
			HQLAst tmp34_AST = null;
			tmp34_AST = (HQLAst)astFactory.create(LT(1));
			astFactory.makeASTRoot(currentAST, tmp34_AST);
			match(CAST);
			match(LPARENS);
			expr();
			astFactory.addASTChild(currentAST, returnAST);
			match(AS);
			expr();
			t_AST = (HQLAst)returnAST;
			astFactory.addASTChild(currentAST, returnAST);
			t_AST.setType(SQL_TYPE);
			match(RPARENS);
			}
			cast_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = cast_AST;
	}
	
/**
 * Matches a ternary expression which uses the CASE WHEN construct in its
 * ternary form.
 */
	public final void ternary() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst ternary_AST = null;
		Token  w = null;
		HQLAst w_AST = null;
		
		try {      // for error handling
			{
			match(CASE);
			w = LT(1);
			w_AST = (HQLAst)astFactory.create(w);
			astFactory.makeASTRoot(currentAST, w_AST);
			match(WHEN);
			expr();
			astFactory.addASTChild(currentAST, returnAST);
			match(THEN);
			expr();
			astFactory.addASTChild(currentAST, returnAST);
			match(ELSE);
			expr();
			astFactory.addASTChild(currentAST, returnAST);
			match(END);
			w_AST.setType(TERNARY);
			}
			ternary_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = ternary_AST;
	}
	
/**
 * Matches a qualified or unqualified property name, with an optional {@link
 * #subscript}.  This rule is called by the {@link #primary_expr} rule, but
 * only after the {@link #function} rule is invoked.  This order is necessary
 * to avoid ambiguity with the latter rule, which looks for a leading SYMBOL
 * token.
 */
	public final void property() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst property_AST = null;
		Token  s = null;
		HQLAst s_AST = null;
		
		try {      // for error handling
			{
			{
			if ((LA(1)==SYMBOL) && (LA(2)==DOT)) {
				s = LT(1);
				s_AST = (HQLAst)astFactory.create(s);
				astFactory.makeASTRoot(currentAST, s_AST);
				match(SYMBOL);
				match(DOT);
			}
			else if ((LA(1)==SYMBOL) && (_tokenSet_8.member(LA(2)))) {
			}
			else {
				throw new NoViableAltException(LT(1), getFilename());
			}
			
			}
			
			if (s_AST != null)
			{
			s_AST.setType(ALIAS);
			}
			
			unqprop();
			astFactory.addASTChild(currentAST, returnAST);
			}
			property_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = property_AST;
	}
	
/**
 * Matches a subselect phrase embedded within a where clause.  Called by
 * {@link #primary_expr} rule.
 */
	public final void subselect() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst subselect_AST = null;
		
		try {      // for error handling
			
			astFactory.makeASTRoot(currentAST, (HQLAst)astFactory.create(SUBSELECT,"subselect"));
			
			{
			{
			switch ( LA(1)) {
			case SELECT:
			{
				select_expr();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			case FROM:
			{
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			from_expr();
			astFactory.addASTChild(currentAST, returnAST);
			{
			switch ( LA(1)) {
			case JOIN:
			{
				join_expr();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			case EOF:
			case AND:
			case AS:
			case ELSE:
			case END:
			case ESCAPE:
			case IN:
			case IS:
			case OR:
			case THEN:
			case WHERE:
			case EQUALS:
			case NOT_EQ:
			case COMMA:
			case RPARENS:
			case GT:
			case LT:
			case GTE:
			case LTE:
			case LIKE:
			case CONCAT:
			case PLUS:
			case MINUS:
			case MULTIPLY:
			case DIVIDE:
			{
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			{
			switch ( LA(1)) {
			case WHERE:
			{
				where_expr();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			case EOF:
			case AND:
			case AS:
			case ELSE:
			case END:
			case ESCAPE:
			case IN:
			case IS:
			case OR:
			case THEN:
			case EQUALS:
			case NOT_EQ:
			case COMMA:
			case RPARENS:
			case GT:
			case LT:
			case GTE:
			case LTE:
			case LIKE:
			case CONCAT:
			case PLUS:
			case MINUS:
			case MULTIPLY:
			case DIVIDE:
			{
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			}
			subselect_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = subselect_AST;
	}
	
/**
 * Matches a subexpression enclosed in parentheses.  Called by {@link
 * #primary_expr} rule;  recursively calls {@link #expr} rule.
 */
	public final void parentheses() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst parentheses_AST = null;
		
		try {      // for error handling
			{
			HQLAst tmp43_AST = null;
			tmp43_AST = (HQLAst)astFactory.create(LT(1));
			astFactory.makeASTRoot(currentAST, tmp43_AST);
			match(LPARENS);
			expr();
			astFactory.addASTChild(currentAST, returnAST);
			match(RPARENS);
			}
			parentheses_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = parentheses_AST;
	}
	
/**
 * Matches an alias for a data model object, which is simply a SYMBOL,
 * optionally followed by a property.  This rule is called by the {@link
 * #primary_expr} rule, but only after the {@link #function} rule is invoked.
 * This order is necessary to avoid ambiguity with the latter rule, which
 * looks for a leading SYMBOL token.
 */
	public final void alias() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst alias_AST = null;
		Token  s = null;
		HQLAst s_AST = null;
		
		try {      // for error handling
			{
			s = LT(1);
			s_AST = (HQLAst)astFactory.create(s);
			astFactory.makeASTRoot(currentAST, s_AST);
			match(SYMBOL);
			s_AST.setType(ALIAS);
			{
			switch ( LA(1)) {
			case SYMBOL:
			{
				property();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			case EOF:
			{
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			}
			alias_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_0);
		}
		returnAST = alias_AST;
	}
	
/**
 * Matches an unqualified property name, with an optional {@link #subscript}.
 */
	public final void unqprop() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst unqprop_AST = null;
		Token  p = null;
		HQLAst p_AST = null;
		
		try {      // for error handling
			{
			p = LT(1);
			p_AST = (HQLAst)astFactory.create(p);
			astFactory.makeASTRoot(currentAST, p_AST);
			match(SYMBOL);
			{
			switch ( LA(1)) {
			case LBRACKET:
			{
				subscript();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			case EOF:
			case AND:
			case AS:
			case ELSE:
			case END:
			case ESCAPE:
			case IN:
			case IS:
			case OR:
			case THEN:
			case EQUALS:
			case NOT_EQ:
			case COMMA:
			case RPARENS:
			case GT:
			case LT:
			case GTE:
			case LTE:
			case LIKE:
			case CONCAT:
			case PLUS:
			case MINUS:
			case MULTIPLY:
			case DIVIDE:
			{
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			}
			p_AST.setType(PROPERTY);
			unqprop_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = unqprop_AST;
	}
	
/**
 * Matches a {@link #property} subscript, for array-type properties.
 */
	public final void subscript() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst subscript_AST = null;
		Token  n = null;
		HQLAst n_AST = null;
		
		try {      // for error handling
			{
			HQLAst tmp45_AST = null;
			tmp45_AST = (HQLAst)astFactory.create(LT(1));
			astFactory.makeASTRoot(currentAST, tmp45_AST);
			match(LBRACKET);
			{
			switch ( LA(1)) {
			case NUM_LITERAL:
			{
				n = LT(1);
				n_AST = (HQLAst)astFactory.create(n);
				astFactory.addASTChild(currentAST, n_AST);
				match(NUM_LITERAL);
				break;
			}
			case SUBST:
			{
				substitution();
				astFactory.addASTChild(currentAST, returnAST);
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			match(RBRACKET);
			}
			subscript_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = subscript_AST;
	}
	
/**
 * Matches a query substitution parameter placeholder.  The "index" annotation
 * is written to this node;  its value is the index of this placeholder among
 * all such placeholders encountered in a left to right traversal of the where
 * clause.
 */
	public final void substitution() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst substitution_AST = null;
		Token  s = null;
		HQLAst s_AST = null;
		
		try {      // for error handling
			{
			s = LT(1);
			s_AST = (HQLAst)astFactory.create(s);
			astFactory.addASTChild(currentAST, s_AST);
			match(SUBST);
			
			// Assign an index to this substitution parameter.
			s_AST.putAnnotation("index", Long.valueOf(nextSubstitutionIndex++));
			
			}
			substitution_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_9);
		}
		returnAST = substitution_AST;
	}
	
/**
 * Matches a select phrase embedded within a where clause as part of a
 * subselect statement.  Called by {@link #subselect} rule.
 */
	public final void select_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst select_expr_AST = null;
		
		try {      // for error handling
			HQLAst tmp47_AST = null;
			tmp47_AST = (HQLAst)astFactory.create(LT(1));
			astFactory.makeASTRoot(currentAST, tmp47_AST);
			match(SELECT);
			function();
			astFactory.addASTChild(currentAST, returnAST);
			select_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_10);
		}
		returnAST = select_expr_AST;
	}
	
/**
 * Matches a from phrase embedded within a where clause as part of a subselect statement.  Called by
 * {@link #subselect} rule.
 */
	public final void from_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst from_expr_AST = null;
		Token  t = null;
		HQLAst t_AST = null;
		
		try {      // for error handling
			HQLAst tmp48_AST = null;
			tmp48_AST = (HQLAst)astFactory.create(LT(1));
			astFactory.makeASTRoot(currentAST, tmp48_AST);
			match(FROM);
			t = LT(1);
			t_AST = (HQLAst)astFactory.create(t);
			astFactory.addASTChild(currentAST, t_AST);
			match(SYMBOL);
			t_AST.setType(DMO);
			{
			if ((LA(1)==AS) && (LA(2)==SYMBOL) && (_tokenSet_11.member(LA(3)))) {
				as_expr();
				astFactory.addASTChild(currentAST, returnAST);
			}
			else if ((_tokenSet_11.member(LA(1))) && (_tokenSet_5.member(LA(2))) && (_tokenSet_12.member(LA(3)))) {
			}
			else {
				throw new NoViableAltException(LT(1), getFilename());
			}
			
			}
			from_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_11);
		}
		returnAST = from_expr_AST;
	}
	
/**
 * Matches a join phrase embedded within a where clause as part of a subselect statement.  Called by
 * {@link #subselect} rule.
 */
	public final void join_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst join_expr_AST = null;
		Token  t = null;
		HQLAst t_AST = null;
		
		try {      // for error handling
			HQLAst tmp49_AST = null;
			tmp49_AST = (HQLAst)astFactory.create(LT(1));
			astFactory.makeASTRoot(currentAST, tmp49_AST);
			match(JOIN);
			t = LT(1);
			t_AST = (HQLAst)astFactory.create(t);
			astFactory.addASTChild(currentAST, t_AST);
			match(SYMBOL);
			t_AST.setType(DMO);
			{
			if ((LA(1)==AS) && (LA(2)==SYMBOL) && (_tokenSet_13.member(LA(3)))) {
				as_expr();
				astFactory.addASTChild(currentAST, returnAST);
			}
			else if ((_tokenSet_13.member(LA(1))) && (_tokenSet_5.member(LA(2))) && (_tokenSet_2.member(LA(3)))) {
			}
			else {
				throw new NoViableAltException(LT(1), getFilename());
			}
			
			}
			join_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_13);
		}
		returnAST = join_expr_AST;
	}
	
/**
 * Matches a where phrase embedded within a where clause as part of a
 * subselect statement.  Called by {@link #subselect} rule.  Recursively
 * calls {@link #expr} rule.
 */
	public final void where_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst where_expr_AST = null;
		
		try {      // for error handling
			HQLAst tmp50_AST = null;
			tmp50_AST = (HQLAst)astFactory.create(LT(1));
			astFactory.makeASTRoot(currentAST, tmp50_AST);
			match(WHERE);
			expr();
			astFactory.addASTChild(currentAST, returnAST);
			where_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_3);
		}
		returnAST = where_expr_AST;
	}
	
/**
 * Matches an as phrase, which is an optional assignment of an alias to a DMO
 * at the end of a from phrase.  Called by {@link #from_expr} rule.  This
 * portion of the phrase is optional if no other part of the subselect phrase
 * references an alias for the DMO.
 */
	public final void as_expr() throws RecognitionException, TokenStreamException {
		
		returnAST = null;
		ASTPair currentAST = new ASTPair();
		HQLAst as_expr_AST = null;
		Token  a = null;
		HQLAst a_AST = null;
		
		try {      // for error handling
			match(AS);
			a = LT(1);
			a_AST = (HQLAst)astFactory.create(a);
			astFactory.addASTChild(currentAST, a_AST);
			match(SYMBOL);
			a_AST.setType(ALIAS);
			as_expr_AST = (HQLAst)currentAST.root;
		}
		catch (RecognitionException ex) {
			reportError(ex);
			recover(ex,_tokenSet_11);
		}
		returnAST = as_expr_AST;
	}
	
	
	public static final String[] _tokenNames = {
		"<0>",
		"EOF",
		"<2>",
		"NULL_TREE_LOOKAHEAD",
		"ALIAS",
		"AND",
		"AS",
		"BOOL_FALSE",
		"BOOL_TRUE",
		"CASE",
		"CAST",
		"DEC_LITERAL",
		"DMO",
		"DOT",
		"ELSE",
		"END",
		"ESCAPE",
		"FROM",
		"FUNCTION",
		"IN",
		"INDEX",
		"IS",
		"IS_NULL",
		"JOIN",
		"NOT",
		"NOT_NULL",
		"NULL",
		"OR",
		"PROPERTY",
		"SELECT",
		"SUBSCRIPT",
		"SUBSELECT",
		"SQL_TYPE",
		"TERNARY",
		"THEN",
		"UN_MINUS",
		"WHERE",
		"WHEN",
		"EQUALS",
		"NOT_EQ",
		"LPARENS",
		"COMMA",
		"RPARENS",
		"GT",
		"LT",
		"GTE",
		"LTE",
		"LIKE",
		"STRING",
		"CONCAT",
		"PLUS",
		"MINUS",
		"MULTIPLY",
		"DIVIDE",
		"SYMBOL",
		"LBRACKET",
		"NUM_LITERAL",
		"RBRACKET",
		"LONG_LITERAL",
		"SUBST",
		"WS",
		"VALID_1ST_IDENT",
		"VALID_SYM_CHAR",
		"LETTER",
		"DIGIT",
		"SYM_CHAR"
	};
	
	protected void buildTokenTypeASTClassMap() {
		tokenTypeToASTClassMap=null;
	};
	
	private static final long[] mk_tokenSet_0() {
		long[] data = { 2L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0());
	private static final long[] mk_tokenSet_1() {
		long[] data = { 957297495925460864L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_1 = new BitSet(mk_tokenSet_1());
	private static final long[] mk_tokenSet_2() {
		long[] data = { 1008806197029760994L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_2 = new BitSet(mk_tokenSet_2());
	private static final long[] mk_tokenSet_3() {
		long[] data = { 17731566460059746L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_3 = new BitSet(mk_tokenSet_3());
	private static final long[] mk_tokenSet_4() {
		long[] data = { 17731566527168610L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_4 = new BitSet(mk_tokenSet_4());
	private static final long[] mk_tokenSet_5() {
		long[] data = { 972777262571835362L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_5 = new BitSet(mk_tokenSet_5());
	private static final long[] mk_tokenSet_6() {
		long[] data = { 53760363479031906L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_6 = new BitSet(mk_tokenSet_6());
	private static final long[] mk_tokenSet_7() {
		long[] data = { 17731566460190818L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_7 = new BitSet(mk_tokenSet_7());
	private static final long[] mk_tokenSet_8() {
		long[] data = { 53760363479023714L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_8 = new BitSet(mk_tokenSet_8());
	private static final long[] mk_tokenSet_9() {
		long[] data = { 161846754535915618L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_9 = new BitSet(mk_tokenSet_9());
	private static final long[] mk_tokenSet_10() {
		long[] data = { 131072L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_10 = new BitSet(mk_tokenSet_10());
	private static final long[] mk_tokenSet_11() {
		long[] data = { 17731635187925090L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_11 = new BitSet(mk_tokenSet_11());
	private static final long[] mk_tokenSet_12() {
		long[] data = { 1008806265749237730L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_12 = new BitSet(mk_tokenSet_12());
	private static final long[] mk_tokenSet_13() {
		long[] data = { 17731635179536482L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_13 = new BitSet(mk_tokenSet_13());
	
	}