com.alibaba.simpleEL.dialect.tiny.parser.TinyELExprParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of SimpleEL Show documentation
Show all versions of SimpleEL Show documentation
simple expression language implementation
The newest version!
package com.alibaba.simpleEL.dialect.tiny.parser;
import java.math.BigInteger;
import java.util.Collection;
import com.alibaba.simpleEL.ELException;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELArrayAccessExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELBinaryOpExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELBinaryOperator;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELBooleanExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELConditionalExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELIdentifierExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELMethodInvokeExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELNewExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELNullExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELNumberLiteralExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELPropertyExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELStringExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyELVariantRefExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyUnaryOpExpr;
import com.alibaba.simpleEL.dialect.tiny.ast.TinyUnaryOperator;
public class TinyELExprParser {
protected final TinyELLexer lexer;
public TinyELExprParser(TinyELLexer lexer){
super();
this.lexer = lexer;
}
public TinyELExprParser(String input){
this(new TinyELLexer(input));
this.lexer.nextToken();
}
public TinyELLexer getLexer() {
return lexer;
}
public void accept(TinyELToken token) {
if (lexer.token() == token) {
lexer.nextToken();
} else {
throw new ELException("syntax error, expect " + token + ", actual " + lexer.token());
}
}
public TinyELExpr expr() {
TinyELExpr expr = primary();
if (lexer.token() == TinyELToken.COMMA) {
return expr;
}
return exprRest(expr);
}
public TinyELExpr exprRest(TinyELExpr expr) {
expr = multiplicativeRest(expr);
expr = additiveRest(expr);
expr = shiftRest(expr);
expr = relationalRest(expr);
expr = equalityRest(expr);
expr = bitAndRest(expr);
expr = bitXorRest(expr);
expr = bitOrRest(expr);
expr = andRest(expr);
expr = orRest(expr);
expr = conditionalRest(expr);
expr = assignRest(expr);
return expr;
}
// ^
public final TinyELExpr bitXor() {
TinyELExpr expr = bitAnd();
return bitXorRest(expr);
}
// ^
public TinyELExpr bitXorRest(TinyELExpr expr) {
if (lexer.token() == TinyELToken.CARET) {
lexer.nextToken();
TinyELExpr rightExp = bitAnd();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.BitwiseXor, rightExp);
expr = bitXorRest(expr);
}
return expr;
}
public final TinyELExpr multiplicative() {
TinyELExpr expr = primary();
return multiplicativeRest(expr);
}
public TinyELExpr multiplicativeRest(TinyELExpr expr) {
if (lexer.token() == TinyELToken.STAR) {
lexer.nextToken();
TinyELExpr rightExp = primary();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.Multiply, rightExp);
expr = multiplicativeRest(expr);
} else if (lexer.token() == TinyELToken.SLASH) {
lexer.nextToken();
TinyELExpr rightExp = primary();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.Divide, rightExp);
expr = multiplicativeRest(expr);
} else if (lexer.token() == TinyELToken.PERCENT) {
lexer.nextToken();
TinyELExpr rightExp = primary();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.Modulus, rightExp);
expr = multiplicativeRest(expr);
}
return expr;
}
// &
public final TinyELExpr bitAnd() {
TinyELExpr expr = equality();
return orRest(expr);
}
public final TinyELExpr bitAndRest(TinyELExpr expr) {
while (lexer.token() == TinyELToken.AMP) {
lexer.nextToken();
TinyELExpr rightExp = equality();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.BitwiseAnd, rightExp);
}
return expr;
}
// |
public final TinyELExpr bitOr() {
TinyELExpr expr = bitXor();
return orRest(expr);
}
// |
public final TinyELExpr bitOrRest(TinyELExpr expr) {
while (lexer.token() == TinyELToken.BAR) {
lexer.nextToken();
TinyELExpr rightExp = bitXor();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.BitwiseOr, rightExp);
}
return expr;
}
public final TinyELExpr equality() {
TinyELExpr expr = relational();
return equalityRest(expr);
}
public final TinyELExpr equalityRest(TinyELExpr expr) {
TinyELExpr rightExp;
if (lexer.token() == TinyELToken.EQEQ) {
lexer.nextToken();
rightExp = relational();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.Equality, rightExp);
} else if (lexer.token() == TinyELToken.BANGEQ) {
lexer.nextToken();
rightExp = relational();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.NotEqual, rightExp);
}
return expr;
}
public final TinyELExpr additive() {
TinyELExpr expr = multiplicative();
return additiveRest(expr);
}
// + -
public TinyELExpr additiveRest(TinyELExpr expr) {
if (lexer.token() == TinyELToken.PLUS) {
lexer.nextToken();
TinyELExpr rightExp = multiplicative();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.Add, rightExp);
expr = additiveRest(expr);
} else if (lexer.token() == TinyELToken.SUB) {
lexer.nextToken();
TinyELExpr rightExp = multiplicative();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.Subtract, rightExp);
expr = additiveRest(expr);
}
return expr;
}
public final TinyELExpr shift() {
TinyELExpr expr = additive();
return shiftRest(expr);
}
public TinyELExpr shiftRest(TinyELExpr expr) {
if (lexer.token() == TinyELToken.LTLT) {
lexer.nextToken();
TinyELExpr rightExp = additive();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.LeftShift, rightExp);
expr = shiftRest(expr);
} else if (lexer.token() == TinyELToken.GTGT) {
lexer.nextToken();
TinyELExpr rightExp = additive();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.RightShift, rightExp);
expr = shiftRest(expr);
}
return expr;
}
public final TinyELExpr and() {
TinyELExpr expr = bitOr();
return andRest(expr);
}
// &&
public final TinyELExpr andRest(TinyELExpr expr) {
if (lexer.token() == TinyELToken.AMPAMP) {
lexer.nextToken();
TinyELExpr rightExp = bitOr();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.BooleanAnd, rightExp);
expr = andRest(expr);
}
return expr;
}
public final TinyELExpr or() {
TinyELExpr expr = and();
return orRest(expr);
}
// ||
public final TinyELExpr orRest(TinyELExpr expr) {
if (lexer.token() == TinyELToken.BARBAR) {
lexer.nextToken();
TinyELExpr rightExp = and();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.BooleanOr, rightExp);
expr = orRest(expr);
}
return expr;
}
public final TinyELExpr conditional() {
TinyELExpr expr = or();
return conditionalRest(expr);
}
// ?:
public final TinyELExpr conditionalRest(TinyELExpr expr) {
if (lexer.token() == TinyELToken.QUES) {
lexer.nextToken();
TinyELExpr trueExpr = expr();
accept(TinyELToken.COLON);
TinyELExpr falseExpr = expr();
expr = new TinyELConditionalExpr(expr, trueExpr, falseExpr);
expr = conditionalRest(expr);
}
return expr;
}
public final TinyELExpr assign() {
TinyELExpr expr = conditional();
return assignRest(expr);
}
// = += -= *= /= %= &= |= ^= ~= <<= >>= >>>=
public final TinyELExpr assignRest(TinyELExpr expr) {
if (lexer.token() == TinyELToken.EQ) {
lexer.nextToken();
TinyELExpr rightExp = conditional();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.Assignment, rightExp);
expr = assignRest(expr);
}
if (lexer.token() == TinyELToken.PLUSEQ) {
lexer.nextToken();
TinyELExpr rightExp = conditional();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.AddAndAssignment, rightExp);
expr = assignRest(expr);
}
return expr;
}
public final TinyELExpr relational() {
TinyELExpr expr = shift();
return relationalRest(expr);
}
public TinyELExpr relationalRest(TinyELExpr expr) {
TinyELExpr rightExp;
if (lexer.token() == TinyELToken.LT) {
lexer.nextToken();
rightExp = shift();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.LessThan, rightExp);
} else if (lexer.token() == TinyELToken.LTEQ) {
lexer.nextToken();
rightExp = shift();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.LessThanOrEqual, rightExp);
} else if (lexer.token() == TinyELToken.GT) {
lexer.nextToken();
rightExp = shift();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.GreaterThan, rightExp);
} else if (lexer.token() == TinyELToken.GTEQ) {
lexer.nextToken();
rightExp = shift();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.GreaterThanOrEqual, rightExp);
} else if (lexer.token() == TinyELToken.INSTNACEOF) {
lexer.nextToken();
rightExp = shift();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.InstanceOf, rightExp);
}
return expr;
}
public final TinyELExpr name() throws ELException {
if (lexer.token() != TinyELToken.IDENTIFIER) {
throw new ELException("error : " + lexer.token());
}
String identName = lexer.stringVal();
lexer.nextToken();
TinyELExpr name = new TinyELIdentifierExpr(identName);
while (lexer.token() == TinyELToken.DOT) {
lexer.nextToken();
if (lexer.token() != TinyELToken.IDENTIFIER) {
throw new ELException("error : " + lexer.token());
}
name = new TinyELPropertyExpr(name, lexer.stringVal());
lexer.nextToken();
}
return name;
}
public String type() {
final TinyELToken tok = lexer.token();
switch (tok) {
case BYTE:
case SHORT:
case INT:
case LONG:
case FLOAT:
case DOUBLE:
lexer.nextToken();
return tok.name;
default:
return name().toString();
}
}
public TinyELExpr primary() {
TinyELExpr primaryExpr = null;
final TinyELToken tok = lexer.token();
switch (tok) {
case LPAREN:
lexer.nextToken();
primaryExpr = expr();
accept(TinyELToken.RPAREN);
break;
case IDENTIFIER:
primaryExpr = new TinyELIdentifierExpr(lexer.stringVal());
lexer.nextToken();
break;
case PLUSPLUS:
lexer.nextToken();
primaryExpr = expr();
primaryExpr = new TinyUnaryOpExpr(primaryExpr, TinyUnaryOperator.PreIncrement);
break;
case SUBSUB:
lexer.nextToken();
primaryExpr = expr();
primaryExpr = new TinyUnaryOpExpr(primaryExpr, TinyUnaryOperator.PreDecrement);
break;
case BANG:
lexer.nextToken();
primaryExpr = primary();
primaryExpr = new TinyUnaryOpExpr(primaryExpr, TinyUnaryOperator.Not);
break;
case NEW:
lexer.nextToken();
TinyELExpr name = name();
String typeName = name.toString();
if (lexer.token() == TinyELToken.LPAREN) {
lexer.nextToken();
TinyELNewExpr newExpr = new TinyELNewExpr(typeName);
if (lexer.token() != TinyELToken.RPAREN) {
exprList(newExpr.getParameters());
}
accept(TinyELToken.RPAREN);
return primaryRest(newExpr);
}
throw new ELException("TODO " + lexer.token());
case TRUE:
primaryExpr = new TinyELBooleanExpr(true);
lexer.nextToken();
break;
case FALSE:
primaryExpr = new TinyELBooleanExpr(false);
lexer.nextToken();
break;
case LITERAL_INT:
primaryExpr = new TinyELNumberLiteralExpr(lexer.integerValue());
lexer.nextToken();
break;
case LITERAL_FLOAT:
primaryExpr = new TinyELNumberLiteralExpr(lexer.decimalValue());
lexer.nextToken();
break;
case LITERAL_STRING:
primaryExpr = new TinyELStringExpr(lexer.stringVal());
lexer.nextToken();
break;
case SUB:
lexer.nextToken();
switch (lexer.token()) {
case LITERAL_INT:
Number integerValue = lexer.integerValue();
if (integerValue instanceof Integer) {
int intVal = ((Integer) integerValue).intValue();
if (intVal == Integer.MIN_VALUE) {
integerValue = Long.valueOf(((long) intVal) * -1);
} else {
integerValue = Integer.valueOf(intVal * -1);
}
} else if (integerValue instanceof Long) {
long longVal = ((Long) integerValue).longValue();
if (longVal == 2147483648L) {
integerValue = Integer.valueOf((int) (((long) longVal) * -1));
} else {
integerValue = Long.valueOf(longVal * -1);
}
} else {
integerValue = ((BigInteger) integerValue).negate();
}
primaryExpr = new TinyELNumberLiteralExpr(integerValue);
lexer.nextToken();
break;
case LITERAL_FLOAT:
primaryExpr = new TinyELNumberLiteralExpr(lexer.decimalValue().negate());
lexer.nextToken();
break;
default:
primaryExpr = expr();
primaryExpr = new TinyUnaryOpExpr(primaryExpr, TinyUnaryOperator.Minus);
break;
}
break;
case PLUS:
lexer.nextToken();
switch (lexer.token()) {
case LITERAL_INT:
primaryExpr = new TinyELNumberLiteralExpr(lexer.integerValue());
lexer.nextToken();
break;
case LITERAL_FLOAT:
primaryExpr = new TinyELNumberLiteralExpr(lexer.decimalValue());
lexer.nextToken();
break;
default:
primaryExpr = expr();
primaryExpr = new TinyUnaryOpExpr(primaryExpr, TinyUnaryOperator.Plus);
break;
}
break;
case QUES:
lexer.nextToken();
primaryExpr = new TinyELVariantRefExpr("?");
break;
case NULL:
primaryExpr = new TinyELNullExpr();
lexer.nextToken();
break;
case VARIANT:
String varName = lexer.stringVal();
primaryExpr = new TinyELVariantRefExpr(varName);
lexer.nextToken();
break;
default:
throw new ELException("ERROR. token : " + tok);
}
return primaryRest(primaryExpr);
}
public TinyELExpr primaryRest(TinyELExpr expr) throws ELException {
if (expr == null) {
throw new IllegalArgumentException("expr");
}
if (lexer.token() == TinyELToken.DOT) {
lexer.nextToken();
if (lexer.token() == TinyELToken.STAR) {
lexer.nextToken();
expr = new TinyELPropertyExpr(expr, "*");
} else {
if (lexer.token() != TinyELToken.IDENTIFIER) {
throw new ELException("error");
}
String name = lexer.stringVal();
lexer.nextToken();
if (lexer.token() == TinyELToken.LPAREN) {
lexer.nextToken();
TinyELMethodInvokeExpr methodInvokeExpr = new TinyELMethodInvokeExpr(name, expr);
if (lexer.token() == TinyELToken.RPAREN) {
lexer.nextToken();
} else {
exprList(methodInvokeExpr.getParameters());
accept(TinyELToken.RPAREN);
}
expr = methodInvokeExpr;
} else {
expr = new TinyELPropertyExpr(expr, name);
}
}
expr = primaryRest(expr);
} else if (lexer.token() == TinyELToken.PLUSPLUS) {
lexer.nextToken();
expr = new TinyUnaryOpExpr(expr, TinyUnaryOperator.PostIncrement);
expr = primaryRest(expr);
} else if (lexer.token() == TinyELToken.SUBSUB) {
lexer.nextToken();
expr = new TinyUnaryOpExpr(expr, TinyUnaryOperator.PostDecrement);
expr = primaryRest(expr);
} else if (lexer.token() == TinyELToken.LBRACKET) {
lexer.nextToken();
TinyELExpr indexExpr = expr();
accept(TinyELToken.RBRACKET);
expr = new TinyELArrayAccessExpr(expr, indexExpr);
expr = primaryRest(expr);
} else if (lexer.token() == TinyELToken.COLONEQ) {
lexer.nextToken();
TinyELExpr rightExp = primary();
expr = new TinyELBinaryOpExpr(expr, TinyELBinaryOperator.Assignment, rightExp);
} else {
if (lexer.token() == TinyELToken.LPAREN) {
if (expr instanceof TinyELIdentifierExpr) {
TinyELIdentifierExpr identExpr = (TinyELIdentifierExpr) expr;
String method_name = identExpr.getName();
lexer.nextToken();
TinyELMethodInvokeExpr methodInvokeExpr = new TinyELMethodInvokeExpr(method_name);
if (lexer.token() != TinyELToken.RPAREN) {
exprList(methodInvokeExpr.getParameters());
}
accept(TinyELToken.RPAREN);
return primaryRest(methodInvokeExpr);
}
throw new ELException("not support token:");
}
}
return expr;
}
public final void exprList(Collection exprCol) throws ELException {
if (lexer.token() == TinyELToken.RPAREN) {
return;
}
if (lexer.token() == TinyELToken.EOF) {
return;
}
TinyELExpr expr = expr();
exprCol.add(expr);
while (lexer.token() == TinyELToken.COMMA) {
lexer.nextToken();
expr = expr();
exprCol.add(expr);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy