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.Map;
import java.util.HashMap;
import java.util.LinkedHashMap;

import org.apache.xerces.util.IntStack;

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.Literal;
import edu.uci.ics.asterix.aql.literal.IntegerLiteral;
import edu.uci.ics.asterix.aql.literal.LongIntegerLiteral;
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.metadata.bootstrap.MetadataConstants;

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;
import edu.uci.ics.asterix.common.functions.FunctionSignature;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IndexedNLJoinExpressionAnnotation;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
import edu.uci.ics.hyracks.algebricks.common.utils.Triple;




public class AQLParser extends ScopeChecker {

    // optimizer hints
    private static final String HASH_GROUP_BY_HINT = "hash";
    private static final String SKIP_SECONDARY_INDEX_SEARCH_HINT = "skip-index";
    private static final String BROADCAST_JOIN_HINT = "bcast";
    private static final String INDEXED_NESTED_LOOP_JOIN_HINT = "indexnl";
    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 class IndexParams {
      public IndexType type;
      public int gramLength;
      
      public IndexParams(IndexType type, int gramLength) {
        this.type = type;
        this.gramLength = gramLength;
      }
    };  
   
    private static class FunctionName {
	   public String dataverse = null;
	   public String library = null;
	   public String function = null;
	}

    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();
    }
    
    private static IRecordFieldDataGen parseFieldDataGen(String hint) throws ParseException {
      IRecordFieldDataGen rfdg = 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]);
      }
      return rfdg;
    }

    public AQLParser(String s){
        this(new StringReader(s));
        super.setInput(s);
    }

    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);
        List<Statement> st = parser.Statement();
        //st.accept(new AQLPrintVisitor(), 0);
    }
}

PARSER_END(AQLParser)


List<Statement> Statement() throws ParseException:
{
  scopeStack.push(RootScopeFactory.createRootScope(this));
  List<Statement> decls = new ArrayList<Statement>();
  Statement stmt = null;
}
{
  ( stmt = SingleStatement() (";") ?
    {
      decls.add(stmt);
    }
  )*
  <EOF>
  {
    return decls;  
  }
}

Statement SingleStatement() throws ParseException:
{
  Statement stmt = null;
}
{
  (
    stmt = DataverseDeclaration()
    | stmt = FunctionDeclaration()
    | stmt = CreateStatement()
    | stmt = LoadStatement()
    | stmt = DropStatement()
    | stmt = WriteStatement()
    | stmt = SetStatement()
    | stmt = InsertStatement()
    | stmt = DeleteStatement()
    | stmt = UpdateStatement()       
    | stmt = FeedStatement()
    | stmt = CompactStatement()
    | stmt = Query()
    | stmt = RefreshExternalDatasetStatement()
  )
  {
    return stmt;
  }
}

DataverseDecl DataverseDeclaration() throws ParseException:
{
  String dvName = null;
}
{
  "use" "dataverse" dvName = Identifier()
    {
      defaultDataverse = dvName;
      return new DataverseDecl(new Identifier(dvName));
    }
}

Statement CreateStatement() throws ParseException:
{
  String hint = null;
  boolean dgen = false;
  Statement stmt = null;
}
{
  "create"
  (
    {
      hint = getHint(token);
      if (hint != null && hint.startsWith(DGEN_HINT)) {
        dgen = true;
      }                  
    }
    stmt = TypeSpecification(hint, dgen)
    | stmt = NodegroupSpecification()
    | stmt = DatasetSpecification()    
    | stmt = IndexSpecification()
    | stmt = DataverseSpecification()
    | stmt = FunctionSpecification()
    | stmt = FeedSpecification()
  )        
  {
    return stmt;
  }
}

TypeDecl TypeSpecification(String hint, boolean dgen) throws ParseException:
{
  Pair<Identifier,Identifier> nameComponents = null;
  boolean ifNotExists = false;
  TypeExpression typeExpr = null;
}
{
  "type" nameComponents = TypeName() ifNotExists = IfNotExists()
  "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(nameComponents.first, nameComponents.second, typeExpr, tddg, ifNotExists);
    }
}


NodegroupDecl NodegroupSpecification() throws ParseException:
{
  String name = null;
  String tmp = null;
  boolean ifNotExists = false;
  List<Identifier>ncNames = null;
}
{
  "nodegroup" name = Identifier()
  ifNotExists = IfNotExists() "on" tmp = Identifier()
    {
      ncNames = new ArrayList<Identifier>();
      ncNames.add(new Identifier(tmp));
    }
  ( <COMMA> tmp = Identifier()
    {
      ncNames.add(new Identifier(tmp));
    }
  )*
    {
      return new NodegroupDecl(new Identifier(name), ncNames, ifNotExists);
    }
}

