options {
  JAVA_UNICODE_ESCAPE = false;
  UNICODE_INPUT = true;
  STATIC = false;
  OPTIMIZE_TOKEN_MANAGER = true;
  MULTI = true;
  VISITOR = true;
  NODE_PACKAGE = "org.eclipse.jst.jsp.core.internal.java.jspel";
  NODE_SCOPE_HOOK = true; 
  DEBUG_PARSER = true;
}

PARSER_BEGIN(JSPELParser)

package org.eclipse.jst.jsp.core.internal.java.jspel;

public class JSPELParser {
  
  void jjtreeOpenNodeScope(Node n)
  {
  	((SimpleNode)n).setFirstToken(getToken(1));
  }

  void jjtreeCloseNodeScope(Node n)
  {
    ((SimpleNode)n).setLastToken(getToken(0));
  }
  
  public static JSPELParser createParser(java.lang.String input) {
  	java.io.StringReader reader = new java.io.StringReader(input);
  	return new JSPELParser(reader);
  }
  
  public void ReInit(java.lang.String input) {
   	java.io.StringReader reader = new java.io.StringReader(input);
   	ReInit(reader);
  }
  
}

PARSER_END(JSPELParser)

SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
}

TOKEN :
{
/* Literals */
  < INTEGER_LITERAL: ["0"-"9"] (["0"-"9"])* >
|
  < FLOATING_POINT_LITERAL:
        (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)?
      | "." (["0"-"9"])+ (<EXPONENT>)?
      | (["0"-"9"])+ <EXPONENT>
  >
|
  < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
|
  < STRING_LITERAL:
      ("\"" ((~["\"","\\"]) | ("\\" ( ["\\","\""] )))* "\"") |
      ("\'" ((~["\'","\\"]) | ("\\" ( ["\\","\'"] )))* "\'")
  >
|
  < BADLY_ESCAPED_STRING_LITERAL:
      ("\"" (~["\"","\\"])* ("\\" ( ~["\\","\""] ))) |
      ("\'" (~["\'","\\"])* ("\\" ( ~["\\","\'"] )))
  >

/* Reserved Words and Symbols */
| < TRUE: "true" >
| < FALSE: "false" >
| < NULL: "null" >
| < DOT: "." >
| < GT1: ">" >
| < GT2: "gt" >
| < LT1: "<" >
| < LT2: "lt" >
| < EQ1: "==" >
| < EQ2: "eq" >
| < LE1: "<=" >
| < LE2: "le" >
| < GE1: ">=" >
| < GE2: "ge" >
| < NEQ1: "!=" >
| < NEQ2: "ne" >
| < LPAREN: "(" >
| < RPAREN: ")" >
| < COMMA: "," >
| < COLON: ":" >
| < LBRACKET: "[" >
| < RBRACKET: "]" >
| < PLUS: "+" >
| < MINUS: "-" >
| < MULTIPLY: "*" >
| < DIVIDE1: "/" >
| < DIVIDE2: "div" >
| < MODULUS1: "%" >
| < MODULUS2: "mod" >
| < NOT1: "not" >
| < NOT2: "!" >
| < AND1: "and" >
| < AND2: "&&" >
| < OR1: "or" >
| < OR2: "||" >
| < EMPTY: "empty" >
| < COND: "?" >

/* Identifiers */

| < IDENTIFIER: (<LETTER>|<IMPL_OBJ_START>) (<LETTER>|<DIGIT>)* >
| < #IMPL_OBJ_START: "#" >
|
  < #LETTER:
      [
       "\u0024",
       "\u0041"-"\u005a",
       "\u005f",
       "\u0061"-"\u007a",
       "\u00c0"-"\u00d6",
       "\u00d8"-"\u00f6",
       "\u00f8"-"\u00ff",
       "\u0100"-"\u1fff",
       "\u3040"-"\u318f",
       "\u3300"-"\u337f",
       "\u3400"-"\u3d2d",
       "\u4e00"-"\u9fff",
       "\uf900"-"\ufaff"
      ]
  >
|
  < #DIGIT:
      [
       "\u0030"-"\u0039",
       "\u0660"-"\u0669",
       "\u06f0"-"\u06f9",
       "\u0966"-"\u096f",
       "\u09e6"-"\u09ef",
       "\u0a66"-"\u0a6f",
       "\u0ae6"-"\u0aef",
       "\u0b66"-"\u0b6f",
       "\u0be7"-"\u0bef",
       "\u0c66"-"\u0c6f",
       "\u0ce6"-"\u0cef",
       "\u0d66"-"\u0d6f",
       "\u0e50"-"\u0e59",
       "\u0ed0"-"\u0ed9",
       "\u1040"-"\u1049"
      ]
  >
}

