*******************************************************************************
 * Copyright (c) 2005 BEA Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     BEA Systems - initial implementation
 *     
 *******************************************************************************/
/* I know that having some of these options on one line is rude but 
 * if we don't do that the line number reported from javacc are off
 * which, trust me, is far more annoying.  --tcarroll@bea.com
 */
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;
}

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() | 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> OrExpression() <COLON> OrExpression()
}

void UnaryExpression() : {}
{
        ((<NOT1> | <NOT2> | <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>
}