DatasetDecl DatasetSpecification() throws ParseException:
{
  Pair<Identifier,Identifier> nameComponents = null;  
  boolean ifNotExists = false;
  String typeName = null;
  String adapterName = null;
  Map<String,String> properties = null;
  Map<String,String> compactionPolicyProperties = null;
  FunctionSignature appliedFunction = null;
  List<String> primaryKeyFields = null;
  String nodeGroupName = null;
  Map<String,String> hints = new HashMap<String,String>();  
  DatasetDecl dsetDecl = null;
  boolean autogenerated = false;
  String compactionPolicy = null;
}
{
  (
    "external" <DATASET> nameComponents = QualifiedName()
    <LEFTPAREN> typeName = Identifier() <RIGHTPAREN>
    ifNotExists = IfNotExists()
    "using" adapterName = AdapterName() properties = Configuration()
    ("on" nodeGroupName = Identifier() )?
    ( "hints" hints = Properties() )?
    ( "using" "compaction" "policy" compactionPolicy = CompactionPolicy() compactionPolicyProperties = Configuration() )?
      {
        ExternalDetailsDecl edd = new ExternalDetailsDecl();
        edd.setAdapter(adapterName);
        edd.setProperties(properties);
        edd.setNodegroupName(nodeGroupName != null? new Identifier(nodeGroupName): null);
        edd.setCompactionPolicy(compactionPolicy);
        edd.setCompactionPolicyProperties(compactionPolicyProperties);
        dsetDecl = new DatasetDecl(nameComponents.first,
                                   nameComponents.second,
                                   new Identifier(typeName),
                                   hints,
                                   DatasetType.EXTERNAL,
                                   edd,
                                   ifNotExists);
      } 

    | ("internal")? <DATASET> nameComponents = QualifiedName()
    <LEFTPAREN> typeName = Identifier() <RIGHTPAREN>
    ifNotExists = IfNotExists()
    primaryKeyFields = PrimaryKey() 
    ("autogenerated" { autogenerated = true; } )? 
    ("on" nodeGroupName = Identifier() )?
    ( "hints" hints = Properties() )?
    ( "using" "compaction" "policy" compactionPolicy = CompactionPolicy() compactionPolicyProperties = Configuration() )?
      {
        InternalDetailsDecl idd = new InternalDetailsDecl(nodeGroupName != null
                                                            ? new Identifier(nodeGroupName)
                                                            : null,
                                                          primaryKeyFields,
                                                          autogenerated,
                                                          compactionPolicy,
                                                          compactionPolicyProperties);
        dsetDecl = new DatasetDecl(nameComponents.first,
                                   nameComponents.second,
                                   new Identifier(typeName),
                                   hints,
                                   DatasetType.INTERNAL,
                                   idd,
                                   ifNotExists);
      }
  )
    {
      return dsetDecl;
    }
}

RefreshExternalDatasetStatement RefreshExternalDatasetStatement() throws ParseException:
{
  RefreshExternalDatasetStatement redss = new RefreshExternalDatasetStatement();
  Pair<Identifier,Identifier> nameComponents = null;
  String datasetName = null;
}
{
	"refresh external" <DATASET> nameComponents = QualifiedName()
	{
	redss.setDataverseName(nameComponents.first);
	redss.setDatasetName(nameComponents.second);
	return redss;
	}
}

CreateIndexStatement IndexSpecification() throws ParseException:
{
  CreateIndexStatement cis = new CreateIndexStatement();
  String indexName = null;
  String fieldExpr = null;
  boolean ifNotExists = false;
  Pair<Identifier,Identifier> nameComponents = null;
  IndexParams indexType = null;
}
{
  "index" indexName = Identifier()
  ifNotExists = IfNotExists()
  "on" nameComponents = QualifiedName()    
  <LEFTPAREN> ( fieldExpr = Identifier()
    {
      cis.addFieldExpr(fieldExpr);
    }
  ) (<COMMA> fieldExpr = Identifier()
    {
      cis.addFieldExpr(fieldExpr);
    }
  )* <RIGHTPAREN> ( "type" indexType = IndexType() )?
    {
      cis.setIndexName(new Identifier(indexName));
      cis.setIfNotExists(ifNotExists);
      cis.setDataverseName(nameComponents.first);
      cis.setDatasetName(nameComponents.second);
      if (indexType != null) {
        cis.setIndexType(indexType.type);
        cis.setGramLength(indexType.gramLength);
      }
      return cis;
    }
}

String CompactionPolicy() throws ParseException :
{
  String compactionPolicy = null;
}
{
  compactionPolicy = Identifier()
    {
	  return compactionPolicy;
    }
}

IndexParams IndexType() throws ParseException:
{
  IndexType type = null;
  int gramLength = 0;
}
{
  ("btree"
    {
      type = IndexType.BTREE;
    }         
  | "rtree"
    {
      type = IndexType.RTREE;
    }
  | "keyword"
    {
      type = IndexType.LENGTH_PARTITIONED_WORD_INVIX;
    }
  | "ngram" <LEFTPAREN> <INTEGER_LITERAL>
    {
      type = IndexType.LENGTH_PARTITIONED_NGRAM_INVIX;
      gramLength = Integer.valueOf(token.image);
    }
  <RIGHTPAREN>)
    {
      return new IndexParams(type, gramLength);
    }
}