ASTExpression Expression() : {}
{
	LOOKAHEAD(ChoiceExpression()) ChoiceExpression() | OrExpression() { return jjtThis; }
}

void OrExpression() #OrExpression(>1) : 
{
	Token t;
}
{
	AndExpression() ((t = <OR1> | t = <OR2>) { jjtThis.addOperatorToken(t); }
	AndExpression())*
}

void AndExpression() #AndExpression(>1) : 
{
	Token t;
}
{
	EqualityExpression() ((t = <AND1> | t = <AND2>) { jjtThis.addOperatorToken(t); }
	EqualityExpression())*	
}

void EqualityExpression() #EqualityExpression(>1) : 
{
	Token t;
}
{
	RelationalExpression() 
	((t = <EQ1> | t = <EQ2> | t = <NEQ1> | t = <NEQ2>) { jjtThis.addOperatorToken(t); }
	RelationalExpression())*
}

void RelationalExpression() #RelationalExpression(>1) :
{
	Token t;
}
{
	AddExpression() 
	(
		(t = <LT1> | t = <LT2> | t = <GT1> | t = <GT2> | t = <GE1> | t = <GE2> | t = <LE1> | t = <LE2>)  { jjtThis.addOperatorToken(t); }
		AddExpression()
	)*
}

void AddExpression() #AddExpression(>1) : 
{
	Token t;
}
{
	MultiplyExpression() ((t = <PLUS> | t = <MINUS>) { jjtThis.addOperatorToken(t); }
	MultiplyExpression())*
}

void MultiplyExpression() #MultiplyExpression(>1) : 
{
	Token t;
}
{
	UnaryExpression() (
		( t = <MULTIPLY> | t = <DIVIDE1> | t = <DIVIDE2> | t = <MODULUS1> | t = <MODULUS2>) { jjtThis.addOperatorToken(t); }
		UnaryExpression()	
	)*
}

void ChoiceExpression() : {}
{
	OrExpression() <COND> Expression() <COLON> Expression()
}

void UnaryExpression() : {}
{
	((<NOT1> | <MINUS> | <EMPTY>) UnaryExpression())
	| Value()
	
}

void Value() : {}
{
	ValuePrefix() (ValueSuffix())*
}

void ValuePrefix() : {}
{
    Literal() | (<LPAREN> Expression() <RPAREN>) | LOOKAHEAD(3) FunctionInvocation() | <IDENTIFIER> 
}

void ValueSuffix() : 
{
	Token t = null;
}
{
	(<DOT> (t = <IDENTIFIER>)?) { jjtThis.setPropertyNameToken(t); }
	| (<LBRACKET> Expression() <RBRACKET>)
}

void FunctionInvocation() : 
{
	Token prefix = null, name = null;
}
{
    (prefix = <IDENTIFIER> <COLON>) { jjtThis.setFullFunctionName(prefix.image + ":"); }
	(name = <IDENTIFIER>)? {
    	if(null != prefix && null != name)
	    	jjtThis.setFullFunctionName(prefix.image + ":" + (null == name ? "" : name.image));
	    else if(null != name)
	    	jjtThis.setFullFunctionName(name.image);
	}
	(<LPAREN> Expression() (<COMMA> Expression())* try  { (<RPAREN>) } catch (Exception e) {} )?
}

void Literal() : {}
{
	<TRUE> | <FALSE> | <INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> | <STRING_LITERAL> | <NULL>
}
