init
This commit is contained in:
587
java/org/apache/el/parser/ELParser.jjt
Normal file
587
java/org/apache/el/parser/ELParser.jjt
Normal file
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Author: Jacob Hookom
|
||||
Email: jacob at hookom.net
|
||||
*/
|
||||
|
||||
/* == Option Declaration == */
|
||||
options
|
||||
{
|
||||
STATIC=false;
|
||||
NODE_PREFIX="Ast";
|
||||
VISITOR_EXCEPTION="javax.el.ELException";
|
||||
VISITOR=false;
|
||||
MULTI=true;
|
||||
NODE_DEFAULT_VOID=true;
|
||||
JAVA_UNICODE_ESCAPE=false;
|
||||
UNICODE_INPUT=true;
|
||||
BUILD_NODE_FILES=true;
|
||||
}
|
||||
|
||||
/* == Parser Declaration == */
|
||||
PARSER_BEGIN( ELParser )
|
||||
package org.apache.el.parser;
|
||||
import java.io.StringReader;
|
||||
import javax.el.ELException;
|
||||
public class ELParser {
|
||||
|
||||
public static Node parse(String ref) throws ELException {
|
||||
try {
|
||||
return new ELParser(new StringReader(ref)).CompositeExpression();
|
||||
} catch (ParseException pe) {
|
||||
throw new ELException(pe.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
PARSER_END( ELParser )
|
||||
|
||||
/*
|
||||
* CompositeExpression
|
||||
* Allow most flexible parsing, restrict by examining
|
||||
* type of returned node
|
||||
*/
|
||||
AstCompositeExpression CompositeExpression() #CompositeExpression : {}
|
||||
{
|
||||
(DeferredExpression() |
|
||||
DynamicExpression() |
|
||||
LiteralExpression())* <EOF> { return jjtThis; }
|
||||
}
|
||||
|
||||
/*
|
||||
* LiteralExpression
|
||||
* Non-EL Expression blocks
|
||||
*/
|
||||
void LiteralExpression() #LiteralExpression : { Token t = null; }
|
||||
{
|
||||
t=<LITERAL_EXPRESSION> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* DeferredExpression
|
||||
* #{...} Expressions
|
||||
*/
|
||||
void DeferredExpression() #DeferredExpression : {}
|
||||
{
|
||||
<START_DEFERRED_EXPRESSION> Expression() <RBRACE>
|
||||
}
|
||||
|
||||
/*
|
||||
* DynamicExpression
|
||||
* ${...} Expressions
|
||||
*/
|
||||
void DynamicExpression() #DynamicExpression : {}
|
||||
{
|
||||
<START_DYNAMIC_EXPRESSION> Expression() <RBRACE>
|
||||
}
|
||||
|
||||
/*
|
||||
* Expression
|
||||
* EL Expression Language Root
|
||||
*/
|
||||
void Expression() : {}
|
||||
{
|
||||
Semicolon()
|
||||
}
|
||||
|
||||
/*
|
||||
* Semicolon
|
||||
*/
|
||||
void Semicolon() : {}
|
||||
{
|
||||
Assignment() ( <SEMICOLON> Assignment() #Semicolon(2) )*
|
||||
}
|
||||
|
||||
/*
|
||||
* Assignment
|
||||
*/
|
||||
void Assignment() : {}
|
||||
{
|
||||
LOOKAHEAD(4) LambdaExpression() |
|
||||
Choice() ( LOOKAHEAD(2) <ASSIGN> Assignment() #Assign(2) )*
|
||||
}
|
||||
|
||||
/*
|
||||
* Lambda expression
|
||||
*/
|
||||
void LambdaExpression() #LambdaExpression : {}
|
||||
{
|
||||
LambdaParameters() <ARROW> ( LOOKAHEAD(3) LambdaExpression() | Choice() )
|
||||
}
|
||||
|
||||
/*
|
||||
* Lambda parameters
|
||||
*/
|
||||
void LambdaParameters() #LambdaParameters : {}
|
||||
{
|
||||
Identifier() | <LPAREN> ( Identifier() ( <COMMA> Identifier() )* )? <RPAREN>
|
||||
}
|
||||
|
||||
/*
|
||||
* Possible invocation of lambda expression. Invocations must be bracketed but
|
||||
* being bracketed does not mean it is an invocation.
|
||||
*/
|
||||
void LambdaExpressionOrInvocation() #LambdaExpression : {}
|
||||
{
|
||||
<LPAREN>
|
||||
LambdaParameters()
|
||||
<ARROW>
|
||||
( LOOKAHEAD(3) LambdaExpression() | Choice() )
|
||||
<RPAREN>
|
||||
( MethodParameters() )*
|
||||
}
|
||||
|
||||
/*
|
||||
* Choice
|
||||
* For Choice markup a ? b : c, then Or
|
||||
*/
|
||||
void Choice() : {}
|
||||
{
|
||||
Or() (LOOKAHEAD(3) <QUESTIONMARK> Choice() <COLON> Choice() #Choice(3))*
|
||||
}
|
||||
|
||||
/*
|
||||
* Or
|
||||
* For 'or' '||', then And
|
||||
*/
|
||||
void Or() : {}
|
||||
{
|
||||
And() ((<OR0>|<OR1>) And() #Or(2))*
|
||||
}
|
||||
|
||||
/*
|
||||
* And
|
||||
* For 'and' '&&', then Equality
|
||||
*/
|
||||
void And() : {}
|
||||
{
|
||||
Equality() ((<AND0>|<AND1>) Equality() #And(2))*
|
||||
}
|
||||
|
||||
/*
|
||||
* Equality
|
||||
* For '==' 'eq' '!=' 'ne', then Compare
|
||||
*/
|
||||
void Equality() : {}
|
||||
{
|
||||
Compare()
|
||||
(
|
||||
((<EQ0>|<EQ1>) Compare() #Equal(2))
|
||||
|
|
||||
((<NE0>|<NE1>) Compare() #NotEqual(2))
|
||||
)*
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare
|
||||
* For a bunch of them, then +=
|
||||
*/
|
||||
void Compare() : {}
|
||||
{
|
||||
Concatenation()
|
||||
(
|
||||
((<LT0>|<LT1>) Concatenation() #LessThan(2))
|
||||
|
|
||||
((<GT0>|<GT1>) Concatenation() #GreaterThan(2))
|
||||
|
|
||||
((<LE0>|<LE1>) Concatenation() #LessThanEqual(2))
|
||||
|
|
||||
((<GE0>|<GE1>) Concatenation() #GreaterThanEqual(2))
|
||||
)*
|
||||
}
|
||||
|
||||
/*
|
||||
* Concatenation
|
||||
* For +=, then Math
|
||||
*
|
||||
*/
|
||||
void Concatenation() : {}
|
||||
{
|
||||
Math()
|
||||
(
|
||||
<CONCAT> Math() #Concatenation(2)
|
||||
)*
|
||||
}
|
||||
|
||||
/*
|
||||
* Math
|
||||
* For '+' '-', then Multiplication
|
||||
*/
|
||||
void Math() : {}
|
||||
{
|
||||
Multiplication()
|
||||
(
|
||||
(<PLUS> Multiplication() #Plus(2))
|
||||
|
|
||||
(<MINUS> Multiplication() #Minus(2))
|
||||
)*
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication
|
||||
* For a bunch of them, then Unary
|
||||
*/
|
||||
void Multiplication() : {}
|
||||
{
|
||||
Unary()
|
||||
(
|
||||
(<MULT> Unary() #Mult(2))
|
||||
|
|
||||
((<DIV0>|<DIV1>) Unary() #Div(2))
|
||||
|
|
||||
((<MOD0>|<MOD1>) Unary() #Mod(2))
|
||||
)*
|
||||
}
|
||||
|
||||
/*
|
||||
* Unary
|
||||
* For '-' '!' 'not' 'empty', then Value
|
||||
*/
|
||||
void Unary() : {}
|
||||
{
|
||||
<MINUS> Unary() #Negative
|
||||
|
|
||||
(<NOT0>|<NOT1>) Unary() #Not
|
||||
|
|
||||
<EMPTY> Unary() #Empty
|
||||
|
|
||||
Value()
|
||||
}
|
||||
|
||||
/*
|
||||
* Value
|
||||
* Defines Prefix plus zero or more Suffixes
|
||||
*/
|
||||
void Value() : {}
|
||||
{
|
||||
(ValuePrefix() (ValueSuffix())*) #Value(>1)
|
||||
}
|
||||
|
||||
/*
|
||||
* ValuePrefix
|
||||
* For Literals, Variables, and Functions
|
||||
*/
|
||||
void ValuePrefix() : {}
|
||||
{
|
||||
Literal()
|
||||
| NonLiteral()
|
||||
}
|
||||
|
||||
/*
|
||||
* ValueSuffix
|
||||
* Either dot or bracket notation
|
||||
*/
|
||||
void ValueSuffix() : {}
|
||||
{
|
||||
( DotSuffix() | BracketSuffix() ) ( MethodParameters())?
|
||||
}
|
||||
|
||||
/*
|
||||
* DotSuffix
|
||||
* Dot Property
|
||||
*/
|
||||
void DotSuffix() #DotSuffix : { Token t = null; }
|
||||
{
|
||||
<DOT> t=<IDENTIFIER> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* BracketSuffix
|
||||
* Sub Expression Suffix
|
||||
*/
|
||||
void BracketSuffix() #BracketSuffix : {}
|
||||
{
|
||||
<LBRACK> Expression() <RBRACK>
|
||||
}
|
||||
|
||||
/*
|
||||
* MethodParameters
|
||||
*/
|
||||
void MethodParameters() #MethodParameters : {}
|
||||
{
|
||||
<LPAREN> ( Expression() ( <COMMA> Expression())* )? <RPAREN>
|
||||
}
|
||||
|
||||
/*
|
||||
* NonLiteral
|
||||
* For Grouped Operations, Identifiers, and Functions
|
||||
*/
|
||||
void NonLiteral() : {}
|
||||
{
|
||||
LOOKAHEAD(5) LambdaExpressionOrInvocation()
|
||||
| <LPAREN> Expression() <RPAREN>
|
||||
| LOOKAHEAD((<IDENTIFIER> <COLON>)? <IDENTIFIER> <LPAREN>) Function()
|
||||
| Identifier()
|
||||
| LOOKAHEAD(3)SetData()
|
||||
| ListData()
|
||||
| MapData()
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that both an empty Set and an empty Map are represented by {}. The
|
||||
* parser will always parse {} as an empty Set and special handling is required
|
||||
* to convert it to an empty Map when appropriate.
|
||||
*/
|
||||
void SetData() #SetData: {}
|
||||
{
|
||||
<START_SET_OR_MAP>
|
||||
( Expression() ( <COMMA> Expression() )* )?
|
||||
<RBRACE>
|
||||
}
|
||||
|
||||
void ListData() #ListData: {}
|
||||
{
|
||||
<LBRACK>
|
||||
( Expression() ( <COMMA> Expression() )* )?
|
||||
<RBRACK>
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that both an empty Set and an empty Map are represented by {}. The
|
||||
* parser will always parse {} as an empty Set and special handling is required
|
||||
* to convert it to an empty Map when appropriate.
|
||||
*/
|
||||
void MapData() #MapData: {}
|
||||
{
|
||||
<START_SET_OR_MAP>
|
||||
( MapEntry() ( <COMMA> MapEntry() )* )?
|
||||
<RBRACE>
|
||||
}
|
||||
|
||||
void MapEntry() #MapEntry: {}
|
||||
{
|
||||
Expression() <COLON> Expression()
|
||||
}
|
||||
|
||||
/*
|
||||
* Identifier
|
||||
* Java Language Identifier
|
||||
*/
|
||||
void Identifier() #Identifier : { Token t = null; }
|
||||
{
|
||||
t=<IDENTIFIER> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* Function
|
||||
* Namespace:Name(a,b,c)
|
||||
*/
|
||||
void Function() #Function :
|
||||
{
|
||||
Token t0 = null;
|
||||
Token t1 = null;
|
||||
}
|
||||
{
|
||||
t0=<IDENTIFIER> ( <COLON> t1=<IDENTIFIER> )?
|
||||
{
|
||||
if (t1 != null) {
|
||||
jjtThis.setPrefix(t0.image);
|
||||
jjtThis.setLocalName(t1.image);
|
||||
} else {
|
||||
jjtThis.setLocalName(t0.image);
|
||||
}
|
||||
}
|
||||
( MethodParameters() )+
|
||||
}
|
||||
|
||||
/*
|
||||
* Literal
|
||||
* Reserved Keywords
|
||||
*/
|
||||
void Literal() : {}
|
||||
{
|
||||
Boolean()
|
||||
| FloatingPoint()
|
||||
| Integer()
|
||||
| String()
|
||||
| Null()
|
||||
}
|
||||
|
||||
/*
|
||||
* Boolean
|
||||
* For 'true' 'false'
|
||||
*/
|
||||
void Boolean() : {}
|
||||
{
|
||||
<TRUE> #True
|
||||
| <FALSE> #False
|
||||
}
|
||||
|
||||
/*
|
||||
* FloatingPoint
|
||||
* For Decimal and Floating Point Literals
|
||||
*/
|
||||
void FloatingPoint() #FloatingPoint : { Token t = null; }
|
||||
{
|
||||
t=<FLOATING_POINT_LITERAL> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* Integer
|
||||
* For Simple Numeric Literals
|
||||
*/
|
||||
void Integer() #Integer : { Token t = null; }
|
||||
{
|
||||
t=<INTEGER_LITERAL> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* String
|
||||
* For Quoted Literals
|
||||
*/
|
||||
void String() #String : { Token t = null; }
|
||||
{
|
||||
t=<STRING_LITERAL> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* Null
|
||||
* For 'null'
|
||||
*/
|
||||
void Null() #Null : {}
|
||||
{
|
||||
<NULL>
|
||||
}
|
||||
|
||||
|
||||
/* ========================================================================== */
|
||||
TOKEN_MGR_DECLS:
|
||||
{
|
||||
java.util.Deque<Integer> deque = new java.util.ArrayDeque<Integer>();
|
||||
}
|
||||
<DEFAULT> TOKEN :
|
||||
{
|
||||
/*
|
||||
* The following definition uses + rather than * in two places to prevent
|
||||
* LITERAL_EXPRESSION matching the empty string that could result in the
|
||||
* Parser entering an infinite loop.
|
||||
*/
|
||||
< LITERAL_EXPRESSION:
|
||||
( (~["$", "#", "\\"])* "\\" (["$", "#"])?
|
||||
| (~["$", "#"])* (["$", "#"] ~["{", "$", "#", "\\"])
|
||||
| (~["$", "#"])+
|
||||
)+
|
||||
| "$"
|
||||
| "#"
|
||||
>
|
||||
|
|
||||
< START_DYNAMIC_EXPRESSION: "${" > {deque.push(DEFAULT);}: IN_EXPRESSION
|
||||
|
|
||||
< START_DEFERRED_EXPRESSION: "#{" > {deque.push(DEFAULT);}: IN_EXPRESSION
|
||||
}
|
||||
|
||||
<IN_EXPRESSION, IN_SET_OR_MAP> SKIP : { " " | "\t" | "\n" | "\r" }
|
||||
|
||||
<IN_EXPRESSION, IN_SET_OR_MAP> TOKEN :
|
||||
{
|
||||
< START_SET_OR_MAP : "{" > {deque.push(curLexState);}: IN_SET_OR_MAP
|
||||
| < RBRACE: "}" > {SwitchTo(deque.pop());}
|
||||
| < INTEGER_LITERAL: ["0"-"9"] (["0"-"9"])* >
|
||||
| < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)?
|
||||
| "." (["0"-"9"])+ (<EXPONENT>)?
|
||||
| (["0"-"9"])+ <EXPONENT>
|
||||
>
|
||||
| < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
|
||||
| < STRING_LITERAL: ("\"" ((~["\"","\\"])
|
||||
| ("\\" ( ["\\","\"","\'"] )))* "\"")
|
||||
| ("\'" ((~["\'","\\"])
|
||||
| ("\\" ( ["\\","\"","\'"] )))* "\'")
|
||||
>
|
||||
| < TRUE : "true" >
|
||||
| < FALSE : "false" >
|
||||
| < NULL : "null" >
|
||||
| < DOT : "." >
|
||||
| < LPAREN : "(" >
|
||||
| < RPAREN : ")" >
|
||||
| < LBRACK : "[" >
|
||||
| < RBRACK : "]" >
|
||||
| < COLON : ":" >
|
||||
| < SEMICOLON : ";" >
|
||||
| < COMMA : "," >
|
||||
| < GT0 : ">" >
|
||||
| < GT1 : "gt" >
|
||||
| < LT0 : "<" >
|
||||
| < LT1 : "lt" >
|
||||
| < GE0 : ">=" >
|
||||
| < GE1 : "ge" >
|
||||
| < LE0 : "<=" >
|
||||
| < LE1 : "le" >
|
||||
| < EQ0 : "==" >
|
||||
| < EQ1 : "eq" >
|
||||
| < NE0 : "!=" >
|
||||
| < NE1 : "ne" >
|
||||
| < NOT0 : "!" >
|
||||
| < NOT1 : "not" >
|
||||
| < AND0 : "&&" >
|
||||
| < AND1 : "and" >
|
||||
| < OR0 : "||" >
|
||||
| < OR1 : "or" >
|
||||
| < EMPTY : "empty" >
|
||||
| < INSTANCEOF : "instanceof" >
|
||||
| < MULT : "*" >
|
||||
| < PLUS : "+" >
|
||||
| < MINUS : "-" >
|
||||
| < QUESTIONMARK : "?" >
|
||||
| < DIV0 : "/" >
|
||||
| < DIV1 : "div" >
|
||||
| < MOD0 : "%" >
|
||||
| < MOD1 : "mod" >
|
||||
| < CONCAT : "+=" >
|
||||
| < ASSIGN : "=" >
|
||||
| < ARROW : "->" >
|
||||
| < IDENTIFIER : (<LETTER>|<IMPL_OBJ_START>) (<LETTER>|<DIGIT>)* >
|
||||
| < FUNCTIONSUFFIX : (<IDENTIFIER>) >
|
||||
| < #IMPL_OBJ_START: "#" >
|
||||
| < #LETTER:
|
||||
[
|
||||
"\u0024",
|
||||
"\u0041"-"\u005a",
|
||||
"\u005f",
|
||||
"\u0061"-"\u007a",
|
||||
"\u00c0"-"\u00d6",
|
||||
"\u00d8"-"\u00f6",
|
||||
"\u00f8"-"\u00ff",
|
||||
"\u0100"-"\u1fff",
|
||||
"\u3040"-"\u318f",
|
||||
"\u3300"-"\u337f",
|
||||
"\u3400"-"\u3d2d",
|
||||
"\u4e00"-"\u9fff",
|
||||
"\uf900"-"\ufaff"
|
||||
]
|
||||
>
|
||||
| < #DIGIT:
|
||||
[
|
||||
"\u0030"-"\u0039",
|
||||
"\u0660"-"\u0669",
|
||||
"\u06f0"-"\u06f9",
|
||||
"\u0966"-"\u096f",
|
||||
"\u09e6"-"\u09ef",
|
||||
"\u0a66"-"\u0a6f",
|
||||
"\u0ae6"-"\u0aef",
|
||||
"\u0b66"-"\u0b6f",
|
||||
"\u0be7"-"\u0bef",
|
||||
"\u0c66"-"\u0c6f",
|
||||
"\u0ce6"-"\u0cef",
|
||||
"\u0d66"-"\u0d6f",
|
||||
"\u0e50"-"\u0e59",
|
||||
"\u0ed0"-"\u0ed9",
|
||||
"\u1040"-"\u1049"
|
||||
]
|
||||
>
|
||||
| < ILLEGAL_CHARACTER: (~[]) >
|
||||
}
|
||||
Reference in New Issue
Block a user