CreateDataverseStatement DataverseSpecification() throws ParseException :
{
  String dvName = null;
  boolean ifNotExists = false;
  String format = null;
}
{
  "dataverse" dvName = Identifier()
  ifNotExists = IfNotExists()
  ( "with format" format = StringLiteral() )?
    {
      return new CreateDataverseStatement(new Identifier(dvName), format, ifNotExists);
    }
}

CreateFunctionStatement FunctionSpecification() throws ParseException:
{
  FunctionSignature signature;
  boolean ifNotExists = false;
  List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
  String functionBody;
  VarIdentifier var = null;
  Expression functionBodyExpr;
  Token beginPos;
  Token endPos;
  FunctionName fctName = null;
  
  createNewScope();
}
{
  "function" fctName = FunctionName()
  ifNotExists = IfNotExists()
  paramList = ParameterList()
  <LEFTBRACE>
  {
     beginPos = token;
  } 
  functionBodyExpr = Expression() <RIGHTBRACE>
    {
      endPos = token;
      functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine, endPos.beginColumn);
      // TODO use fctName.library
      signature = new FunctionSignature(fctName.dataverse, fctName.function, paramList.size());
      getCurrentScope().addFunctionDescriptor(signature, false);
      return new CreateFunctionStatement(signature, paramList, functionBody, ifNotExists);
    }
}

CreateFeedStatement FeedSpecification() throws ParseException:
{
  Pair<Identifier,Identifier> nameComponents = null;  
  boolean ifNotExists = false;
  String adaptorName = null;
  Map<String,String> properties = null;
  FunctionSignature appliedFunction = null;
  CreateFeedStatement cfs = null;
}
{
  (
    "feed"  nameComponents = QualifiedName()
    ifNotExists = IfNotExists()
    "using" adaptorName = AdapterName() properties = Configuration()
    (appliedFunction = ApplyFunction())?
      {
        cfs = new CreateFeedStatement(nameComponents.first,
                                   nameComponents.second, adaptorName, properties, appliedFunction, ifNotExists);
      } 
      
  )
    {
      return cfs;
    }
}



List<VarIdentifier> ParameterList() throws ParseException:
{
  List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
  VarIdentifier var = null;
}
{
  <LEFTPAREN> (<VARIABLE>
    {
      var = new VarIdentifier();
      var.setValue(token.image);
      paramList.add(var);
      getCurrentScope().addNewVarSymbolToScope(var);
    }
  (<COMMA> <VARIABLE>
    {
      var = new VarIdentifier();
      var.setValue(token.image);
      paramList.add(var);
      getCurrentScope().addNewVarSymbolToScope(var);
    }
  )*)? <RIGHTPAREN>
    {
      return paramList;
    }
}

boolean IfNotExists() throws ParseException:
{
}
{
  ( "if not exists"
    {
      return true;
    }
  )?
    {
      return false;
    }
}

FunctionSignature ApplyFunction() throws ParseException:
{
  FunctionName functioName = null;
  FunctionSignature funcSig = null;
}
{
  "apply" "function" functioName = FunctionName()
    {
       String fqFunctionName = functioName.library == null ? functioName.function : functioName.library + "#" + functioName.function;
       return new FunctionSignature(functioName.dataverse, fqFunctionName, 1);
    }
}

String GetPolicy() throws ParseException:
{
  String policy = null;
}
{
   "using" "policy" policy = Identifier() 
   {
     return policy;
   }
   
}   

FunctionSignature FunctionSignature() throws ParseException:
{
  FunctionName fctName = null;
  int arity = 0;
}
{
  fctName = FunctionName() "@" <INTEGER_LITERAL> 
    {  
      arity = new Integer(token.image);
      if (arity < 0 && arity != FunctionIdentifier.VARARGS) {
        throw new ParseException(" invalid arity:" + arity);
      }

      // TODO use fctName.library
      String fqFunctionName = fctName.library == null ? fctName.function : fctName.library + "#" + fctName.function;
      return new FunctionSignature(fctName.dataverse, fqFunctionName, arity);
    }
}

List<String> PrimaryKey() throws ParseException:
{
  String tmp = null;
  List<String> primaryKeyFields = new ArrayList<String>();
}
{
  "primary" "key" tmp = Identifier()
    {
      primaryKeyFields.add(tmp);
    }
  ( <COMMA> tmp = Identifier()
    {
      primaryKeyFields.add(tmp);
    }
  )*
    {
      return primaryKeyFields;
    }
}

Statement DropStatement() throws ParseException:
{
  String id = null;
  Pair<Identifier,Identifier> pairId = null;
  Triple<Identifier,Identifier,Identifier> tripleId = null;
  FunctionSignature funcSig = null;
  boolean ifExists = false;
  Statement stmt = null;
}
{
  "drop"
  (
    <DATASET> pairId = QualifiedName() ifExists = IfExists()
      {
        stmt = new DropStatement(pairId.first, pairId.second, ifExists);
      }
    | "index" tripleId = DoubleQualifiedName() ifExists = IfExists()
      {
        stmt = new IndexDropStatement(tripleId.first, tripleId.second, tripleId.third, ifExists);
      }
    | "nodegroup" id = Identifier() ifExists = IfExists()
      {
        stmt = new NodeGroupDropStatement(new Identifier(id), ifExists);
      }
    | "type" pairId = TypeName() ifExists = IfExists()
      {
        stmt = new TypeDropStatement(pairId.first, pairId.second, ifExists);
      }
    | "dataverse" id = Identifier() ifExists = IfExists()
      {
        stmt = new DataverseDropStatement(new Identifier(id), ifExists);
      }
    | "function" funcSig = FunctionSignature() ifExists = IfExists()
      {
        stmt = new FunctionDropStatement(funcSig, ifExists);
      }
    | "feed" pairId = QualifiedName() ifExists = IfExists()
      {
        stmt = new FeedDropStatement(pairId.first, pairId.second, ifExists);
      }  
  )
  {
    return stmt;  
  }
}

boolean IfExists() throws ParseException :
{
}
{
  ( <IF> "exists"
    {
      return true;
    }
  )?
    {
      return false;
    }
}

InsertStatement InsertStatement() throws ParseException:
{
  Pair<Identifier,Identifier> nameComponents = null;
  Query query;
}
{
  "insert" "into" <DATASET> nameComponents = QualifiedName() query = Query()
    {
      return new InsertStatement(nameComponents.first, nameComponents.second, query, getVarCounter());
    }
}

DeleteStatement DeleteStatement() throws ParseException:
{
  VariableExpr var = null;
  Expression condition = null;
  Pair<Identifier, Identifier> nameComponents;
}
{
  "delete" var = Variable()
    {
      getCurrentScope().addNewVarSymbolToScope(var.getVar());
    }
  "from" <DATASET> nameComponents  = QualifiedName() 
  (<WHERE> condition = Expression())?
    {
      return new DeleteStatement(var, nameComponents.first, nameComponents.second, condition, getVarCounter());
    }
}

UpdateStatement UpdateStatement() throws ParseException:
{
  VariableExpr vars;
  Expression target;
  Expression condition;
  UpdateClause uc;
  List<UpdateClause> ucs = new ArrayList<UpdateClause>();
}
{
  "update" vars = Variable() <IN> target = Expression()
  <WHERE> condition = Expression() 
  <LEFTPAREN> (uc = UpdateClause()
    {
      ucs.add(uc);
    }
  (<COMMA> 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() <ASSIGN> value = Expression() 
   | is = InsertStatement()
   | ds = DeleteStatement()
   | 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;
  String pv = null;
}
{
  "set" pn = Identifier() pv = StringLiteral()
    {
      return new SetStatement(pn, pv);
    }
}

Statement WriteStatement() throws ParseException:
{
  String nodeName = null;
  String fileName = null;
  Query query;
  String writerClass = null;
  Pair<Identifier,Identifier> nameComponents = null;
}
{
  "write" "output" "to" nodeName = Identifier() <COLON> fileName = StringLiteral()
    ( "using" writerClass = StringLiteral() )?
    {                  
      return new WriteStatement(new Identifier(nodeName), fileName, writerClass);         
    }
}

LoadStatement LoadStatement() throws ParseException:
{
  Identifier dataverseName = null;
  Identifier datasetName = null;
  boolean alreadySorted = false;
  String adapterName;
  Map<String,String> properties;
  Pair<Identifier,Identifier> nameComponents = null;
}
{
  "load" <DATASET> nameComponents = QualifiedName()
    {
      dataverseName = nameComponents.first;
      datasetName = nameComponents.second;
    }
  "using" adapterName = AdapterName() properties = Configuration()
  ("pre-sorted" 
    {
      alreadySorted = true;
    }
  )?
    {
      return new LoadStatement(dataverseName, datasetName, adapterName, properties, alreadySorted);
    }   
}


String AdapterName() throws ParseException :
{
  String adapterName = null;
}
{
  adapterName = Identifier()
    {
	  return adapterName;
    }
}

Statement CompactStatement() throws ParseException:
{
  Pair<Identifier,Identifier> nameComponents = null;
  Statement stmt = null;
}
{
  "compact" <DATASET> nameComponents = QualifiedName()
    {
	  stmt = new CompactStatement(nameComponents.first, nameComponents.second);
    }
    {
	  return stmt;  
    }
}

Statement FeedStatement() throws ParseException:
{
  Pair<Identifier,Identifier> feedNameComponents = null;
  Pair<Identifier,Identifier> datasetNameComponents = null;
  
  Map<String,String> configuration = null;
  Statement stmt = null;
  String policy = null;
}
{
  (
    "connect" "feed" feedNameComponents = QualifiedName() "to" <DATASET> datasetNameComponents = QualifiedName() (policy = GetPolicy())? 
      {
        stmt = new ConnectFeedStatement(feedNameComponents, datasetNameComponents, policy, getVarCounter());
      }
    | "disconnect" "feed" feedNameComponents = QualifiedName() "from" <DATASET> datasetNameComponents = QualifiedName()
      {
        stmt = new DisconnectFeedStatement(feedNameComponents, datasetNameComponents);
      }
  )
    {
      return stmt;
    }
}

Map<String,String> Configuration()  throws ParseException :
{
	Map<String,String> configuration = new LinkedHashMap<String,String>();
	Pair<String, String> keyValuePair = null;
}
{
  <LEFTPAREN> ( keyValuePair = KeyValuePair()
    {
      configuration.put(keyValuePair.first, keyValuePair.second);
    }
  ( <COMMA> keyValuePair = KeyValuePair()
    {
      configuration.put(keyValuePair.first, keyValuePair.second);
    }
  )* )? <RIGHTPAREN>
    {
      return configuration;
    }
}

Pair<String, String> KeyValuePair() throws ParseException:
{
  String key;
  String value;
}
{
  <LEFTPAREN> key = StringLiteral() <EQ> value = StringLiteral() <RIGHTPAREN>
    {
      return new Pair<String, String>(key, value);
    }  
}

Map<String,String> Properties() throws ParseException:
{
  Map<String,String> properties = new HashMap<String,String>();
  Pair<String, String> property;
}
{
  ( <LEFTPAREN> property = Property()
    {
      properties.put(property.first, property.second);
    }
  ( <COMMA> property = Property() 
    {
      properties.put(property.first, property.second);
    }
  )* <RIGHTPAREN> )?
    {
      return properties;
    }
}

Pair<String, String> Property() throws ParseException:
{
  String key;
  String value;
}
{
  key = Identifier() <EQ> ( value = StringLiteral() | <INTEGER_LITERAL>
    {
      try {
        value = "" + Long.valueOf(token.image);
      } catch (NumberFormatException nfe) {
        throw new ParseException("inapproriate value: " + token.image); 
      }
    }
  )
    {
      return new Pair<String, String>(key.toUpperCase(), value);
    }  
}

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; } )?
   <LEFTBRACE>
    {
      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)
		  ( <COMMA>  RecordField(recType) )*
		)?
   <RIGHTBRACE>
   {
      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;
}
{
  fieldName = Identifier()
    {
      String hint = getHint(token);
      IRecordFieldDataGen rfdg = hint != null ? parseFieldDataGen(hint) : null;
    }
  <COLON> type =  TypeExpr() (<QUES> { nullable = true; } )?
    {
      recType.addField(fieldName, type, nullable, rfdg);
    }   
}

TypeReferenceExpression TypeReference() throws ParseException:
{
  String id = null;
}
{
 id = Identifier()
   {
     return new TypeReferenceExpression(new Identifier(id));
   }
}

OrderedListTypeDefinition OrderedListTypeDef() throws ParseException:
{  
  TypeExpression type = null;
}
{
  <LEFTBRACKET>
    ( type =  TypeExpr() )
  <RIGHTBRACKET>
  {
    return new OrderedListTypeDefinition(type);
  }
}


UnorderedListTypeDefinition UnorderedListTypeDef() throws ParseException:
{  
  TypeExpression type = null;
}
{
  <LEFTDBLBRACE>
    ( type =  TypeExpr() )
  <RIGHTDBLBRACE>
  {
    return new UnorderedListTypeDefinition(type);
  }
}

FunctionName FunctionName() throws ParseException:
{
  String first = null;
  String second = null;
  String third = null;
  boolean secondAfterDot = false;
}
{
  first = Identifier() ( <DOT> second = Identifier()
    {
      secondAfterDot = true;
    }
  ("#" third = Identifier())? | "#" second = Identifier() )?
    {
      FunctionName result = new FunctionName();
      if (second == null) {
        result.dataverse = defaultDataverse;
        result.library   = null;
        result.function  = first;
      } else if (third == null) {
        if (secondAfterDot) {
          result.dataverse = first;
          result.library   = null;
          result.function  = second;
        } else {
          result.dataverse = defaultDataverse;
          result.library   = first;
          result.function  = second;
        }
      } else {
        result.dataverse = first;
        result.library   = second;
        result.function  = third;
      }
      return result;
    }  
}


Pair<Identifier,Identifier> TypeName() throws ParseException:
{
  Pair<Identifier,Identifier> name = null;
}
{
  name = QualifiedName()
    {
      if (name.first == null) {
        name.first = new Identifier(defaultDataverse);
      }
      return name;
    }
}

String Identifier() throws ParseException:
{
  String lit = null;
}
{
  <IDENTIFIER>
    {
      return token.image;
    }
  | lit = StringLiteral()
    {
      return lit;
    } 
}

String StringLiteral() throws ParseException:
{
}
{
  <STRING_LITERAL>
    {
      return removeQuotesAndEscapes(token.image);
    }
}

Pair<Identifier,Identifier> QualifiedName() throws ParseException:
{
  String first = null;
  String second = null;
}
{
  first = Identifier() (<DOT> second = Identifier())?
  {
    Identifier id1 = null;
    Identifier id2 = null;
    if (second == null) {
      id2 = new Identifier(first);
    } else
    {
      id1 = new Identifier(first);
      id2 = new Identifier(second);
    }
    return new Pair<Identifier,Identifier>(id1, id2);
  }  
}  
  
