options {

	  
       STATIC = false;
	
}


PARSER_BEGIN(AQLParser)

package edu.uci.ics.asterix.aql.parser;

import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Stack;

import java.util.Map;
import java.util.HashMap;
import edu.uci.ics.asterix.aql.literal.FloatLiteral;
import edu.uci.ics.asterix.aql.literal.DoubleLiteral;
import edu.uci.ics.asterix.aql.literal.FalseLiteral;
import edu.uci.ics.asterix.aql.base.ILiteral;
import edu.uci.ics.asterix.aql.literal.IntegerLiteral;
import edu.uci.ics.asterix.aql.literal.NullLiteral;
import edu.uci.ics.asterix.aql.literal.StringLiteral;
import edu.uci.ics.asterix.aql.literal.TrueLiteral;

import edu.uci.ics.asterix.aql.base.*;
import edu.uci.ics.asterix.aql.expression.*;
import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
import edu.uci.ics.asterix.aql.expression.visitor.AQLPrintVisitor;
import edu.uci.ics.asterix.aql.expression.UnaryExpr.Sign;
import edu.uci.ics.asterix.aql.base.Statement.Kind;
import edu.uci.ics.asterix.aql.context.Scope;
import edu.uci.ics.asterix.aql.context.RootScopeFactory;
import edu.uci.ics.asterix.common.annotations.*;
import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.om.functions.AsterixFunction;


public class AQLParser extends ScopeChecker {

/*
    private void printHints(Token t) {
       //System.err.println("token="+t.image+"\t special="+t.specialToken); 
       if (t.specialToken == null) return;
       Token tmp_t = t.specialToken;
       while (tmp_t.specialToken != null) tmp_t = tmp_t.specialToken;    
       while (tmp_t != null) {
         System.out.println(tmp_t.image);
         tmp_t = tmp_t.next;
       }
    }
*/
  
    // optimizer hints
    private static final String HASH_GROUP_BY_HINT = "hash";
    private static final String BROADCAST_JOIN_HINT = "bcast";
    private static final String INMEMORY_HINT = "inmem";
    private static final String VAL_FILE_HINT = "val-files";
    private static final String VAL_FILE_SAME_INDEX_HINT = "val-file-same-idx";
    private static final String INTERVAL_HINT = "interval";
    private static final String COMPOSE_VAL_FILES_HINT = "compose-val-files";
    private static final String INSERT_RAND_INT_HINT = "insert-rand-int";
    private static final String LIST_VAL_FILE_HINT = "list-val-file";
    private static final String LIST_HINT = "list";
    private static final String DATETIME_BETWEEN_YEARS_HINT = "datetime-between-years";
    private static final String DATE_BETWEEN_YEARS_HINT = "date-between-years";
    private static final String DATETIME_ADD_RAND_HOURS_HINT = "datetime-add-rand-hours";
    private static final String AUTO_HINT = "auto";   
        
    private static final String GEN_FIELDS_HINT = "gen-fields";   
    
    // data generator hints
    private static final String DGEN_HINT = "dgen";
   
    private static String getHint(Token t) {
       if (t.specialToken == null) {
         return null;
       }       
       String s = t.specialToken.image;
       int n = s.length();
       if (n < 2) {
         return null;
       }  
       return s.substring(1).trim();
    }

	public static void main(String args[]) throws ParseException, TokenMgrError, IOException, FileNotFoundException, AsterixException {
			File file = new File(args[0]);
			Reader fis = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
		    AQLParser parser = new AQLParser(fis);
		    Statement st = parser.Statement();
		    st.accept(new AQLPrintVisitor(), 0);
	}


}

PARSER_END(AQLParser)


Statement Statement() throws ParseException:
{
  Query query = null;
  scopeStack.push(RootScopeFactory.createRootScope(this));
  List<Statement> decls = new ArrayList<Statement>();
}
{
    (
      (
        ( 
          "use"
            {
              decls.add(DataverseDeclaration());
            }           
          | "declare" "function" { 
                              decls.add(FunctionDeclaration()); 
             }
	  	   |  "create" (
	  	   	  {
                String hint = getHint(token);
                boolean dgen = false;
         	   	if (hint != null && hint.startsWith(DGEN_HINT)) {
         	   	  dgen = true;
         	   	}                  
              } 
              "type"     
              	{ 
                              decls.add(TypeDeclaration(dgen, hint)); 
                 }
              | "nodegroup" 
              	{
                              decls.add(NodegroupDeclaration());
                }   
              | "external" <DATASET>
            	{   
              		decls.add(DatasetDeclaration(DatasetType.EXTERNAL));
            	}
              | "feed" <DATASET>
                {
                   decls.add(DatasetDeclaration(DatasetType.FEED)); 	
            	}
              | <DATASET>
          		{
            		decls.add(DatasetDeclaration(DatasetType.INTERNAL));
          		}
              | "index" 
              	{
              				decls.add(CreateIndexStatement());
                 }
	          | "dataverse"
          		{
            		decls.add(CreateDataverseStatement());
          		}
          	  | "function"
          	    {
          	        decls.add(FunctionCreation());
          	    }	
            )        
         	 | "load" {
                       decls.add(LoadStatement());
                   }  
          	                    
          	| "drop"
			(
          	<DATASET>
          	{
            		decls.add(DropStatement());
          	}
        	| "index"
          	{
            		decls.add(IndexDropStatement());
          	}
        	| "nodegroup"
          	{
            		decls.add(NodeGroupDropStatement());
          	}
        	| "type"
          	{
            		decls.add(TypeDropStatement());
          	}
        	| "dataverse"
          	{
            		decls.add(DataverseDropStatement());
          	}
        	)
          | "write" {
                       decls.add(WriteStatement());
                    }              
          | "set" {
                       decls.add(SetStatement());
                    }                                                      
	  	  | "insert" {
		       decls.add(InsertStatement());
			}
          | "delete" {
			decls.add(DeleteStatement());
		    }
          | "update" {
	  		decls.add(UpdateStatement());		
	  	    } 
	  	  | "begin" "feed"  <IDENTIFIER> {
	  	    Identifier datasetName = new Identifier(token.image); 
	  	    decls.add(new BeginFeedStatement(datasetName, getVarCounter()));
	  	   } ";"
	  	  | "suspend" "feed"  <IDENTIFIER> {
	  	    datasetName = new Identifier(token.image); 
	  	    decls.add(new ControlFeedStatement(ControlFeedStatement.OperationType.SUSPEND, datasetName));
	  	   } ";"
	  	   | "resume" "feed"  <IDENTIFIER> {
	  	    datasetName = new Identifier(token.image); 
	  	    decls.add(new ControlFeedStatement(ControlFeedStatement.OperationType.RESUME, datasetName));
	  	   } ";"
	  	   | "end" "feed"  <IDENTIFIER> {
	  	    datasetName = new Identifier(token.image); 
	  	    decls.add(new ControlFeedStatement(ControlFeedStatement.OperationType.END, datasetName));
	  	   } ";" 
	  	   | "alter" "feed" <IDENTIFIER> {
             datasetName = new Identifier(token.image);
             decls.add(AlterFeedDeclaration(datasetName));
           }             
                                                     
        )*
        (query = Query())?
      )

      <EOF>
    )
    {
      if (query == null) {
        query = new Query(true);
      }
      query.setPrologDeclList(decls);
    
      return query;
    }
}

