/*
 *
 * 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.filter.selector;

import java.io.StringReader;
import java.util.ArrayList;

import org.apache.qpid.filter.ArithmeticExpression;
import org.apache.qpid.filter.BooleanExpression;
import org.apache.qpid.filter.ComparisonExpression;
import org.apache.qpid.filter.ConstantExpression;
import org.apache.qpid.filter.Expression;
import org.apache.qpid.filter.LogicExpression;
import org.apache.qpid.filter.PropertyExpression;
import org.apache.qpid.filter.PropertyExpressionFactory;
import org.apache.qpid.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;
    }
}