Triple<Identifier,Identifier,Identifier> DoubleQualifiedName() throws ParseException:
{
  String first = null;
  String second = null;
  String third = null;
}
{
  first = Identifier() <DOT> second = Identifier() (<DOT> third = Identifier())?
  {
    Identifier id1 = null;
    Identifier id2 = null;
    Identifier id3 = null;
    if (third == null) {
      id2 = new Identifier(first);
      id3 = new Identifier(second);
    } else {
      id1 = new Identifier(first);
      id2 = new Identifier(second);
      id3 = new Identifier(third);
    }
    return new Triple<Identifier,Identifier,Identifier>(id1, id2, id3);
  }  
}  

FunctionDecl FunctionDeclaration() throws ParseException:
{
  FunctionDecl funcDecl;
  FunctionSignature signature;
  String functionName;
  List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
  Expression funcBody;
  createNewScope();
}
{
  "declare" "function" functionName = Identifier()
  paramList = ParameterList()
  <LEFTBRACE> funcBody = Expression() <RIGHTBRACE>
    {
      signature = new FunctionSignature(defaultDataverse, functionName, paramList.size());
      getCurrentScope().addFunctionDescriptor(signature, false);
      funcDecl = new FunctionDecl(signature, paramList, funcBody);
      removeCurrentScope();
      return funcDecl;
    }
}