InsertStatement InsertStatement() throws ParseException:
{
	Identifier datasetName;
	Query query;
}
{
   "into" <DATASET> <IDENTIFIER> { datasetName = new Identifier(token.image); }
     		<LEFTPAREN> query = Query() <RIGHTPAREN> ";"
   {return new InsertStatement(datasetName, query,  getVarCounter());}
}

DeleteStatement DeleteStatement() throws ParseException:
{
	VariableExpr var = null;
    Identifier datasetName = null;
	Expression condition = null;
	Clause dieClause = null;
}
{
   var = Variable() { getCurrentScope().addNewVarSymbolToScope(var.getVar());  }
	    "from" <DATASET> <IDENTIFIER> { datasetName = new Identifier(token.image); }
	    ("where" condition = Expression())?  (dieClause = DieClause())? ";"
   {return new DeleteStatement(var, datasetName, condition,  dieClause, getVarCounter()); }
}

UpdateStatement UpdateStatement() throws ParseException:
{
	VariableExpr vars;
    Expression target;
	Expression condition;
	UpdateClause uc;
 	List<UpdateClause> ucs = new ArrayList<UpdateClause>();
}
{
   vars = Variable()  "in" target = Expression()
	"where" condition = Expression() 
	<LEFTPAREN> (uc=UpdateClause() {ucs.add(uc); }  ("," uc=UpdateClause() {ucs.add(uc); } )*) <RIGHTPAREN> ";"
   {return new UpdateStatement(vars, target, condition, ucs);}
}



UpdateClause UpdateClause() throws ParseException:
{
	Expression target = null;
	Expression value = null ;	
	InsertStatement is = null;
	DeleteStatement ds = null;
	UpdateStatement us = null;
	Expression condition = null;
	UpdateClause ifbranch = null;
	UpdateClause elsebranch = null;
}
{
   "set" target = Expression() ":=" value = Expression() 
   | "insert" is = InsertStatement()
   | "delete" ds = DeleteStatement()
   | "update" us = UpdateStatement()
   | "if" <LEFTPAREN> condition = Expression() <RIGHTPAREN> "then" ifbranch = UpdateClause() [LOOKAHEAD(1) "else" elsebranch = UpdateClause()] 
   {return new UpdateClause(target, value, is, ds, us, condition, ifbranch, elsebranch);}
}


Statement SetStatement() throws ParseException:
{
  String pn = null;
  Statement stmt = null;
}
{
  <IDENTIFIER>  { pn = token.image; }  
  <STRING_LITERAL>
    { String pv = removeQuotesAndEscapes(token.image); }
    ";"
  {
    return new SetStatement(pn, pv);
  }
}

Statement WriteStatement() throws ParseException:
{
  Identifier nodeName = null;
  String fileName = null;
  Identifier datasetName = null;
  Statement stmt = null;
  Query query;
  String writerClass = null;
}
{
  (( "output" "to" 
    <IDENTIFIER> { nodeName = new Identifier(token.image); } 
    ":" <STRING_LITERAL> { fileName = removeQuotesAndEscapes(token.image); }
    ( "using" <STRING_LITERAL> { writerClass = removeQuotesAndEscapes(token.image); } )?
         {                  
             stmt = new WriteStatement(nodeName, fileName, writerClass);         
         } )
    |
   ( "into" 
     <DATASET> <IDENTIFIER> { datasetName = new Identifier(token.image); }
     <LEFTPAREN> query = Query() <RIGHTPAREN>
     {
        stmt = new WriteFromQueryResultStatement(datasetName, query, getVarCounter());
     } ))  
        
    ";"
    {
      return stmt;
    }
}

CreateIndexStatement CreateIndexStatement() throws ParseException:
{
  CreateIndexStatement cis = new CreateIndexStatement();
}
{
  <IDENTIFIER> { cis.setIndexName(new Identifier(token.image)); }
  (
    "if not exists"
    {
      cis.setIfNotExists(true);
    }
  )?
  "on"  
  <IDENTIFIER> { cis.setDatasetName(new Identifier(token.image)); }
  <LEFTPAREN>
  	( <IDENTIFIER> { cis.addFieldExpr(token.image); } )
  	("," <IDENTIFIER> { cis.addFieldExpr(token.image); })*
  <RIGHTPAREN>
    ("type"
  		("btree" { cis.setIndexType(IndexType.BTREE); }
  		| "keyword" { cis.setIndexType(IndexType.KEYWORD); }
  		| "qgram" { cis.setIndexType(IndexType.QGRAM); } 
  		| "rtree" { cis.setIndexType(IndexType.RTREE); }   		  		  
		)  
  	";"  	
  	| ";"
    )
   {
     return cis;
   }
}

DataverseDecl DataverseDeclaration() throws ParseException:
{
  Identifier dvName = null;  
}
{
  "dataverse" <IDENTIFIER> { dvName = new Identifier(token.image); }
  ";"
  {
    return new DataverseDecl(dvName);
  }
}

DropStatement DropStatement() throws ParseException :
{
  Identifier datasetName = null;
  boolean ifExists = false;
}
{
  < IDENTIFIER >
  {
    datasetName = new Identifier(token.image);
  }
  (
    "if exists"
    {
      ifExists = true;
    }
  )? ";"
  {
    return new DropStatement(datasetName, ifExists);
  }
}

IndexDropStatement IndexDropStatement() throws ParseException :
{
  Identifier datasetName = null;
  Identifier indexName = null;
  boolean ifExists = false;
}
{
  < IDENTIFIER >
  {
    datasetName = new Identifier(token.image);
  }
  "." < IDENTIFIER >
  {
    indexName = new Identifier(token.image);
  }
  (
    "if exists"
    {
      ifExists = true;
    }
  )? ";"
  {
    return new IndexDropStatement(datasetName, indexName, ifExists);
  }
}

NodeGroupDropStatement NodeGroupDropStatement() throws ParseException :
{
  Identifier groupName = null;
  boolean ifExists = false;
}
{
  < IDENTIFIER >
  {
    groupName = new Identifier(token.image);
  }
  (
    "if exists"
    {
      ifExists = true;
    }
  )? ";"
  {
    return new NodeGroupDropStatement(groupName, ifExists);
  }
}

TypeDropStatement TypeDropStatement() throws ParseException :
{
  Identifier typeName = null;
  boolean ifExists = false;
}
{
  < IDENTIFIER >
  {
    typeName = new Identifier(token.image);
  }
  (
    "if exists"
    {
      ifExists = true;
    }
  )? ";"
  {
    return new TypeDropStatement(typeName, ifExists);
  }
}

