📄 ognl.jjt
字号:
//--------------------------------------------------------------------------
// Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// Neither the name of the Drew Davidson nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//--------------------------------------------------------------------------
/*
* This file defines the syntax of OGNL, the Object-Graph Navigation Language. This
* language was devised by Drew Davidson, who called it Key-Value Coding Language. Luke
* Blanshard then made up the new name and reimplemented it using ANTLR, refining and
* polishing the language a bit on the way. Drew maintained the system for a couple of
* years; then Luke converted the ANTLR grammar to JavaCC, to eliminate the run-time
* dependency on ANTLR.
*
* See package.html for a description of the language.
*/
options {
// Parser options
LOOKAHEAD = 1;
STATIC = false;
JAVA_UNICODE_ESCAPE = true;
UNICODE_INPUT = true;
// Tree options
MULTI = true;
NODE_DEFAULT_VOID = true;
}
PARSER_BEGIN(OgnlParser)
package ognl;
import java.math.*;
/**
* OgnlParser is a JavaCC parser class; it translates OGNL expressions into abstract
* syntax trees (ASTs) that can then be interpreted by the getValue and setValue methods.
*/
public class OgnlParser
{
}
PARSER_END(OgnlParser)
/**
* This is the top-level construct of OGNL.
*/
Node topLevelExpression() : {}
{
expression() <EOF> { return jjtree.rootNode(); }
}
// sequence (level 14)
void expression() : {}
{
assignmentExpression() ( "," assignmentExpression() #Sequence(2) )*
}
// assignment expression (level 13)
void assignmentExpression() : {}
{
conditionalTestExpression() [ "=" assignmentExpression() #Assign(2) ]
}
// conditional test (level 12)
void conditionalTestExpression() : {}
{
logicalOrExpression()
[ "?" conditionalTestExpression() ":" conditionalTestExpression() #Test(3) ]
}
// logical or (||) (level 11)
void logicalOrExpression() : {}
{
logicalAndExpression() (("||" | "or") logicalAndExpression() #Or(2) )*
}
// logical and (&&) (level 10)
void logicalAndExpression() : {}
{
inclusiveOrExpression() (("&&" | "and") inclusiveOrExpression() #And(2) )*
}
// bitwise or non-short-circuiting or (|) (level 9)
void inclusiveOrExpression() : {}
{
exclusiveOrExpression() (("|" | "bor") exclusiveOrExpression() #BitOr(2) )*
}
// exclusive or (^) (level 8)
void exclusiveOrExpression() : {}
{
andExpression() (("^" | "xor") andExpression() #Xor(2) )*
}
// bitwise or non-short-circuiting and (&) (level 7)
void andExpression() : {}
{
equalityExpression() (("&" | "band") equalityExpression() #BitAnd(2) )*
}
// equality/inequality (==/!=) (level 6)
void equalityExpression() : {}
{
relationalExpression()
(
("==" | "eq") relationalExpression() #Eq(2)
|
("!=" | "neq") relationalExpression() #NotEq(2)
)*
}
// boolean relational expressions (level 5)
void relationalExpression() : {}
{
shiftExpression()
(
("<" | "lt") shiftExpression() #Less(2)
|
(">" | "gt") shiftExpression() #Greater(2)
|
("<=" | "lte") shiftExpression() #LessEq(2)
|
(">=" | "gte") shiftExpression() #GreaterEq(2)
|
"in" shiftExpression() #In(2)
|
"not" "in" shiftExpression() #NotIn(2)
)*
}
// bit shift expressions (level 4)
void shiftExpression() : {}
{
additiveExpression()
(
("<<" | "shl") additiveExpression() #ShiftLeft(2)
|
(">>" | "shr") additiveExpression() #ShiftRight(2)
|
(">>>" | "ushr") additiveExpression() #UnsignedShiftRight(2)
)*
}
// binary addition/subtraction (level 3)
void additiveExpression() : {}
{
multiplicativeExpression()
(
"+" multiplicativeExpression() #Add(2)
|
"-" multiplicativeExpression() #Subtract(2)
)*
}
// multiplication/division/remainder (level 2)
void multiplicativeExpression() : {}
{
unaryExpression()
(
"*" unaryExpression() #Multiply(2)
|
"/" unaryExpression() #Divide(2)
|
"%" unaryExpression() #Remainder(2)
)*
}
// unary (level 1)
void unaryExpression() : {
StringBuffer sb;
Token t;
ASTInstanceof ionode;
}
{
(
"-" unaryExpression() #Negate(1)
|
"+" unaryExpression() // Just leave it there
|
"~" unaryExpression() #BitNegate(1)
|
("!" | "not") unaryExpression() #Not(1)
|
navigationChain()
[
"instanceof"
t = <IDENT> { sb = new StringBuffer(t.image); ionode = jjtThis; } #Instanceof(1)
( "." t = <IDENT> { sb.append('.').append( t.image ); }
)* { ionode.setTargetType( new String(sb) ); }
]
)
}
// navigation chain: property references, method calls, projections, selections, etc.
void navigationChain() : {}
{
primaryExpression()
( "."
( /* Prevent the "eval" ambiguity from issuing a warning; see discussion below. */
( LOOKAHEAD(2) methodCall() | propertyName() )
// Also handle "{", which requires a lookahead of 2.
| ( LOOKAHEAD(2) projection() | selection() )
| "(" expression() ")"
) #Chain(2)
| index() #Chain(2)
| "(" expression() ")" #Eval(2)
/* Using parentheses to indicate evaluation of the current
object makes this language ambiguous, because the
expression "ident(args)" could be seen as a single
method call or as a property name followed by an
evaluation. We always put the method call first and
turn off the ambiguity warning; we always want to
interpret this as a method call. */
)*
}
void primaryExpression() : {
Token t;
String className = null;
}
{
(
(<CHAR_LITERAL> | <BACK_CHAR_LITERAL> | <STRING_LITERAL> | <INT_LITERAL> | <FLT_LITERAL>)
{ jjtThis.setValue( token_source.literalValue ); } #Const(0)
|
"true" { jjtThis.setValue( Boolean.TRUE ); } #Const(0)
|
"false" { jjtThis.setValue( Boolean.FALSE ); } #Const(0)
|
"null" #Const(0) // Null is the default value in an ASTConst
|
LOOKAHEAD(2) "#this" { jjtThis.setName( "this" ); } #ThisVarRef(0)
|
LOOKAHEAD(2) "#root" { jjtThis.setName( "root" ); } #RootVarRef(0)
|
LOOKAHEAD(2) "#" t=<IDENT> { jjtThis.setName( t.image ); } #VarRef(0)
|
LOOKAHEAD(2) ":" "[" expression() "]" { jjtThis.setValue( jjtThis.jjtGetChild(0) ); } #Const(1)
|
staticReference()
|
LOOKAHEAD(2) constructorCall()
|
// Prevent the "eval" ambiguity from issuing a warning; see discussion elsewhere.
( LOOKAHEAD(2) methodCall() | propertyName() )
|
index()
|
"(" expression() ")"
|
"{" [assignmentExpression() ("," assignmentExpression())*] #List "}"
|
LOOKAHEAD(2) ( "#" (className=classReference())? "{" [keyValueExpression() ("," keyValueExpression())*] { jjtThis.setClassName(className); } "}" ) #Map
)
}
void keyValueExpression() : {}
{
( assignmentExpression() (":" assignmentExpression())? ) #KeyValue
}
void staticReference() : {
String className = "java.lang.Math";
Token t;
}
{
className=classReference()
( // Prevent the "eval" ambiguity from issuing a warning; see discussion elsewhere.
LOOKAHEAD(2)
staticMethodCall( className )
|
t=<IDENT> { jjtThis.init( className, t.image ); } #StaticField(0)
)
}
String classReference(): {
String result = "java.lang.Math";
}
{
"@" ( result=className() )? "@" { return result; }
}
String className(): {
Token t;
StringBuffer result;
}
{
t=<IDENT> { result = new StringBuffer( t.image ); }
( "." t=<IDENT> { result.append('.').append( t.image ); }
)* { return new String(result); }
}
void constructorCall() #Ctor : {
String className;
Token t;
StringBuffer sb;
}
{
"new" className=className()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -