/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// ----------------------------------------------------------------------------
// OPTIONS
// ----------------------------------------------------------------------------
options {
  STATIC = false;
  UNICODE_INPUT = true;
  
  // some performance optimizations
  OPTIMIZE_TOKEN_MANAGER = true;
  ERROR_REPORTING = false;
}

// ----------------------------------------------------------------------------
// PARSER
// ----------------------------------------------------------------------------

PARSER_BEGIN(SelectorParser)
/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
using System;
using System.IO;
using System.Text;
using System.Collections;

using Apache.NMS;

//namespace Apache.NMS.Selector
//{
    /// <summary>
    /// JMS Selector Parser generated by <a href="https://github.com/deveel/csharpcc">CSharpCC</a>
    /// 
    /// Do not edit this .cs file directly - it is autogenerated from SelectorParser.csc
    /// using <c>csharpcc.exe -UNICODE_INPUT=true SelectorParser.csc</c>.
    /// 
    /// SelectorParser.csc is adapted from
    /// <a href="https://raw.githubusercontent.com/apache/activemq/activemq-4.0/activemq-core/src/main/grammar/SelectorParser.jj">
    /// ActiveMQ 4.0 SelectorParser.jj</a>
    /// </summary>
    public class SelectorParser
    {

        public SelectorParser()
        {
        }

        public IBooleanExpression Parse(string selector)
        {
            this.ReInit(new StringReader(selector));

            try
            {
                return this.JmsSelector();
            } 
            catch(Exception e)
            {
	            throw new InvalidSelectorException(selector, e);
            }
        }

        private IBooleanExpression AsBooleanExpression(IExpression value)
        {
            if(value is IBooleanExpression)
            {
                return (IBooleanExpression)value;
            }
            if(value is PropertyExpression)
            {
                return UnaryExpression.CreateBooleanCast(value);
            }
            throw new ParseException("IExpression will not result in a boolean value: " + value);
        }
    }

//}

PARSER_END(SelectorParser)

// ----------------------------------------------------------------------------
// Tokens
// ----------------------------------------------------------------------------

/* White Space */
SPECIAL_TOKEN :
{
  " " | "\t" | "\n" | "\r" | "\f"
}

/* Comments */
SKIP:
{
  <LINE_COMMENT: "--" (~["\n","\r"])* ("\n"|"\r"|"\r\n") >
}

SKIP:
{
  <BLOCK_COMMENT: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/">
}

/* Reserved Words */
TOKEN [IGNORE_CASE] :
{
    <  NOT     : "NOT">
  | <  AND     : "AND">
  | <  OR      : "OR">
  | <  BETWEEN : "BETWEEN">
  | <  LIKE    : "LIKE">
  | <  ESCAPE  : "ESCAPE">
  | <  IN      : "IN">
  | <  IS      : "IS">
  | <  TRUE    : "TRUE" >
  | <  FALSE   : "FALSE" >
  | <  NULL    : "NULL" >
  | <  XPATH   : "XPATH" >
  | <  XQUERY  : "XQUERY" >
}