DataverseDropStatement DataverseDropStatement() throws ParseException :
{
  Identifier dataverseName = null;
  boolean ifExists = false;
}
{
  < IDENTIFIER >
  {
    dataverseName = new Identifier(token.image);
  }
  (
    "if exists"
    {
      ifExists = true;
    }
  )? ";"
  {
    return new DataverseDropStatement(dataverseName, ifExists);
  }
}

CreateDataverseStatement CreateDataverseStatement() throws ParseException :
{
  Identifier dvName = null;
  boolean ifNotExists = false;
  String format = null;
}
{
  < IDENTIFIER >
  {
    dvName = new Identifier(token.image);
  }
  (
    "if not exists"
    {
      ifNotExists = true;
    }
  )?
  (
    "with format" < STRING_LITERAL >
    {
      format = removeQuotesAndEscapes(token.image);
    }
  )?
  ";"
  {
    return new CreateDataverseStatement(dvName, format, ifNotExists);
  }
}

LoadFromFileStatement LoadStatement() throws ParseException:
{
  Identifier datasetName = null;
  boolean alreadySorted = false;
  String adapterClassname;
  Map<String,String> properties;
}
{
   <DATASET> <IDENTIFIER> { datasetName = new Identifier(token.image); }
 
   "using"

    <STRING_LITERAL>
    {
      adapterClassname = removeQuotesAndEscapes(token.image);
    }

    {
      properties = getConfiguration();
    }
  
    ("pre-sorted" 
      {  alreadySorted = true; }
    )?
        
  ";"
  {
     return new LoadFromFileStatement(datasetName, adapterClassname, properties, alreadySorted);
  }   
}



DatasetDecl DatasetDeclaration(DatasetType datasetType) throws ParseException :
{
  DatasetDecl dd = null;
  Identifier datasetName = null;
  Identifier itemTypeName = null;
  boolean ifNotExists = false;
  IDatasetDetailsDecl idd = null;
}
{
  < IDENTIFIER >
  {
    datasetName = new Identifier(token.image);
  }
  (
    "if not exists"
    {
      ifNotExists = true;
    }
  )?
  (
  	< LEFTPAREN > < IDENTIFIER >
  	{
    	itemTypeName = new Identifier(token.image);
  	}
  	< RIGHTPAREN >
  )?
  {
  	  if(datasetType == DatasetType.INTERNAL) {
      	idd = InternalDatasetDeclaration();
      	dd = new DatasetDecl(datasetName, itemTypeName, idd, ifNotExists);
      }
      else if(datasetType == DatasetType.EXTERNAL) {
      	idd = ExternalDatasetDeclaration();
      	dd = new DatasetDecl(datasetName, itemTypeName, idd,ifNotExists);
      }
      else if(datasetType == DatasetType.FEED) {
      	idd = FeedDatasetDeclaration();
      	dd = new DatasetDecl(datasetName, itemTypeName, idd,ifNotExists);
      }
      dd.setDatasetType(datasetType);
  }
  {
    return dd;
  }
}

InternalDetailsDecl InternalDatasetDeclaration() throws ParseException :
{
    InternalDetailsDecl idd = null;
}
{
  {
    idd = new InternalDetailsDecl();
  }
  "partitioned" "by" "key"
  < IDENTIFIER >
  {
    	 idd.addPartitioningExpr(token.image);
  }
  (
    "," < IDENTIFIER >
    {
      	idd.addPartitioningExpr(token.image);
    }
  )*
  (
  "on" < IDENTIFIER >
    {
    	idd.setNodegroupName(new Identifier(token.image));
    }
  )?
  ";"
  {
    return idd;
  }
}

ExternalDetailsDecl ExternalDatasetDeclaration() throws ParseException :
{
  ExternalDetailsDecl edd = null;
  String adapterClassname = null;
  Map < String, String > properties;
}
{
  {
    edd = new ExternalDetailsDecl();
  }
 
    "using"
    
     <STRING_LITERAL>
    {
      adapterClassname = removeQuotesAndEscapes(token.image);
    }

    {
      properties = getConfiguration();
    }

    {
    	  edd = new ExternalDetailsDecl();
		  edd.setAdapter(adapterClassname);
   		  edd.setProperties(properties);
    } 
  ";"
 
  {
    return edd;
  }
}

FeedDetailsDecl FeedDatasetDeclaration() throws ParseException :
{
    FeedDetailsDecl fdd = null;
    String adapterClassname = null;
    Map < String, String > properties;
}
{
  {
    fdd = new FeedDetailsDecl();
  }
  
   "using"
   
    <STRING_LITERAL>
    {
      adapterClassname = removeQuotesAndEscapes(token.image);
    }

    {
      properties = getConfiguration();
    }
  
  ("apply" "function" 
  < IDENTIFIER >
  {
      fdd.setFunctionIdentifier(token.image);
  }
  )?
  
  "partitioned" "by" "key"
  < IDENTIFIER >
  {
    	 fdd.addPartitioningExpr(token.image);
  }
  (
    "," < IDENTIFIER >
    {
      	fdd.addPartitioningExpr(token.image);
    }
  )*
  (
  "on" < IDENTIFIER >
  {
    	fdd.setNodegroupName(new Identifier(token.image));
  }
  )?
  ";"
  {
    fdd.setAdapterClassname(adapterClassname);
    fdd.setProperties(properties);
    return fdd;
  }
}

ControlFeedStatement AlterFeedDeclaration(Identifier datasetName) throws ParseException :
{
    String name = null;
    String value = null;
    Map < String, String > configuration = new HashMap < String, String > ();
}
{
   "set"
   { 
   configuration = getConfiguration();
   }
  ";"
  {
    return new ControlFeedStatement(ControlFeedStatement.OperationType.ALTER, datasetName, configuration);
  }
}

Map<String,String> getConfiguration()  throws ParseException :
{
	Map<String,String> configuration = new HashMap<String,String>();
	String key;
	String value;
}
{

<LEFTPAREN>
    (
      (
        <LEFTPAREN>
        (
          <STRING_LITERAL>
          {
            key = removeQuotesAndEscapes(token.image);
          }
          "=" <STRING_LITERAL>
          {
            value = removeQuotesAndEscapes(token.image);
          }
        )
        <RIGHTPAREN>
        {
          configuration.put(key, value);
        }
      )
      (
        "," <LEFTPAREN>
        (
          <STRING_LITERAL>
          {
            key = removeQuotesAndEscapes(token.image);
          }
          "=" <STRING_LITERAL>
          {
            value = removeQuotesAndEscapes(token.image);
          }
        )
        <RIGHTPAREN>
        {
          configuration.put(key, value);
        }
      )*
    )?
    <RIGHTPAREN>
     {
     	return configuration;
     }
}


NodegroupDecl NodegroupDeclaration() throws ParseException :
{
  Identifier name = null;
  List < Identifier > ncNames = new ArrayList < Identifier > ();
  boolean ifNotExists = false;
}
{
  < IDENTIFIER >
  {
    name = new Identifier(token.image);
  }
  (
    "if not exists"
    { 
      ifNotExists = true;
    }
  )?
  "on" < IDENTIFIER >
  {
    ncNames.add(new Identifier(token.image));
  }
  (
    "," < IDENTIFIER >
    {
      ncNames.add(new Identifier(token.image));
    }
  )*
  ";"
  {
    return new NodegroupDecl(name, ncNames, ifNotExists);
  }
}


