// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
/**
* @author Simon Thoresen
* @version $Id$
*/
options {
CACHE_TOKENS = true;
DEBUG_PARSER = false;
ERROR_REPORTING = true;
IGNORE_CASE = true;
STATIC = false;
UNICODE_INPUT = true;
USER_CHAR_STREAM = true;
USER_TOKEN_MANAGER = false;
}
PARSER_BEGIN(SelectParser)
package com.yahoo.document.select.parser;
import com.yahoo.document.select.rule.*;
import java.math.BigInteger;
import java.util.List;
import java.util.ArrayList;
public class SelectParser {
}
PARSER_END(SelectParser)
SKIP :
{
" " | "\f" | "\n" | "\r" | "\t"
}
TOKEN :
{
(["l","L"])? | (["l","L"])? | (["l","L"])?> |
<#DECIMAL: ["1"-"9"] (["0"-"9"])*> |
<#HEX: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+> |
<#OCTAL: "0" (["0"-"7"])*> |
)? (["f","F","d","D"])?> |
<#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+>
}
TOKEN :
{
|
|
|
|
|
|
|
|
|
|
="> |
|
|
|
|
"> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
ExpressionNode expression() :
{
ExpressionNode ret = new LiteralNode(true);
}
{
( [ ret = logic() ] )
{ return ret; }
}
ExpressionNode logic() :
{
LogicNode lst = new LogicNode();
String op = null;
ExpressionNode node;
}
{
( node = negation() { lst.add(null, node); }
( ( | ) { op = token.image; }
node = negation() { lst.add(op, node); } )* )
{ return op != null ? lst : node; }
}
ExpressionNode negation() :
{
boolean not = false;
ExpressionNode node;
}
{
( [ { not = true; } ] node = relational() )
{ return not ? new NegationNode(node) : node; }
}
NowNode now() : { }
{
( )
{ return new NowNode(); }
}
ExpressionNode relational() :
{
ExpressionNode lhs, rhs = null;
String op = null;
}
{
( lhs = arithmetic()
[ ( | | | | | | | ) { op = token.image; }
rhs = arithmetic() ] )
{ return rhs != null ? new ComparisonNode(lhs, op, rhs) : lhs; }
}
ExpressionNode arithmetic() :
{
ArithmeticNode lst = new ArithmeticNode();
String op = null;
ExpressionNode node;
}
{
( node = attribute() { lst.add(null, node); }
( ( | | |
| ) { op = token.image; }
node = attribute() { lst.add(op, node); } )* )
{ return op != null ? lst : node; }
}
VariableNode variable() :
{
VariableNode ret;
}
{
( identifier() { ret = new VariableNode(token.image); } )
{ return ret; }
}
ExpressionNode attribute() :
{
ExpressionNode val;
AttributeNode.Item item;
List lst = new ArrayList();
}
{
( val = value() ( identifier() { item = new AttributeNode.Item(token.image); }
[ { item.setType(AttributeNode.Item.FUNCTION); } ]
{ lst.add(item); } )* )
{ return lst.size() > 0 ? new AttributeNode(val, lst) : val; }
}
ExpressionNode value() :
{
ExpressionNode ret;
}
{
( LOOKAHEAD(2)
( ret = id() |
ret = searchColumn() |
ret = literal() |
ret = variable() |
ret = now() |
ret = logic() { ret = new EmbracedNode(ret); } ) |
( ret = document() ) )
{ return ret; }
}
DocumentNode document() :
{
DocumentNode ret;
}
{
( identifier() { ret = new DocumentNode(token.image); } )
{ return ret; }
}
void identifier() : { }
{
( |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// | Causes a choice conflict, but it is not such a good name anyway ...
)
}
IdNode id() :
{
IdNode ret = new IdNode();
}
{
( [ LOOKAHEAD(2)
( { ret.setField(token.image); } |
{ ret.setField(token.image); } |
{ ret.setField(token.image); } |
{ ret.setField(token.image); } |
{ ret.setField(token.image); } |
{ ret.setField(token.image); } |
{ ret.setField(token.image); } |
( { ret.setField(token.image); }
{ ret.setWidthBits(Short.parseShort(token.image)); }
{ ret.setDivisionBits(Short.parseShort(token.image)); } ) )
] )
{ return ret; }
}
SearchColumnNode searchColumn() :
{
SearchColumnNode ret = new SearchColumnNode();
}
{
( [ LOOKAHEAD(2) { ret.setField(Integer.parseInt(token.image)); } ] )
{ return ret; }
}
LiteralNode literal() :
{
String sign = "";
Object ret = null;
}
{
( ( [ { sign = "-"; } ]
( { ret = Double.parseDouble(sign + token.image); } |
{ ret = SelectParserUtils.decodeLong(sign + token.image); } ) ) |
( { ret = Double.parseDouble(token.image); } ) |
( { ret = SelectParserUtils.unquote(token.image); } ) |
( { ret = true; } ) |
( { ret = false; } ) |
( { ret = null; } ) )
{ return new LiteralNode(ret); }
}