/*
 *
 * 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.
 *
 */

 //
 // Original File from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html>
 //

// ----------------------------------------------------------------------------
// OPTIONS
// ----------------------------------------------------------------------------
options {
  STATIC = false;
  UNICODE_INPUT = true;

  // some performance optimizations
  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.
 *
 */

package org.apache.qpid.server.filter.selector;

import java.io.StringReader;
import java.util.ArrayList;

import org.apache.qpid.server.filter.ArithmeticExpression;
import org.apache.qpid.server.filter.BooleanExpression;
import org.apache.qpid.server.filter.ComparisonExpression;
import org.apache.qpid.server.filter.ConstantExpression;
import org.apache.qpid.server.filter.Expression;
import org.apache.qpid.server.filter.LogicExpression;
import org.apache.qpid.server.filter.PropertyExpression;
import org.apache.qpid.server.filter.PropertyExpressionFactory;
import org.apache.qpid.server.filter.UnaryExpression;

/**
 * JMS Selector Parser generated by JavaCC
 *
 * Do not edit this .java file directly - it is autogenerated from SelectorParser.jj
 */
public class SelectorParser<E>
{
    private PropertyExpressionFactory<E> _factory;

    public SelectorParser()
    {
        this(new StringReader(""));
    }

    public void setPropertyExpressionFactory(PropertyExpressionFactory<E> factory)
    {
        _factory = factory;
    }

    public BooleanExpression<E> parse(String sql) throws ParseException
    {
        this.ReInit(new StringReader(sql));

        return this.JmsSelector();

    }

    private BooleanExpression<E> asBooleanExpression(Expression<E> value) throws ParseException
    {
        if (value instanceof BooleanExpression)
        {
            return (BooleanExpression<E>) value;
        }
        if (value instanceof PropertyExpression)
        {
            return UnaryExpression.createBooleanCast( (Expression<E>) value );
        }
        throw new ParseException("Expression 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" >
}

/* 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","_", "$"])* >
    | < QUOTED_ID : "\"" ( ("\"\"") | ~["\""] )*  "\""  >
}

// ----------------------------------------------------------------------------
// Grammer
// ----------------------------------------------------------------------------
BooleanExpression JmsSelector() :
{
    Expression left=null;
}
{
    (
        left = orExpression() <EOF>
    )
    {
        return asBooleanExpression(left);
    }

}

Expression orExpression() :
{
    Expression left;
    Expression right;
}
{
    (
        left = andExpression()
        (
            <OR> right = andExpression()
            {
                left = LogicExpression.createOR(asBooleanExpression(left), asBooleanExpression(right));
            }
        )*
    )
    {
        return left;
    }

}


Expression andExpression() :
{
    Expression left;
    Expression right;
}
{
    (
        left = equalityExpression()
        (
            <AND> right = equalityExpression()
            {
                left = LogicExpression.createAND(asBooleanExpression(left), asBooleanExpression(right));
            }
        )*
    )
    {
        return left;
    }
}

Expression equalityExpression() :
{
    Expression left;
    Expression right;
}
{
    (
        left = comparisonExpression()
        (

            "=" right = comparisonExpression()
            {
                left = ComparisonExpression.createEqual(left, right);
            }
            |
            "<>" right = comparisonExpression()
            {
                left = ComparisonExpression.createNotEqual(left, right);
            }
            |
            LOOKAHEAD(2)
            <IS> <NULL>
            {
                left = ComparisonExpression.createIsNull(left);
            }
            |
            <IS> <NOT> <NULL>
            {
                left = ComparisonExpression.createIsNotNull(left);
            }
        )*
    )
    {
        return left;
    }
}

Expression comparisonExpression() :
{
    Expression left;
    Expression right;
    Expression low;
    Expression high;
    String t, u;
	boolean not;
	ArrayList list;
}
{
    (
        left = addExpression()
        (

                ">" right = addExpression()
                {
                    left = ComparisonExpression.createGreaterThan(left, right);
                }
            |
                ">=" right = addExpression()
                {
                    left = ComparisonExpression.createGreaterThanEqual(left, right);
                }
            |
                "<" right = addExpression()
                {
                    left = ComparisonExpression.createLessThan(left, right);
                }
            |
                "<=" right = addExpression()
                {
                    left = ComparisonExpression.createLessThanEqual(left, right);
                }
           |
				{
					u=null;
				}
		        <LIKE> t = stringLiteral()
		        	[ <ESCAPE> u = stringLiteral() ]
		        {
                    left = ComparisonExpression.createLike(left, t, u);
		        }
           |
	        	LOOKAHEAD(2)
				{
					u=null;
				}
		        <NOT> <LIKE> t = stringLiteral() [ <ESCAPE> u = stringLiteral() ]
		        {
                    left = ComparisonExpression.createNotLike(left, t, u);
		        }
            |
		        <BETWEEN> low = addExpression() <AND> high = addExpression()
		        {
					left = ComparisonExpression.createBetween(left, low, high);
		        }
	        |
	        	LOOKAHEAD(2)
		        <NOT> <BETWEEN> low = addExpression() <AND> high = addExpression()
		        {
					left = ComparisonExpression.createNotBetween(left, low, high);
		        }
            |
				<IN>
		        "("
		            t = stringLiteral()
		            {
			            list = new ArrayList();
			            list.add( t );
		            }
			        (
			        	","
			            t = stringLiteral()
			            {
				            list.add( t );
			            }

			        )*
		        ")"
		        {
		           left = ComparisonExpression.createInFilter(left, list, false );
		        }
            |
	        	LOOKAHEAD(2)
	            <NOT> <IN>
		        "("
		            t = stringLiteral()
		            {
			            list = new ArrayList();
			            list.add( t );
		            }
			        (
			        	","
			            t = stringLiteral()
			            {
				            list.add( t );
			            }

			        )*
		        ")"
		        {
		           left = ComparisonExpression.createNotInFilter(left, list, false);
		        }

        )*
    )
    {
        return left;
    }
}

Expression addExpression() :
{
    Expression left;
    Expression right;
}
{
    left = multExpr()
    (
	    LOOKAHEAD( ("+"|"-") multExpr())
	    (
	        "+" right = multExpr()
	        {
	            left = ArithmeticExpression.createPlus(left, right);
	        }
	        |
	        "-" right = multExpr()
	        {
	            left = ArithmeticExpression.createMinus(left, right);
	        }
        )

    )*
    {
        return left;
    }
}

Expression multExpr() :
{
    Expression left;
    Expression right;
}
{
    left = unaryExpr()
    (
        "*" right = unaryExpr()
        {
	        left = ArithmeticExpression.createMultiply(left, right);
        }
        |
        "/" right = unaryExpr()
        {
	        left = ArithmeticExpression.createDivide(left, right);
        }
        |
        "%" right = unaryExpr()
        {
	        left = ArithmeticExpression.createMod(left, right);
        }

    )*
    {
        return left;
    }
}


Expression unaryExpr() :
{
    String s=null;
    Expression left=null;
}
{
	(
		LOOKAHEAD( "+" unaryExpr() )
	    "+" left=unaryExpr()
	    |
	    "-" left=unaryExpr()
	    {
	        left = UnaryExpression.createNegate(left);
	    }
	    |
	    <NOT> left=unaryExpr()
	    {
		    left = UnaryExpression.createNOT( asBooleanExpression(left) );
	    }
	    |
	    left = primaryExpr()
    )
    {
        return left;
    }

}

Expression primaryExpr() :
{
    Expression left=null;
}
{
    (
        left = literal()
        |
        left = variable()
        |
        "(" left = orExpression() ")"
    )
    {
        return left;
    }
}



ConstantExpression literal() :
{
    Token t;
    String s;
    ConstantExpression left=null;
}
{
    (
        (
            s = stringLiteral()
            {
                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 stringLiteral() :
{
    Token t;
    StringBuffer rc = new StringBuffer();
    boolean first=true;
}
{
    t = <STRING_LITERAL>
    {
    	// Decode the sting value.
    	String image = t.image;
    	for( int i=1; i < image.length()-1; i++ ) {
            char c = image.charAt(i);
            if( c == (char) 0x27 )//single quote
            {
                i++;
            }
            rc.append(c);
    	}
	    return rc.toString();
    }
}

PropertyExpression variable() :
{
    Token t;
    StringBuffer rc = new StringBuffer();
    PropertyExpression left=null;
}
{
    (
        t = <ID>
        {
            left = _factory.createPropertyExpression(t.image);
        }
        |
        t = <QUOTED_ID>
        {
            // Decode the sting value.
            String image = t.image;
            for( int i=1; i < image.length()-1; i++ ) {
                char c = image.charAt(i);
                if( c == '"' )
                {
                    i++;
                }
                rc.append(c);
            }
            return _factory.createPropertyExpression(rc.toString());
        }


    )
    {
        return left;
    }
}