TypeDecl TypeDeclaration(boolean dgen, String hint) throws ParseException:
{
  Identifier ident;
  TypeExpression typeExpr;
  boolean ifNotExists = false;
}
{
  <IDENTIFIER>
  {
    ident = new Identifier(token.image.toString());
  }
  (
    "if not exists"
    {
      ifNotExists = true;
    }
  )?
  "as"
  ( typeExpr = TypeExpr() )
  {
    long numValues = -1;
    String filename = null;
    if (dgen) {       
      String splits[] = hint.split(" +");
      if (splits.length != 3) {
        throw new ParseException("Expecting /*+ dgen <filename> <numberOfItems> */");
      } 
      filename = splits[1];
      numValues = Long.parseLong(splits[2]);
    }  
    TypeDataGen tddg = new TypeDataGen(dgen, filename, numValues);
    return new TypeDecl(ident, typeExpr, tddg, ifNotExists);
  }
}

TypeExpression TypeExpr() throws ParseException:
{
  TypeExpression typeExpr = null;
}
{
  (
      typeExpr = RecordTypeDef()
    | typeExpr = TypeReference()
    | typeExpr = OrderedListTypeDef()
    | typeExpr = UnorderedListTypeDef()  
  )  
  {
    return typeExpr;
  }
}

RecordTypeDefinition RecordTypeDef() throws ParseException:
{
  RecordTypeDefinition recType = new RecordTypeDefinition();
  RecordTypeDefinition.RecordKind recordKind = null; 
}
{
  ( "closed" { recordKind = RecordTypeDefinition.RecordKind.CLOSED; } 
    | "open" { recordKind = RecordTypeDefinition.RecordKind.OPEN; } )?
   "{"
    {
      String hint = getHint(token);
      if (hint != null) { 
        String splits[] = hint.split(" +");
        if (splits[0].equals(GEN_FIELDS_HINT)) {
          if (splits.length != 5) {
            throw new ParseException("Expecting: /*+ gen-fields <type> <min> <max> <prefix>*/");
          }
          if (!splits[1].equals("int")) {
            throw new ParseException("The only supported type for gen-fields is int.");
          } 
          UndeclaredFieldsDataGen ufdg = new UndeclaredFieldsDataGen(UndeclaredFieldsDataGen.Type.INT, 
             Integer.parseInt(splits[2]), Integer.parseInt(splits[3]), splits[4]);
          recType.setUndeclaredFieldsDataGen(ufdg);   
        }
      }  
      
    }
		( 
		  RecordField(recType)
		  ( ","  RecordField(recType) )*
		)?
   "}"
   {
      if (recordKind == null) {
        recordKind = RecordTypeDefinition.RecordKind.OPEN;
      }
      recType.setRecordKind(recordKind);
      return recType;
   } 
}

void RecordField(RecordTypeDefinition recType) throws ParseException:
{
        String fieldName;
        TypeExpression type = null; 
        boolean nullable = false;
}
{
      <IDENTIFIER>
      	{
	     Token t = getToken(0);
	     fieldName = t.toString();	     	     
         String hint = getHint(t);
         IRecordFieldDataGen rfdg = null;
         if (hint != null) { 
           String splits[] = hint.split(" +");
           if (splits[0].equals(VAL_FILE_HINT)) { 
             File[] valFiles = new File[splits.length - 1];
             for (int k=1; k<splits.length; k++) {
               valFiles[k-1] = new File(splits[k]);
             } 
             rfdg = new FieldValFileDataGen(valFiles);
           } else if (splits[0].equals(VAL_FILE_SAME_INDEX_HINT)) {
             rfdg = new FieldValFileSameIndexDataGen(new File(splits[1]), splits[2]);
           } else if (splits[0].equals(LIST_VAL_FILE_HINT)) {
             rfdg = new ListValFileDataGen(new File(splits[1]), Integer.parseInt(splits[2]), Integer.parseInt(splits[3]));
           } else if (splits[0].equals(LIST_HINT)) {
             rfdg = new ListDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
           } else if (splits[0].equals(INTERVAL_HINT)) {
             FieldIntervalDataGen.ValueType vt;
             if (splits[1].equals("int")) {
               vt = FieldIntervalDataGen.ValueType.INT;
             } else if (splits[1].equals("long")) {
               vt = FieldIntervalDataGen.ValueType.LONG;
             } else if (splits[1].equals("float")) {
               vt = FieldIntervalDataGen.ValueType.FLOAT;
             } else if (splits[1].equals("double")) {
               vt = FieldIntervalDataGen.ValueType.DOUBLE;
             } else {
               throw new ParseException("Unknown type for interval data gen: " + splits[1]);
             }
             rfdg = new FieldIntervalDataGen(vt, splits[2], splits[3]); 
           } else if (splits[0].equals(INSERT_RAND_INT_HINT)) {
             rfdg = new InsertRandIntDataGen(splits[1], splits[2]);
           } else if (splits[0].equals(DATE_BETWEEN_YEARS_HINT)) {
             rfdg = new DateBetweenYearsDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
           } else if (splits[0].equals(DATETIME_BETWEEN_YEARS_HINT)) {
             rfdg = new DatetimeBetweenYearsDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
           } else if (splits[0].equals(DATETIME_ADD_RAND_HOURS_HINT)) {
             rfdg = new DatetimeAddRandHoursDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]), splits[3]);
           } else if (splits[0].equals(AUTO_HINT)) {
              rfdg = new AutoDataGen(splits[1]);
           }
         }
	    }
	  ":"
	  ( type =  TypeExpr() )
	  ("?" { nullable = true; } )?
	  {
	     recType.addField(fieldName, type, nullable, rfdg);
	  }   
}

TypeReferenceExpression TypeReference() throws ParseException:
{}
{
  <IDENTIFIER>
  	{
	  Token t = getToken(0);
	  Identifier id = new Identifier(t.toString());
	  return new TypeReferenceExpression(id);
	}      
}

OrderedListTypeDefinition OrderedListTypeDef() throws ParseException:
{  
  TypeExpression type = null;
}
{
  "["
    ( type =  TypeExpr() )
  "]"
  {
    return new OrderedListTypeDefinition(type);
  }
}


UnorderedListTypeDefinition UnorderedListTypeDef() throws ParseException:
{  
  TypeExpression type = null;
}
{
  "{{"
    ( type =  TypeExpr() )
  "}}"
  {
    return new UnorderedListTypeDefinition(type);
  }
}


