/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. QueryParser.jj */
/*@egen*//**
 * A simple boolean query language that supports a number of features for free text querying.  These
 * features include: "and"s, "or"s, sub-expressions using parens "( )", negation, and prefix and postfix wildcard queries.
 *
 * Most of the classes in this package are auto-generated from QueryParser.jjt using javacc and jjtree.  ASTExpression and
 * ASTTerm slightly modified versions of the auto-generated files.
 * 
 * I highly recommend the "JavaCC Eclipse Plug-in".
 */options{
                 JDK_VERSION = "1.5";  IGNORE_CASE = true;                         
  static = false;
//  DEBUG_PARSER = true;
//  DEBUG_LOOKAHEAD = true;}PARSER_BEGIN(QueryParser)package mvm.rya.indexing.accumulo.freetext.query;
import java.io.StringReader;
public class QueryParser/*@bgen(jjtree)*/implements QueryParserTreeConstants/*@egen*/{/*@bgen(jjtree)*/
  protected JJTQueryParserState jjtree = new JJTQueryParserState();

/*@egen*/
  // Helper method to parse Strings (instead of streams)
  public static SimpleNode parse(String query) throws ParseException, TokenMgrError  {    QueryParser parser = new QueryParser(new StringReader(query));    return parser.Start();  }}PARSER_END(QueryParser)SKIP : /* Ignore Whitespace */{  " " | "\t" | "\n" | "\r"
}
TOKEN : {
  <AND:       ("AND" | "&&" | "&") >
| <OR:        ("OR" | "||" | "|") >
| <NOT:       ("NOT" | "!") >
| <LPAREN:    "(" >
| <RPAREN:    ")" >
| <QUOTED:     "\"" (<_QUOTED_CHAR>)* "\"">
| <#_QUOTED_CHAR:  ~[ "\""] >
| <TERM:      <_TERM_CHAR> (<_TERM_CHAR>)*  >
| <PREFIXTERM:  "*" <TERM> >
| <WILDTERM:   <TERM> "*" >
| <#_TERM_CHAR: ~[ " ", "\t", "\n", "\r", "*", "(", ")", "!"] >
}  
SimpleNode Start()            :{/*@bgen(jjtree) SimpleNode */
  ASTSimpleNode jjtn000 = new ASTSimpleNode(JJTSIMPLENODE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}{/*@bgen(jjtree) SimpleNode */
   try {
/*@egen*/
  // "or"s have the lowest order of operations, so they will be highest on the tree.  Start with them.   OrExpression() < EOF >/*@bgen(jjtree)*/
  {
    jjtree.closeNodeScope(jjtn000, true);
    jjtc000 = false;
  }
/*@egen*/  {    return jjtn000;  }/*@bgen(jjtree)*/
   } catch (Throwable jjte000) {
     if (jjtc000) {
       jjtree.clearNodeScope(jjtn000);
       jjtc000 = false;
     } else {
       jjtree.popNode();
     }
     if (jjte000 instanceof RuntimeException) {
       throw (RuntimeException)jjte000;
     }
     if (jjte000 instanceof ParseException) {
       throw (ParseException)jjte000;
     }
     throw (Error)jjte000;
   } finally {
     if (jjtc000) {
       jjtree.closeNodeScope(jjtn000, true);
     }
   }
/*@egen*/}

void OrExpression()                :
{/*@bgen(jjtree) #Expression(> 1) */
  ASTExpression jjtn000 = new ASTExpression(JJTEXPRESSION);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/ jjtn000.setType(ASTExpression.OR); }	
{/*@bgen(jjtree) #Expression(> 1) */
  try {
/*@egen*/
  AndExpression() (< OR > AndExpression())*/*@bgen(jjtree)*/
  } catch (Throwable jjte000) {
    if (jjtc000) {
      jjtree.clearNodeScope(jjtn000);
      jjtc000 = false;
    } else {
      jjtree.popNode();
    }
    if (jjte000 instanceof RuntimeException) {
      throw (RuntimeException)jjte000;
    }
    if (jjte000 instanceof ParseException) {
      throw (ParseException)jjte000;
    }
    throw (Error)jjte000;
  } finally {
    if (jjtc000) {
      jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
    }
  }
/*@egen*/}

void AndExpression()                :{/*@bgen(jjtree) #Expression(> 1) */
  ASTExpression jjtn000 = new ASTExpression(JJTEXPRESSION);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/ jjtn000.setType(ASTExpression.AND); }
{/*@bgen(jjtree) #Expression(> 1) */
  try {
/*@egen*/  Term() ([< AND >] Term())*/*@bgen(jjtree)*/
  } catch (Throwable jjte000) {
    if (jjtc000) {
      jjtree.clearNodeScope(jjtn000);
      jjtc000 = false;
    } else {
      jjtree.popNode();
    }
    if (jjte000 instanceof RuntimeException) {
      throw (RuntimeException)jjte000;
    }
    if (jjte000 instanceof ParseException) {
      throw (ParseException)jjte000;
    }
    throw (Error)jjte000;
  } finally {
    if (jjtc000) {
      jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
    }
  }
/*@egen*/
}
void Term() :{ Token t; boolean notFlag = false; String type = ""; }{
  // Update the notFlag if a "not" is present
  [ < NOT > { notFlag = true; } ]

  (    // Create a term, if a term is present
    (	  t = < TERM > { type = ASTTerm.TERM; }	  | t = < WILDTERM > { type = ASTTerm.WILDTERM; }
	  | t = < PREFIXTERM > { type = ASTTerm.PREFIXTERM; }
	  | t = < QUOTED > { type = ASTTerm.QUOTED; }
	)/*@bgen(jjtree) #Term(true) */
        {
          ASTTerm jjtn001 = new ASTTerm(JJTTERM);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*//*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn001, true);
          jjtc001 = false;
        }
/*@egen*/	{ jjtn001.setTerm(t.image); jjtn001.setNotFlag(notFlag); jjtn001.setType(type); }/*@bgen(jjtree)*/
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001, true);
          }
        }
/*@egen*/        
	
    // Otherwise, we a dealing with a Sub-Expression, so start back from the top.
	| ( < LPAREN > ( OrExpression() ) <  RPAREN > )
    {
      // pass on the notFlag state to the sub-expression
      // note: the sub-expression might be a term (eg, "a" is a term in "!(!a)")
      {
	   if (notFlag) {
	     Node n = jjtree.peekNode();
	     if (n instanceof ASTExpression) {
	       boolean v = ((ASTExpression)n).isNotFlag();
		   ((ASTExpression)n).setNotFlag(v ^ notFlag);
	     }
	     if (n instanceof ASTTerm) {	       boolean v = ((ASTTerm)n).isNotFlag();		   ((ASTTerm)n).setNotFlag(v ^ notFlag);	      }
	    }
      }
    }
  )
  
}