Query Query() throws ParseException:
{
  Query query = new Query();
  Expression expr;
}
{
  expr = Expression()
    {
      query.setBody(expr);
      query.setVarCounter(getVarCounter());
      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);  	      	     
  	  }  
      op.addOperator(token.image);
	}

	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);  	      	     
  	  }  
      op.addOperator(token.image);
	}

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

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



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

    (
      LOOKAHEAD(2)( <LT> | <GT> | <LE> | <GE> | <EQ> | <NE> |<SIMILAR>)
  	  {
  	    String mhint = getHint(token);
  	    if (mhint != null) {
  	      if (mhint.equals(INDEXED_NESTED_LOOP_JOIN_HINT)) {
            annotation = IndexedNLJoinExpressionAnnotation.INSTANCE;
          } else if (mhint.equals(SKIP_SECONDARY_INDEX_SEARCH_HINT)) {
            annotation = SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE;
          }
        }
  	    if (op == null) {
  	      op = new OperatorExpr();
  	      op.addOperand(operand, broadcast);
          op.setCurrentop(true);
          broadcast = false;
  	    }
        op.addOperator(token.image);
	  }
	  
 	  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);
      } 
    )?
 	
 	{
 	  if (annotation != null) {
 	    op.addHint(annotation);
 	  }
 	  return op==null? operand: op;
 	}
}

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

	( (<PLUS> | <MINUS>)
  	{
  	  if (op == null) {
  	    op = new OperatorExpr();
        op.addOperand(operand);  	    
        op.setCurrentop(true);        
  	  }
	  ((OperatorExpr)op).addOperator(token.image);
	}

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

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

	(( <MUL> | <DIV> | <MOD> | <CARET> | <IDIV>)
  	{
  	  if (op == null) {
  	    op = new OperatorExpr();
        op.addOperand(operand);
        op.setCurrentop(true);          	    
  	  }
	  op.addOperator(token.image);
	}
	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;
}
{
	( (<PLUS> | <MINUS>) 
	{
	  	uexpr = new UnaryExpr();
		if("+".equals(token.image))
			((UnaryExpr)uexpr).setSign(Sign.POSITIVE);
		else if("-".equals(token.image))
			((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 = null;
  Identifier ident = null;
  AbstractAccessor fa = null;
  Expression indexExpr = null;
}
{
  expr = PrimaryExpr() ( ident = Field()
	{
	  fa = (fa == null ? new FieldAccessor(expr, ident) 
                       : new FieldAccessor(fa, ident));
    }
  | indexExpr = Index()
    {
      fa = (fa == null ? new IndexAccessor(expr, indexExpr)
                       : new IndexAccessor(fa, indexExpr));
     }
  )*
    {
      return fa == null ? expr : fa;
    }
}

Identifier Field() throws ParseException:
{
  String ident = null;
}
{
  <DOT> ident = Identifier()
    {
      return new Identifier(ident);
    }
}

Expression Index() throws ParseException:
{
	Expression expr = null;
}
{
  <LEFTBRACKET> ( expr = Expression()
	{
		if(expr.getKind() == Expression.Kind.LITERAL_EXPRESSION)
		{
			Literal lit = ((LiteralExpr)expr).getValue();
			if(lit.getLiteralType() != Literal.Type.INTEGER &&
			   lit.getLiteralType() != Literal.Type.LONG) {
				throw new ParseException("Index should be an INTEGER");				
            }
		}
	}

  	| <QUES> // ANY
 	 
  	)

   <RIGHTBRACKET>
	{
	  return expr;
	}
}


Expression PrimaryExpr()throws ParseException:
{
  Expression expr = null;
}
{
  ( LOOKAHEAD(2) 
    expr = FunctionCallExpr()
  | expr = Literal()
  | expr = DatasetAccessExpression()
  | 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();
  String str = null;
}
{
  ( str = StringLiteral()
    {
      lit.setValue(new StringLiteral(str));
    }
  | <INTEGER_LITERAL>
    {
      try {
        lit.setValue(new IntegerLiteral(new Integer(token.image)));
      } catch(NumberFormatException ex) {
        lit.setValue(new LongIntegerLiteral(new Long(token.image)));
      }
    }
  | <FLOAT_LITERAL>
    {
      lit.setValue(new FloatLiteral(new Float(token.image)));
    }
  | <DOUBLE_LITERAL>
    {
      lit.setValue(new DoubleLiteral(new Double(token.image)));
    }
  | <NULL>
    {
      lit.setValue(NullLiteral.INSTANCE);
    }
  | <TRUE>
    {
      lit.setValue(TrueLiteral.INSTANCE);
    }      
  | <FALSE>
    {
      lit.setValue(FalseLiteral.INSTANCE);
    }
  )
    {
      return lit;
    }
}


VariableExpr VariableRef() throws ParseException:
{
	VariableExpr varExp = new VariableExpr();
	VarIdentifier var = new VarIdentifier();
}
{
  <VARIABLE>
    {
     String varName = token.image; 
     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(varName);        
     return varExp;
    }
}


VariableExpr Variable() throws ParseException:
{
	VariableExpr varExp = new VariableExpr();
	VarIdentifier var = new VarIdentifier();
}
{
  <VARIABLE>
    {
     Identifier ident = lookupSymbol(token.image);
     if(ident != null) { // exist such ident
       varExp.setIsNewVar(false);
     }  
     varExp.setVar(var);     
     var.setValue(token.image);        
     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);
}
{

    <LEFTBRACKET> 
	    ( tmp = Expression()
			{
			  exprList.add(tmp);
			}
		
		    (<COMMA> tmp = Expression() { exprList.add(tmp);  })*
	    )? 
    
    <RIGHTBRACKET>

    {
      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);
}
{

    <LEFTDBLBRACE> ( tmp = Expression()
	{
	  exprList.add(tmp);
	}
    (<COMMA> tmp = Expression() { exprList.add(tmp);  })*)? <RIGHTDBLBRACE>
    {
      expr.setExprList(exprList);
      return expr;
    }    
}

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

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


Expression FunctionCallExpr() throws ParseException:
{
  CallExpr callExpr;
  List<Expression> argList = new ArrayList<Expression>();
  Expression tmp;
  int arity = 0;
  FunctionName funcName = null;
  String hint = null;
}
{  
  funcName = FunctionName()
    {
      hint = getHint(token);
    }
  <LEFTPAREN> (tmp = Expression()
    {
      argList.add(tmp);
      arity ++;
    }
  (<COMMA> tmp = Expression()
    {
      argList.add(tmp);
      arity++;
    }
  )*)? <RIGHTPAREN>
    {
      // TODO use funcName.library
      String fqFunctionName = funcName.library == null ? funcName.function : funcName.library + "#" + funcName.function;
      FunctionSignature signature
        = lookupFunctionSignature(funcName.dataverse, fqFunctionName, arity);
      if (signature == null) {
        signature = new FunctionSignature(funcName.dataverse, fqFunctionName, arity);
      }
      callExpr = new CallExpr(signature,argList);
      if (hint != null) {
        if (hint.startsWith(INDEXED_NESTED_LOOP_JOIN_HINT)) {
          callExpr.addHint(IndexedNLJoinExpressionAnnotation.INSTANCE);
        } else if (hint.startsWith(SKIP_SECONDARY_INDEX_SEARCH_HINT)) {
          callExpr.addHint(SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE);
        }
      }
      return callExpr;
    }
}


Expression DatasetAccessExpression() throws ParseException:
{
  String funcName;
  String arg1 = null;
  String arg2 = null;
  Expression nameArg;
}
{  
  <DATASET>
    {
      funcName = token.image;
    }
  ( ( arg1 = Identifier() ( <DOT> arg2 = Identifier() )? ) 
    {
      String name = arg2 == null ? arg1 : arg1 + "." + arg2;
      LiteralExpr ds = new LiteralExpr();
      ds.setValue( new StringLiteral(name) );
      nameArg = ds;
    }
  | ( <LEFTPAREN> nameArg = Expression() <RIGHTPAREN> ) )  
    {
      String dataverse = MetadataConstants.METADATA_DATAVERSE_NAME;
      FunctionSignature signature = lookupFunctionSignature(dataverse, funcName, 1);
      if (signature == null) {
        signature = new FunctionSignature(dataverse, funcName, 1);
      }
      List<Expression> argList = new ArrayList<Expression>();
      argList.add(nameArg);
      return new CallExpr(signature, argList);
    }
}

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()
    )
    {
      return clause;
    }
}

Clause ForClause()throws ParseException :
{
	ForClause fc = new ForClause();
	VariableExpr varExp;
	VariableExpr varPos = null;
	Expression inExp;
	extendCurrentScope();
}
{
    <FOR> varExp = Variable() (<AT> varPos = Variable())?  <IN> ( inExp = Expression() )
    {
      fc.setVarExpr(varExp);
      getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
      fc.setInExpr(inExp);
      if (varPos != null) {
        fc.setPosExpr(varPos);
	    getCurrentScope().addNewVarSymbolToScope(varPos.getVar());
      }
      return fc;
    }
}

Clause LetClause() throws ParseException:
{
	LetClause lc = new LetClause();
	VariableExpr varExp;
	Expression beExp;
	extendCurrentScope();
}
{
    <LET> varExp = Variable() <ASSIGN> beExp = Expression()
    {
      getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
      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);
    }
    
    (<COMMA> 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());
    } <ASSIGN>)?
    expr = Expression() 
       {
         GbyVariableExpressionPair pair1 = new GbyVariableExpressionPair(var, expr);    
         vePairList.add(pair1);
       }
    (<COMMA> ( LOOKAHEAD(2) var = Variable()
    {
      newScope.addNewVarSymbolToScope(var.getVar());
    } <ASSIGN>)?
    	expr = Expression()  
    	 {
           GbyVariableExpressionPair pair2 = new GbyVariableExpressionPair(var, expr);    
           vePairList.add(pair2);
         }
    	)*
    (<DECOR> decorVar = Variable() <ASSIGN> decorExpr = Expression()
       {    
         newScope.addNewVarSymbolToScope(decorVar.getVar()); 
         GbyVariableExpressionPair pair3 = new GbyVariableExpressionPair(decorVar, decorExpr);
         decorPairList.add(pair3);
       }
      (<COMMA> <DECOR> decorVar = Variable() <ASSIGN> 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());
    }
    (<COMMA> 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);
  }
  (<COMMA> expr = Expression() 
  	{
  		exprs.add(expr); 
  	} 
  )*
  {
  	return new DistinctClause(exprs);
  }
}

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);
	}
	(
	<COMMA> 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;
    public IntStack lexerStateStack = new IntStack();
    
    public void pushState() {
      lexerStateStack.push( curLexState );
    }
    
    public void popState() {
      if (lexerStateStack.size() > 0) {
         SwitchTo( lexerStateStack.pop() );
      } else {
         throw new RuntimeException();
      }
    }
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <ASC : "asc">
  | <AT : "at">
  | <BY : "by">
  | <DATASET : "dataset">
  | <DECOR : "decor">
  | <DESC : "desc">
  | <DISTINCT : "distinct">
  | <ELSE : "else">
  | <EVERY : "every">
  | <FOR : "for">
  | <GROUP : "group">
  | <IF : "if">
  | <IN : "in">
  | <LET : "let">
  | <LIMIT : "limit">
  | <OFFSET : "offset">
  | <ORDER : "order">
  | <RETURN : "return">
  | <SATISFIES : "satisfies">
  | <SOME : "some">
  | <THEN : "then">
  | <UNION : "union">
  | <WHERE : "where">
  | <WITH : "with">
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <CARET : "^">
  | <DIV : "/">
  | <IDIV : "idiv">
  | <MINUS : "-">
  | <MOD : "%">
  | <MUL : "*">
  | <PLUS : "+">

  | <LEFTPAREN : "(">
  | <RIGHTPAREN : ")">
  | <LEFTBRACKET : "[">
  | <RIGHTBRACKET : "]">

  | <COLON : ":">
  | <COMMA : ",">
  | <DOT : ".">
  | <QUES : "?">

  | <LT : "<">
  | <GT : ">">
  | <LE : "<=">
  | <GE : ">=">
  | <EQ : "=">
  | <NE : "!=">
  | <SIMILAR : "~=">
  | <ASSIGN : ":=">

  | <AND : "and">
  | <OR : "or">
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <LEFTBRACE : "{"> { pushState(); } : DEFAULT
}