FunctionDecl FunctionDeclaration() throws ParseException:
{
  FunctionDecl func = new FunctionDecl();
  AsterixFunction ident;
  String functionName;
  int arity = 0;
  List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
  Expression funcBody;
  VarIdentifier var = null;
  createNewScope();
}
{

    <IDENTIFIER>
	{
	  Token t = getToken(0);
	  functionName = t.toString();
	}
    <LEFTPAREN> (<VARIABLE>
    {
      var = new VarIdentifier();
      var.setValue(getToken(0).toString());
      paramList.add(var);
      getCurrentScope().addNewVarSymbolToScope(var);
      arity++;
    }
    ("," <VARIABLE>
    {
      var = new VarIdentifier();
      var.setValue(getToken(0).toString());
      paramList.add(var);
      getCurrentScope().addNewVarSymbolToScope(var);
      arity++;
    })*)? <RIGHTPAREN> "{" funcBody = Expression() "}"

    {
      ident = new AsterixFunction(functionName,arity);
      getCurrentScope().addFunctionDescriptor(ident, false);
      func.setIdent(ident);
      func.setFuncBody(funcBody);
      func.setParamList(paramList);
      return func;
    }
}

CreateFunctionStatement FunctionCreation() throws ParseException:
{
  CreateFunctionStatement cfs = null;
  AsterixFunction ident;
  String functionName;
  int arity = 0;
  boolean ifNotExists = false;
  List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
  String funcBody;
  VarIdentifier var = null;
  createNewScope();
}
{

    <IDENTIFIER>
	{
	  Token t = getToken(0);
	  functionName= t.toString();
	}
	
	(
      "if not exists"
       {
         ifNotExists = true;
       }
    )?
	
    <LEFTPAREN> (<VARIABLE>
    {
      var = new VarIdentifier();
      var.setValue(getToken(0).toString());
      paramList.add(var);
      getCurrentScope().addNewVarSymbolToScope(var);
      arity++;
    }
    ("," <VARIABLE>
    {
      var = new VarIdentifier();
      var.setValue(getToken(0).toString());
      paramList.add(var);
      getCurrentScope().addNewVarSymbolToScope(var);
      arity++;
    })*)? <RIGHTPAREN>  "{" <STRING_LITERAL>
          {
            funcBody = removeQuotesAndEscapes(token.image);
          }
          "}"
    {
      ident = new AsterixFunction(functionName, arity);
      getCurrentScope().addFunctionDescriptor(ident, false);
      cfs = new CreateFunctionStatement(ident, paramList, funcBody, ifNotExists);
      return cfs;
    }
}



Query Query()throws ParseException:
{
  Query query = new Query();
  Expression expr;
}
{
    expr = Expression()

    {
      query.setBody(expr);
      return query;
    }
}



Expression Expression():
{
  Expression expr = null;
  Expression exprP = null;
}
{
(
  
//OperatorExpr | IfThenElse | FLWOGRExpression | QuantifiedExpression
    expr = OperatorExpr()
    | expr = IfThenElse()
    | expr = FLWOGR()
    | expr = QuantifiedExpression()


)
	{
	  return (exprP==null) ? expr : exprP;
	}
}



Expression OperatorExpr()throws ParseException:
{
  OperatorExpr op = null;
  Expression operand = null;
}
{
	operand = AndExpr()
	(
	
	  "or"
  	{
  	  if (op == null) {
  	    op = new OperatorExpr();
  	    op.addOperand(operand);
	    op.setCurrentop(true);  	      	     
  	  }  
  	  Token t = getToken(0);
      op.addOperator(t.toString());
	}

	operand = AndExpr()
	{
	  op.addOperand(operand);
	}

	)*
	
	{
	  return op==null? operand: op;
	}
}

Expression AndExpr()throws ParseException:
{
  OperatorExpr op = null;
  Expression operand = null;
}
{
	operand = RelExpr()
	(
	
	  "and"
  	{
  	  if (op == null) {
  	    op = new OperatorExpr();
  	    op.addOperand(operand);
	    op.setCurrentop(true);  	      	     
  	  }  
  	  Token t = getToken(0);
      op.addOperator(t.toString());
	}

	operand = RelExpr()
	{
	  op.addOperand(operand);
	}

	)*
	
	{
	  return op==null? operand: op;
	}
}



Expression RelExpr()throws ParseException:
{
  OperatorExpr op = null;
  Expression operand = null;
  boolean broadcast = false;
}
{
    operand = AddExpr()
    {
      if (operand instanceof VariableExpr) {
        String hint = getHint(token);
        if (hint != null && hint.equals(BROADCAST_JOIN_HINT)) {
          broadcast = true;       
        }
      }
    } 

    (
      LOOKAHEAD(2)( "<" | ">" | "<=" | ">=" | "=" | "!=" |"~=")
  	  {
  	    if (op == null) {
  	      op = new OperatorExpr();
  	      op.addOperand(operand, broadcast);
          op.setCurrentop(true);
          broadcast = false;
  	    }   
  	    Token t = getToken(0);
        op.addOperator(t.toString());
	  }
	  
 	  operand = AddExpr()
	  {
         broadcast = false;
	     if (operand instanceof VariableExpr) {
           String hint = getHint(token);
           if (hint != null && hint.equals(BROADCAST_JOIN_HINT)) {
             broadcast = true;
           }
         } 
         op.addOperand(operand, broadcast);
      } 
    )?
 	
 	{
 	  return op==null? operand: op;
 	}
}

Expression AddExpr()throws ParseException:
{
  OperatorExpr op = null;
  Expression operand = null;  
}
{
	operand = MultExpr()

	( ("+" | "-")
  	{
  	  if (op == null) {
  	    op = new OperatorExpr();
        op.addOperand(operand);  	    
        op.setCurrentop(true);        
  	  } 
  	  Token t = getToken(0);
	  ((OperatorExpr)op).addOperator(t.toString());
	}

	operand = MultExpr()
	{
	  op.addOperand(operand);
	}
	)*
	
	{
 	  return op==null? operand: op;
 	}
}

Expression MultExpr()throws ParseException:
{
  OperatorExpr op = null;
  Expression operand = null;
}
{
	operand = UnionExpr()

	(( "*" | "/" | "%" | <CARET> | "idiv")
  	{
  	  if (op == null) {
  	    op = new OperatorExpr();
        op.addOperand(operand);
        op.setCurrentop(true);          	    
  	  } 
  	  Token t = getToken(0);
	  op.addOperator(t.toString());
	}
	operand = UnionExpr()
	{
	   op.addOperand(operand);
	}
	)*
	
 	{
 	  return op==null?operand:op;
 	}	
}

Expression UnionExpr() throws ParseException:
{
    UnionExpr union = null;
    Expression operand1 = null;
    Expression operand2 = null;
}
{
   operand1 = UnaryExpr() 
   ("union" 
       (operand2 = UnaryExpr()) {
          if (union == null) {
             union = new UnionExpr();
             union.addExpr(operand1); 
          }
          union.addExpr(operand2);   
       } )*
   {
     return (union == null)? operand1: union;
   }
}

Expression UnaryExpr() throws ParseException:
{
	Expression uexpr = null;
	Expression expr = null;
}
{
	(( "+"|"-") 
	{
	  	uexpr = new UnaryExpr(); 
		Token t = getToken(0);
		if("+".equals(t.toString()))
			((UnaryExpr)uexpr).setSign(Sign.POSITIVE);
		else if("-".equals(t.toString()))
			((UnaryExpr)uexpr).setSign(Sign.NEGATIVE);
		else 
			throw new ParseException();
	}
	)?
	
	expr = ValueExpr()
	{
		if(uexpr!=null){
			((UnaryExpr)uexpr).setExpr(expr);
			return uexpr;
		}
		else{
			return expr;
		}
	}
}