/* Literals */
TOKEN [IGNORE_CASE] :
{

    < DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* (["l","L"])? >
  | < HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
  | < OCTAL_LITERAL: "0" (["0"-"7"])* >  
  | < FLOATING_POINT_LITERAL:  		  
          (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? // matches: 5.5 or 5. or 5.5E10 or 5.E10
        | "." (["0"-"9"])+ (<EXPONENT>)?              // matches: .5 or .5E10
        | (["0"-"9"])+ <EXPONENT>                     // matches: 5E10
    >
  | < #EXPONENT: "E" (["+","-"])? (["0"-"9"])+ >
  | < STRING_LITERAL: "'" ( ("''") | ~["'"] )*  "'" >
}

TOKEN [IGNORE_CASE] :
{
    < ID : ["a"-"z", "_", "$"] (["a"-"z","0"-"9","_", "$"])* >
}

// ----------------------------------------------------------------------------
// Grammar
// ----------------------------------------------------------------------------
IBooleanExpression JmsSelector() :
{
    IExpression left = null;
}
{
    (
        left = GetOrExpression()
    ) 
    {
        return AsBooleanExpression(left);
    }

}

IExpression GetOrExpression() :
{
    IExpression left;
    IExpression right;
}
{
    (
        left = GetAndExpression() 
        ( 
            <OR> right = GetAndExpression() 
            {
                left = LogicExpression.CreateOR(AsBooleanExpression(left), AsBooleanExpression(right));
            }
        )*
    ) 
    {
        return left;
    }

}


IExpression GetAndExpression() :
{
    IExpression left;
    IExpression right;
}
{
    (
        left = GetEqualityExpression() 
        ( 
            <AND> right = GetEqualityExpression() 
            {
                left = LogicExpression.CreateAND(AsBooleanExpression(left), AsBooleanExpression(right));
            }
        )*
    ) 
    {
        return left;
    }
}

IExpression GetEqualityExpression() :
{
    IExpression left;
    IExpression right;
}
{
    (
        left = GetComparisonExpression() 
        ( 
            
            "=" right = GetComparisonExpression() 
            {
                left = ComparisonExpression.CreateEqual(left, right);
            }
            |            
            "<>" right = GetComparisonExpression() 
            {
                left = ComparisonExpression.CreateNotEqual(left, right);
            }
            |            
            LOOKAHEAD(2)
            <IS> <NULL>
            {
                left = ComparisonExpression.CreateIsNull(left);
            }
            |            
            <IS> <NOT> <NULL>
            {
                left = ComparisonExpression.CreateIsNotNull(left);
            }
        )*
    ) 
    {
        return left;
    }
}

IExpression GetComparisonExpression() :
{
    IExpression left;
    IExpression right;
    IExpression low;
    IExpression high;
    string t;
    string u;
	ArrayList list;
}
{
    (
        left = GetAddExpression() 
        ( 
            
                ">" right = GetAddExpression() 
                {
                    left = ComparisonExpression.CreateGreaterThan(left, right);
                }
            |            
                ">=" right = GetAddExpression() 
                {
                    left = ComparisonExpression.CreateGreaterThanOrEqual(left, right);
                }
            |            
                "<" right = GetAddExpression() 
                {
                    left = ComparisonExpression.CreateLesserThan(left, right);
                }
            |            
                "<=" right = GetAddExpression() 
                {
                    left = ComparisonExpression.CreateLesserThanOrEqual(left, right);
                }
           |
				{
					u = null;
				}           		
		        <LIKE> t = GetStringLitteral() 
		        	[ <ESCAPE> u = GetStringLitteral() ]
		        {
                    left = ComparisonExpression.CreateLike(left, t, u);
		        }
           |
	        	LOOKAHEAD(2)
				{
					u=null;
				}           		
		        <NOT> <LIKE> t = GetStringLitteral() [ <ESCAPE> u = GetStringLitteral() ]
		        {
                    left = ComparisonExpression.CreateNotLike(left, t, u);
		        }
            |
		        <BETWEEN> low = GetAddExpression() <AND> high = GetAddExpression()
		        {
					left = ComparisonExpression.CreateBetween(left, low, high);
		        }
	        |
	        	LOOKAHEAD(2)
		        <NOT> <BETWEEN> low = GetAddExpression() <AND> high = GetAddExpression()
		        {
					left = ComparisonExpression.CreateNotBetween(left, low, high);
		        }
            |
				<IN> 
		        "(" 
		            t = GetStringLitteral()
		            {
			            list = new ArrayList();
			            list.Add(t);
		            }
			        ( 
			        	","
			            t = GetStringLitteral() 
			            {
				            list.Add(t);
			            }
			        	
			        )*
		        ")"
		        {
		           left = ComparisonExpression.CreateIn(left, list);
		        }
            |
	        	LOOKAHEAD(2)
	            <NOT> <IN> 
		        "(" 
		            t = GetStringLitteral()
		            {
			            list = new ArrayList();
			            list.Add(t);
		            }
			        ( 
			        	","
			            t = GetStringLitteral() 
			            {
				            list.Add(t);
			            }
			        	
			        )*
		        ")"
		        {
		           left = ComparisonExpression.CreateNotIn(left, list);
		        }
            
        )*
    ) 
    {
        return left;
    }
}

IExpression GetAddExpression() :
{
    IExpression left;
    IExpression right;
}
{
    left = GetMultiplyExpression() 
    ( 
	    LOOKAHEAD( ("+"|"-") GetMultiplyExpression())
	    (
	        "+" right = GetMultiplyExpression() 
	        {
	            left = ArithmeticExpression.CreatePlus(left, right);
	        }
	        |            
	        "-" right = GetMultiplyExpression() 
	        {
	            left = ArithmeticExpression.CreateMinus(left, right);
	        }
        )
        
    )*
    {
        return left;
    }
}

IExpression GetMultiplyExpression() :
{
    IExpression left;
    IExpression right;
}
{
    left = GetUnaryExpression() 
    ( 
        "*" right = GetUnaryExpression() 
        {
	        left = ArithmeticExpression.CreateMultiply(left, right);
        }
        |            
        "/" right = GetUnaryExpression() 
        {
	        left = ArithmeticExpression.CreateDivide(left, right);
        }
        |            
        "%" right = GetUnaryExpression() 
        {
	        left = ArithmeticExpression.CreateMod(left, right);
        }
        
    )*
    {
        return left;
    }
}


IExpression GetUnaryExpression() :
{
    IExpression left = null;
}
{
	(
		LOOKAHEAD( "+" GetUnaryExpression() )
	    "+" left = GetUnaryExpression()
	    |
	    "-" left = GetUnaryExpression()
	    {
	        left = UnaryExpression.CreateNegate(left);
	    }
	    |
	    <NOT> left = GetUnaryExpression()
	    {
		    left = UnaryExpression.CreateNOT(AsBooleanExpression(left));
	    }
	    |
	    left = GetPrimaryExpression()
    )
    {
        return left;
    }

}

IExpression GetPrimaryExpression() :
{
    IExpression left = null;
}
{
    (
        left = GetLiteral()
        |
        left = GetVariable()
        |
        "(" left = GetOrExpression() ")"
    ) 
    {
        return left;
    }
}



ConstantExpression GetLiteral() :
{
    Token t;
    string s;
    ConstantExpression left = null;
}
{
    (
        (
            s = GetStringLitteral()
            {
                left = new ConstantExpression(s);
            }
        ) 
        | 
        (
            t = <DECIMAL_LITERAL>
            {
            	left = ConstantExpression.CreateFromDecimal(t.image);
            }    
        ) 
        | 
        (
            t = <HEX_LITERAL>
            {
            	left = ConstantExpression.CreateFromHex(t.image);
            }    
        ) 
        | 
        (
            t = <OCTAL_LITERAL>
            {
            	left = ConstantExpression.CreateFromOctal(t.image);
            }    
        ) 
        | 
        (
            t = <FLOATING_POINT_LITERAL>
            {
            	left = ConstantExpression.CreateFloat(t.image);
            }    
        ) 
        | 
        (
            <TRUE>
            {
                left = ConstantExpression.TRUE;
            }    
        ) 
        | 
        (
            <FALSE>
            {
                left = ConstantExpression.FALSE;
            }    
        ) 
        | 
        (
            <NULL>
            {
                left = ConstantExpression.NULL;
            }    
        )
    )
    {
        return left;
    }
}

string GetStringLitteral() :
{
    Token t;
    StringBuilder rc = new StringBuilder();
}
{
    t = <STRING_LITERAL> 
    {
    	// Decode the sting value.
    	String image = t.image;
    	for(int c = 1; c < image.Length - 1; c++)
        {
    		char ch = image[c];
    		if(ch == '\'')
            {
    			c++;    			
            }
   			rc.Append(ch);
    	}
	    return rc.ToString();
    }    
}

PropertyExpression GetVariable() :
{
    Token t;
    PropertyExpression left = null;
}
{
    ( 
        t = <ID> 
        {
            left = new PropertyExpression(t.image);
        }    
    )
    {
        return left;
    }
}