<DEFAULT>
TOKEN :
{
    <RIGHTBRACE : "}"> { popState(); }
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <LEFTDBLBRACE : "{{"> { pushState(); } : IN_DBL_BRACE
}

<IN_DBL_BRACE>
TOKEN :
{
    <RIGHTDBLBRACE : "}}"> { popState(); }
}

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

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <NULL : "null">
  | <TRUE : "true">
  | <FALSE : "false">
}

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

<DEFAULT,IN_DBL_BRACE>
TOKEN:
{
    < DOUBLE_LITERAL: <DIGITS>
        | <DIGITS> ( "." <DIGITS> )?
        | "." <DIGITS>
    >
  | < FLOAT_LITERAL: <DIGITS> ( "f" | "F" )
        | <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
        | "." <DIGITS> ( "f" | "F" )
    >
  | <DIGITS : (<DIGIT>)+ >
}

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <#LETTER : ["A" - "Z", "a" - "z"]>
  | <SPECIALCHARS : ["$", "_", "-"]>
}

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

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

<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
    <VARIABLE : "$" <LETTER> (<LETTER> | <DIGIT> | "_")*>
}

<DEFAULT,IN_DBL_BRACE>
SKIP:
{
    " "
  | "\t"
  | "\r"
  | "\n"
}

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

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

<DEFAULT,IN_DBL_BRACE>
SKIP:
{
    <"/*"> { pushState(); } : INSIDE_COMMENT
}

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

<INSIDE_COMMENT>
SKIP:
{
    <"/*"> { pushState(); }
}

<INSIDE_COMMENT>
SKIP:
{
    <"*/"> { popState(); }
  | <~[]>
}