Expression ValueExpr() throws ParseException:
{
  Expression expr;
}
{
  expr = FieldOrIndexAccessor()
  {
    return expr;
  }
}


Expression FieldOrIndexAccessor()throws ParseException:
{
  Expression expr = null;
  Identifier ident = null;
  AbstractAccessor fa = null;
  int index;

}
{
	( expr = PrimaryExpr()

	)


	(
	(
	  	ident = Field()
	{
		  if(fa == null)
		  	fa = new FieldAccessor(expr, ident);
		  else
		  	fa = new FieldAccessor(fa, ident);
	}
	)
	| (
		index = Index()
		{
		  if(fa == null)
		  	fa = new IndexAccessor(expr, index);
		  else
		  	fa = new IndexAccessor(fa, index);
		}
	) 
	)*

	
  	{
 	  return fa==null?expr:fa;
 	}
}

Identifier Field() throws ParseException:
{
  Identifier ident = null;

}
{
  "." < IDENTIFIER >
  	{
    
  	ident = new Identifier();
	ident.setValue(getToken(0).toString());

	  return ident;
	}
}

int Index() throws ParseException:
{
	Expression expr = null;
	int idx = -2;
}
{
  "[" ( expr = Expression()
	{
		if(expr.getKind() == Expression.Kind.LITERAL_EXPRESSION)
		{
			ILiteral lit = ((LiteralExpr)expr).getValue();
			if(lit.getLiteralType() == ILiteral.Type.INTEGER) {
				idx = Integer.valueOf(lit.getStringValue());
			}	
			else {
				throw new ParseException("Index should be an INTEGER");				
            }
		}

	}

  	| "?"
	{
		idx = IndexAccessor.ANY;
	  // ANY
	}
 	 
  	)

   "]"
	{
	  return idx;
	}
}


Expression PrimaryExpr()throws ParseException:
{
  Expression expr = null;
}
{
  //ILiteral | VariableRef | ListConstructor | RecordConstructor | FunctionCallExpr | ParenthesizedExpression
	(
	  expr =Literal() 
	   | expr = FunctionCallExpr()
	   | expr =VariableRef() 
	   
    {
      if(((VariableExpr)expr).getIsNewVar() == true)
      	throw new ParseException("can't find variable " + ((VariableExpr)expr).getVar());
    }
    	   | expr = ListConstructor()
	   | expr = RecordConstructor()
	   | expr = ParenthesizedExpression()
	)
 	{
 	  return expr;
 	}
}

Expression Literal() throws ParseException:
{

  LiteralExpr lit = new LiteralExpr();
  Token t;
}
{
(
      <STRING_LITERAL>
	{
	  t= getToken(0);
	  lit.setValue( new StringLiteral(removeQuotesAndEscapes(t.image)));
	}
    
 	 | <INTEGER_LITERAL>
    {
      t= getToken(0);
	  lit.setValue(new IntegerLiteral(new Integer(t.image)));
	}
     | < FLOAT_LITERAL >
    {
      t= getToken(0);
      lit.setValue(new FloatLiteral(new Float(t.image)));
    }     
	 | < DOUBLE_LITERAL >
    {
      t= getToken(0);
	  lit.setValue(new DoubleLiteral(new Double(t.image)));
	}	  
 	 | <NULL>
	{
	  t= getToken(0);
	  lit.setValue(NullLiteral.INSTANCE);
	}
   	 | <TRUE>
	{
	  t= getToken(0);
	  lit.setValue(TrueLiteral.INSTANCE);
	}   	 
   	 | <FALSE>
	{
	  t= getToken(0);
	  lit.setValue(FalseLiteral.INSTANCE);
	}
)
    {
      return lit;
    }
}


VariableExpr VariableRef() throws ParseException:
{
	VariableExpr varExp = new VariableExpr();
	VarIdentifier var = new VarIdentifier();
	Token t;
}
{
      <VARIABLE>
    {
     t = getToken(0);//get current token
     String varName = t.toString(); 
     Identifier ident = lookupSymbol(varName);
     if (isInForbiddenScopes(varName)) {
       throw new ParseException("Inside limit clauses, it is disallowed to reference a variable having the same name as any variable bound in the same scope as the limit clause.");
     }
     if(ident != null) { // exist such ident
       varExp.setIsNewVar(false);
       varExp.setVar((VarIdentifier)ident);       
     } else {
       varExp.setVar(var);     
     }
     var.setValue(t.toString());        
     return varExp;
    }
}


VariableExpr Variable() throws ParseException:
{
	VariableExpr varExp = new VariableExpr();
	VarIdentifier var = new VarIdentifier();
	Token t;
}
{
      <VARIABLE>
    {
     t = getToken(0);//get current token
     Identifier ident = lookupSymbol(t.toString());
     if(ident != null) { // exist such ident
       varExp.setIsNewVar(false);
     }  
     varExp.setVar(var);     
     var.setValue(t.toString());        
     return varExp;
    }
}

Expression ListConstructor() throws ParseException:
{
	Expression expr = null;
}
{
    (
    	expr = OrderedListConstructor() | expr = UnorderedListConstructor()
    )
    
    {
      return expr;
    }
}


ListConstructor OrderedListConstructor() throws ParseException:
{
  	ListConstructor expr = new ListConstructor();
  	Expression tmp = null;
  	List<Expression> exprList = new ArrayList<Expression>();
  	expr.setType(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR);
}
{

    "[" 
	    ( tmp = Expression()
			{
			  exprList.add(tmp);
			}
		
		    ("," tmp = Expression() { exprList.add(tmp);  })*
	    )? 
    
    "]"

    {
      expr.setExprList(exprList);
      return expr;
    }    
}

ListConstructor UnorderedListConstructor() throws ParseException:
{
  	ListConstructor expr = new ListConstructor();
  	Expression tmp = null;
  	List<Expression> exprList = new ArrayList<Expression>();
  	expr.setType(ListConstructor.Type.UNORDERED_LIST_CONSTRUCTOR);
}
{

    "{{" ( tmp = Expression()
	{
	  exprList.add(tmp);
	}
    ("," tmp = Expression() { exprList.add(tmp);  })*)? "}}"
    {
      expr.setExprList(exprList);
      return expr;
    }    
}

RecordConstructor RecordConstructor() throws ParseException:
{
  	RecordConstructor expr = new RecordConstructor();
  	FieldBinding tmp = null;
  	List<FieldBinding> fbList = new ArrayList<FieldBinding>();
}
{
    "{" (tmp = FieldBinding()
    {
      fbList.add(tmp);
    }
    ("," tmp = FieldBinding() { fbList.add(tmp);  })*)? "}"
    {
      expr.setFbList(fbList);
      return expr;
    }       
}

FieldBinding FieldBinding() throws ParseException:
{
	FieldBinding fb = new FieldBinding();
	Expression left, right;
}
{
    left = Expression() ":" right = Expression()
    {
      fb.setLeftExpr(left);
      fb.setRightExpr(right);
      return fb;
    }
}

Expression FunctionCallExpr() throws ParseException:
{
  CallExpr pf = new CallExpr();
  List<Expression > argList = new ArrayList<Expression >();
  Expression tmp;
  int arity = 0;
  Token funcName;
}
{
    ( <IDENTIFIER> | <DATASET> )
    {
		funcName = getToken(0);
    }
     <LEFTPAREN> (tmp = Expression()
     {
       argList.add(tmp);
       arity ++;
     } ("," tmp = Expression() { argList.add(tmp); arity++; })*)? <RIGHTPAREN>

     {
       AsterixFunction fd = lookupFunctionSignature(funcName.toString(), arity);
	     if(fd == null)
	     {
	        fd = new AsterixFunction(funcName.toString(), arity);
//	     	notFoundFunctionList.add(fd);
	     }
//	     	throw new ParseException("can't find function "+ funcName.toString() + "@" + arity);
       pf.setIdent(fd);
       pf.setExprList(argList);
       return pf;
     }
}


Expression ParenthesizedExpression() throws ParseException:
{
  Expression expr;
}
{
    <LEFTPAREN> expr = Expression() <RIGHTPAREN>
    {
      return expr;
    }
}

Expression IfThenElse() throws ParseException:
{
  Expression condExpr;
  Expression thenExpr;
  Expression elseExpr;
  IfExpr ifExpr = new IfExpr();
}
{
    "if" <LEFTPAREN> condExpr = Expression() <RIGHTPAREN> "then" thenExpr = Expression() "else" elseExpr = Expression()

    {
      ifExpr.setCondExpr(condExpr);
      ifExpr.setThenExpr(thenExpr);
      ifExpr.setElseExpr(elseExpr);
      return ifExpr;
    }
}

Expression  FLWOGR() throws ParseException:
{
	FLWOGRExpression flworg = new FLWOGRExpression();
	List<Clause> clauseList = new ArrayList<Clause>();
	Expression returnExpr;
	Clause tmp;
	createNewScope();
}
{
     (tmp = ForClause()  {clauseList.add(tmp);} | tmp = LetClause() {clauseList.add(tmp);})
      (tmp = Clause() {clauseList.add(tmp);})* "return" returnExpr = Expression()

     {
       flworg.setClauseList(clauseList);
       flworg.setReturnExpr(returnExpr);
       removeCurrentScope();
       return flworg;
     }
}

Clause Clause()throws ParseException :
{
  Clause clause;
}
{
    (
         clause = ForClause() 
       | clause = LetClause() 
       | clause = WhereClause() 
       | clause = OrderbyClause() 
       | clause = GroupClause() 
       | clause = LimitClause()
       | clause = DistinctClause()
       | clause = DieClause()
    )
    {
      return clause;
    }
}

Clause ForClause()throws ParseException :
{
	ForClause fc = new ForClause();
	VariableExpr varExp;
	VariableExpr varPos = null;
	Expression inExp;
	extendCurrentScope();
}
{
    "for" varExp = Variable()
    {
     	getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
	}
	("at" varPos = Variable()
	  {
	     getCurrentScope().addNewVarSymbolToScope(varPos.getVar());
	  } 
	 )? 
      "in" ( inExp = Expression() )
    {
      fc.setVarExpr(varExp);
      fc.setInExpr(inExp);
      if (varPos != null) {
        fc.setPosExpr(varPos);
      }
      return fc;
    }
}

Clause LetClause() throws ParseException:
{
	LetClause lc = new LetClause();
	VariableExpr varExp;
	Expression beExp;
	extendCurrentScope();
}
{
    "let" varExp = Variable()
    {
      getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
	}
     ":=" beExp = Expression()
    {
      lc.setVarExpr(varExp);
      lc.setBeExpr(beExp);
      return lc;
    }
}

Clause WhereClause()throws ParseException :
{
  WhereClause wc = new WhereClause();
  Expression whereExpr;
}
{
    "where" whereExpr = Expression()
    {
      wc.setWhereExpr(whereExpr);
      return wc;
    }
}

Clause OrderbyClause()throws ParseException :
{
  OrderbyClause oc = new OrderbyClause();
  Expression orderbyExpr;
  List<Expression> orderbyList = new ArrayList<Expression>();
  List<OrderbyClause.OrderModifier> modifierList = new ArrayList<OrderbyClause.OrderModifier >();
  int numOfOrderby = 0;
}
{
  (
    "order" 
      {
         String hint = getHint(token);
         if (hint != null && hint.startsWith(INMEMORY_HINT)) {
           String splits[] = hint.split(" +"); 
           int numFrames = Integer.parseInt(splits[1]);
           int numTuples = Integer.parseInt(splits[2]);
           oc.setNumFrames(numFrames);
           oc.setNumTuples(numTuples);   
         } 
      }     
    "by" orderbyExpr = Expression()
    {
      orderbyList.add(orderbyExpr);
      OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC;       
    }
    ( ("asc" { modif = OrderbyClause.OrderModifier.ASC; })
    | ("desc" { modif = OrderbyClause.OrderModifier.DESC; }))?
    {
      modifierList.add(modif);
    }
    
    ("," orderbyExpr = Expression()
    {
      orderbyList.add(orderbyExpr);
      modif = OrderbyClause.OrderModifier.ASC;
    }
    ( ("asc" { modif = OrderbyClause.OrderModifier.ASC; })
    | ("desc" { modif = OrderbyClause.OrderModifier.DESC; }))?
    {
      modifierList.add(modif);
    }    
    )*
)
    {
      oc.setModifierList(modifierList);
      oc.setOrderbyList(orderbyList);
      return oc;
    }
}
Clause GroupClause()throws ParseException :
{
  	GroupbyClause gbc = new GroupbyClause();
  	// GbyVariableExpressionPair pair = new GbyVariableExpressionPair();
 	List<GbyVariableExpressionPair> vePairList = new ArrayList<GbyVariableExpressionPair>();
    List<GbyVariableExpressionPair> decorPairList = new ArrayList<GbyVariableExpressionPair>();
	List<VariableExpr> withVarList= new ArrayList<VariableExpr>();
	VariableExpr var = null;
	VariableExpr withVar = null;
	Expression expr = null;
	VariableExpr decorVar = null;
	Expression decorExpr = null;
}
{
  	{
  	  Scope newScope = extendCurrentScopeNoPush(true); 
  	  // extendCurrentScope(true);
  	}
    "group"
      {
         String hint = getHint(token);
         if (hint != null && hint.equals(HASH_GROUP_BY_HINT)) {
           gbc.setHashGroupByHint(true);   
         } 
      } 
    "by" (LOOKAHEAD(2)  var = Variable()
    {
      newScope.addNewVarSymbolToScope(var.getVar());
    } ":=")?
    expr = Expression() 
       {
         GbyVariableExpressionPair pair1 = new GbyVariableExpressionPair(var, expr);    
         vePairList.add(pair1);
       }
    ("," ( LOOKAHEAD(2) var = Variable()
    {
      newScope.addNewVarSymbolToScope(var.getVar());
    } ":=")?
    	expr = Expression()  
    	 {
           GbyVariableExpressionPair pair2 = new GbyVariableExpressionPair(var, expr);    
           vePairList.add(pair2);
         }
    	)*
    ("decor" decorVar = Variable() ":=" decorExpr = Expression()
       {    
         newScope.addNewVarSymbolToScope(decorVar.getVar()); 
         GbyVariableExpressionPair pair3 = new GbyVariableExpressionPair(decorVar, decorExpr);
         decorPairList.add(pair3);
       }
      ("," "decor" decorVar = Variable() ":=" decorExpr = Expression()
           { 
             newScope.addNewVarSymbolToScope(decorVar.getVar()); 
             GbyVariableExpressionPair pair4 = new GbyVariableExpressionPair(decorVar, decorExpr);
             decorPairList.add(pair4);              
           }
       )*            
    )?	
    "with" withVar = VariableRef()
    {
      if(withVar.getIsNewVar()==true)
      	throw new ParseException("can't find variable " + withVar.getVar());
      withVarList.add(withVar);
      newScope.addNewVarSymbolToScope(withVar.getVar());
    }
    ("," withVar = VariableRef()
    {
      if(withVar.getIsNewVar()==true)
      	throw new ParseException("can't find variable " + withVar.getVar());
      withVarList.add(withVar);
      newScope.addNewVarSymbolToScope(withVar.getVar());
    })*
    {
      gbc.setGbyPairList(vePairList);
      gbc.setDecorPairList(decorPairList);
      gbc.setWithVarList(withVarList);
      replaceCurrentScope(newScope);
      return gbc;
    }
}


LimitClause LimitClause() throws ParseException:
{
	LimitClause lc = new LimitClause();
	Expression expr;
	pushForbiddenScope(getCurrentScope());
}
{
    "limit" expr = Expression()    { lc.setLimitExpr(expr);    }
    ("offset" expr = Expression() { lc.setOffset(expr);    })?

  {
    popForbiddenScope();   
    return lc;
  }
}

DistinctClause DistinctClause() throws ParseException:
{
  List<Expression> exprs = new ArrayList<Expression>();
  Expression expr;
}
{
  "distinct" "by" expr = Expression() 
  {
    exprs.add(expr);
  }
  ("," expr = Expression() 
  	{
  		exprs.add(expr); 
  	} 
  )*
  {
  	return new DistinctClause(exprs);
  }
}

DieClause DieClause() throws ParseException:
{
	DieClause lc = new DieClause();
	Expression expr;
	pushForbiddenScope(getCurrentScope());
}
{
  "die" "after" expr = Expression()    { lc.setDieExpr(expr);    }
  {
    popForbiddenScope();   
    return lc;
  }
}


QuantifiedExpression QuantifiedExpression()throws ParseException:
{
  QuantifiedExpression qc = new QuantifiedExpression();
  List<QuantifiedPair> quantifiedList = new ArrayList<QuantifiedPair>();
  Expression satisfiesExpr;
  VariableExpr var;
  Expression inExpr;
  QuantifiedPair pair;
}
{
  {
    createNewScope();
  }
	
   (      ("some"  {  qc.setQuantifier(QuantifiedExpression.Quantifier.SOME);	})
		| ("every" {  qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY);	}))
	var = Variable() "in" inExpr = Expression() 
	{
	  pair = new QuantifiedPair(var, inExpr);
      getCurrentScope().addNewVarSymbolToScope(var.getVar());
      quantifiedList.add(pair);
	}
	(
	"," var = Variable() "in" inExpr = Expression() 
	{ 
      pair = new QuantifiedPair(var, inExpr);
      getCurrentScope().addNewVarSymbolToScope(var.getVar());
      quantifiedList.add(pair);	
	}
	)*
	 "satisfies" satisfiesExpr = Expression()
	 {
	   qc.setSatisfiesExpr(satisfiesExpr);
	   qc.setQuantifiedList(quantifiedList);
	   removeCurrentScope();
	   return qc;
	 }
}

TOKEN_MGR_DECLS:
{
        public int commentDepth = 0;
}

<DEFAULT>
TOKEN :
{
   <CARET : "^"  >
}

<DEFAULT>
TOKEN :
{
   <DATASET : "dataset"  >
}

<DEFAULT>
TOKEN :
{
   <LEFTPAREN : "("  >
}

<DEFAULT>
TOKEN :
{
   <RIGHTPAREN : ")"  >
}


<DEFAULT>
TOKEN :
{
	<INTEGER_LITERAL : (<DIGIT>)+ >
}


<DEFAULT>
TOKEN :
{
	<NULL : "null">
}

<DEFAULT>
TOKEN :
{
	<TRUE : "true">
}

<DEFAULT>
TOKEN :
{
	<FALSE : "false">
}

<DEFAULT>
TOKEN :
{
	<#DIGIT : ["0" - "9"]>
}


TOKEN:
{
  < DOUBLE_LITERAL: <INTEGER>
        | <INTEGER> ( "." <INTEGER> )?
        | "." <INTEGER>
  >
  |
  < FLOAT_LITERAL: <INTEGER> ( "f" | "F" )
        | <INTEGER> ( "." <INTEGER> ( "f" | "F" ) )?
        | "." <INTEGER> ( "f" | "F" )
  >
  |
  <INTEGER : (<DIGIT>)+ >
}

<DEFAULT>
TOKEN :
{
	<#LETTER : ["A" - "Z", "a" - "z"]>
}

<DEFAULT>
TOKEN :
{
	<SPECIALCHARS : ["$", "_", "-"]  >
}

<DEFAULT>
TOKEN :
{
	<STRING_LITERAL : ("\"" (<EscapeQuot> | ~["\""])* "\"") | ("\'"(<EscapeApos> | ~["\'"])* "\'")>
	|
	< #EscapeQuot: "\\\"" >
	|
    < #EscapeApos: "\\\'" >
}

<DEFAULT>
TOKEN :
{
	<IDENTIFIER : (<LETTER>)+ (<LETTER> | <DIGIT> | <SPECIALCHARS>)*>
}

<DEFAULT>
TOKEN :
{
	<VARIABLE : "$" <IDENTIFIER> >
}

SKIP:
{
    " "
|   "\t"
|   "\r"
|   "\n"
}

SKIP:
{
	<"//" (~["\n"])* "\n">
}

SKIP:
{
	<"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?> 
}


SKIP:
{
        <"/*"> {commentDepth=1;}: INSIDE_COMMENT
}

<INSIDE_COMMENT>
SPECIAL_TOKEN:
{
       <"+"(" ")*(~["*"])*>
}

<INSIDE_COMMENT>
SKIP:
{
        <"/*"> {commentDepth++;}
}

<INSIDE_COMMENT>
SKIP:
{
        <"*/"> {commentDepth--; if (commentDepth == 0) SwitchTo(DEFAULT);}
|       <~[]>
}
