Zhiqim Markup Language是知启蒙定义的、类似于JavaJavascript语法的语句和表达式,通常和XML/HTML混编在一起形成的一种新的标记语言。 ZML力求简单易用,目前支持常用的十二种标记语句和五十种表达式,在知启蒙技术体系中被用来代替JSP。
ExpressionParser.java59KB
/*
* 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙,邂逅框架梦]
*
* https://zhiqim.org/project/zhiqim_framework/zhiqim_zml.htm
*
* Zhiqim Zml is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.zhiqim.zml;
import java.util.ArrayList;
import java.util.ListIterator;
import org.zhiqim.kernel.util.Types;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.zml.exception.ExpressionException;
import org.zhiqim.zml.expression.Operator;
import org.zhiqim.zml.expression.Primitive;
import org.zhiqim.zml.expression.operator._Add;
import org.zhiqim.zml.expression.operator._And;
import org.zhiqim.zml.expression.operator._Bracket;
import org.zhiqim.zml.expression.operator._Division;
import org.zhiqim.zml.expression.operator._EqualEqual;
import org.zhiqim.zml.expression.operator._EqualNot;
import org.zhiqim.zml.expression.operator._GreateThen;
import org.zhiqim.zml.expression.operator._GreateThenEqual;
import org.zhiqim.zml.expression.operator._Indexable;
import org.zhiqim.zml.expression.operator._IntegerArray;
import org.zhiqim.zml.expression.operator._LessThen;
import org.zhiqim.zml.expression.operator._LessThenEqual;
import org.zhiqim.zml.expression.operator._Method;
import org.zhiqim.zml.expression.operator._Modulus;
import org.zhiqim.zml.expression.operator._Multiplication;
import org.zhiqim.zml.expression.operator._Negative;
import org.zhiqim.zml.expression.operator._New;
import org.zhiqim.zml.expression.operator._Not;
import org.zhiqim.zml.expression.operator._Or;
import org.zhiqim.zml.expression.operator._Subtraction;
import org.zhiqim.zml.expression.operator._Ternary;
import org.zhiqim.zml.expression.primitive._Boolean;
import org.zhiqim.zml.expression.primitive._Char;
import org.zhiqim.zml.expression.primitive._Class;
import org.zhiqim.zml.expression.primitive._Decimal;
import org.zhiqim.zml.expression.primitive._Integer;
import org.zhiqim.zml.expression.primitive._Null;
import org.zhiqim.zml.expression.primitive._String;
import org.zhiqim.zml.expression.primitive._Variable;
import org.zhiqim.zml.expression.symbol._Ampersand;
import org.zhiqim.zml.expression.symbol._Asterisk;
import org.zhiqim.zml.expression.symbol._CloseBracket;
import org.zhiqim.zml.expression.symbol._CloseParenthesis;
import org.zhiqim.zml.expression.symbol._Colon;
import org.zhiqim.zml.expression.symbol._Comma;
import org.zhiqim.zml.expression.symbol._Dot;
import org.zhiqim.zml.expression.symbol._DotDot;
import org.zhiqim.zml.expression.symbol._Equal;
import org.zhiqim.zml.expression.symbol._Exclamation;
import org.zhiqim.zml.expression.symbol._Gt;
import org.zhiqim.zml.expression.symbol._Gte;
import org.zhiqim.zml.expression.symbol._Inequal;
import org.zhiqim.zml.expression.symbol._Lt;
import org.zhiqim.zml.expression.symbol._Lte;
import org.zhiqim.zml.expression.symbol._Minus;
import org.zhiqim.zml.expression.symbol._OpenBracket;
import org.zhiqim.zml.expression.symbol._OpenParenthesis;
import org.zhiqim.zml.expression.symbol._Percent;
import org.zhiqim.zml.expression.symbol._Plus;
import org.zhiqim.zml.expression.symbol._Question;
import org.zhiqim.zml.expression.symbol._Slash;
import org.zhiqim.zml.expression.symbol._VerticalBar;
/**
* 表达式基类<br><br>
*
* @see Operator 运算符表达式<br>
* @see Primitive 对象原型表达式<br>
* @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
*/
public class ExpressionParser implements ZmlConstants
{
/**
* 完整解析表达式,由字符串解析成最后一个表达式
*
* @param expression 表达式语句
* @return 表达式对象
* @throws ExpressionException 可能产生的异常
*/
public static Expression parseExpression(String expression) throws ExpressionException
{
//第一步,找到_String原型,并去除多余的空格
ArrayList<Object> list = ExpressionParser.parse_String(expression);
//第二步,找到_Char原型
for (ListIterator<Object> it=list.listIterator();it.hasNext();)
{
Object obj = it.next();
if (!(obj instanceof String))
continue;
it.remove();
ArrayList<Object> charList = ExpressionParser.parse_Char((String)obj);
for (Object value : charList)
it.add(value);
}
//第三步,找到_Numberic原型,并检查有没有不支持的字符
for (ListIterator<Object> it=list.listIterator();it.hasNext();)
{
Object obj = it.next();
if (!(obj instanceof String))
continue;
it.remove();
ArrayList<Object> charList = ExpressionParser.parse_Numberic((String)obj);
for (Object value : charList)
it.add(value);
}
//第四步,找到_Variable原型,包括_Null,_Boolean,_Gt,_Gte,_Lt,_Lte
for (ListIterator<Object> it=list.listIterator();it.hasNext();)
{
Object obj = it.next();
if (!(obj instanceof String))
continue;
it.remove();
ArrayList<Object> charList = ExpressionParser.parse_Variable((String)obj);
for (Object value : charList)
it.add(value);
}
//第五步,对符号进行检查,生成子表达式列表
ArrayList<Expression> eList = ExpressionParser.parse_Symbol(list);
//第六步,开始按优先级解析操作符,进行合并,最终表达式
parse_Operator(eList);
//第七步,最后,判断是否有效并得到最终表达式
if (eList.size() > 1)
throw new ExpressionException("存在无法处理的表达式");
Expression _expression = eList.get(0);
eList.clear();eList = null;list.clear();list = null;
return _expression;
}
/**
* 解析操作符表达式,并合并成最终一个表达式
*
* @param eList 解析标点符号之后的表达式列表
* @throws ExpressionException 可能产生的异常
*/
public static void parse_Operator(ArrayList<Expression> eList) throws ExpressionException
{//第六步,开始按优先级解析操作符,进行合并,最终表达式
if (eList.size() <= 1)
return;
//6.1括号,并拆分出括号表达式和方法表达式,和对_Variable中可能是方法名进行替换,得到未设置目标对象的方法表达式
parse_Bracket(eList);
if (eList.size() <= 1)
return;
//6.2方括号,把方括号转为未设置目标对应的可索引表达式
parse_BracketSquare(eList);
if (eList.size() <= 1)
return;
//6.3点号对应的方法和小数、双点号对应的整数数组、方括号对应的可索引表达式
parse_DotIndexable(eList);
//6.4双点号
parse_DotDot(eList);
if (eList.size() <= 1)
return;
//6.5感叹号
parse_Not(eList);
if (eList.size() <= 1)
return;
//6.6取负号
parse_Negative(eList);
if (eList.size() <= 1)
return;
//6.7new
parse_New(eList);
if (eList.size() <= 1)
return;
//6.8乘除模表达式
parse_MuliplicationDivisionModulus(eList);
if (eList.size() <= 1)
return;
//6.9加减表达式
parse_AddSubtraction(eList);
if (eList.size() <= 1)
return;
//6.10大于小于/大等于/小等于表达式
parse_GtGteLtLte(eList);
if (eList.size() <= 1)
return;
//6.11恒等不等表达式
parse_EqualEqualNot(eList);
if (eList.size() <= 1)
return;
//6.12逻辑与表达式
parse_AndOr(eList, CONNECTOR);
if (eList.size() <= 1)
return;
//6.13逻辑或表达式
parse_AndOr(eList, VERTICAL);
if (eList.size() <= 1)
return;
//6.14三目运算
parse_Ternary(eList);
}
/**
* 解析三目运算表达式
*
* @param eList 表达式列表
* @throws ExpressionException 表达式异常
*/
public static void parse_Ternary(ArrayList<Expression> eList) throws ExpressionException
{//从右到左
boolean isDoLoop = false;
for (int i=eList.size()-1;i>=0;i--)
{
Expression expression = eList.get(i);
if (expression.getType() != COLON)
continue;
if (i == eList.size()-1 || i < 2)//?a:b
throw new ExpressionException(COLON+"格式不正确,前面或后面无内容");
Expression colon = eList.get(i-2);
if (colon.getType() != QUESTION)
throw new ExpressionException(COLON+"格式不正确,前面没找到符号(?)");
Expression condition = eList.get(i-3);
Expression first = eList.get(i-1);
Expression second = eList.get(i+1);
Expression _tarnary = new _Ternary(condition, first, second);
eList.remove(i);//当前 :
eList.remove(i);//NEXT b
eList.remove(i-1);//PREV a
eList.remove(i-2);//PREV2 ?
eList.remove(i-3);//PREV3 c
eList.add(i-3, _tarnary);//加入当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_Ternary(eList);
eList.trimToSize();
}
/**
* 解析逻辑与/逻辑或表达式
*
* @param eList 表达式列表
* @param oprType 表达式类型 CONNECTOR | VERTICAL
* @throws ExpressionException 除号格式不正确
*/
public static void parse_AndOr(ArrayList<Expression> eList, int oprType) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
if (expression.getType() != oprType)
continue;
if (i == 0 || i == eList.size()-1)
throw new ExpressionException((oprType==CONNECTOR?"逻辑与&&":"逻辑或||")+"格式不正确,前面或后面无内容");
Expression last = eList.get(i-1);
Expression next = eList.get(i+1);
Expression _te = null;
switch (oprType)
{
case CONNECTOR: _te = new _And(last, next);break;
case VERTICAL: _te = new _Or(last, next);break;
}
eList.remove(i);//当前
eList.remove(i);//NEXT
eList.remove(i-1);//LAST
eList.add(i-1, _te);//加入当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_AndOr(eList, oprType);
eList.trimToSize();
}
/**
* 解析恒等和不等表达式
*
* @param eList 表达式列表
* @throws ExpressionException 除号格式不正确
*/
public static void parse_EqualEqualNot(ArrayList<Expression> eList) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
int type = expression.getType();
if (type != EQUAL && type != INEQUAL)
continue;
if (i == 0 || i == eList.size()-1)
throw new ExpressionException("恒等和不等格式不正确,前面或后面无内容");
Expression last = eList.get(i-1);
Expression next = eList.get(i+1);
Expression _te = null;
switch (type)
{
case EQUAL: _te = new _EqualEqual(last, next);break;
case INEQUAL: _te = new _EqualNot(last, next);break;
}
eList.remove(i);//当前
eList.remove(i);//NEXT
eList.remove(i-1);//LAST
eList.add(i-1, _te);//加入当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_EqualEqualNot(eList);
eList.trimToSize();
}
/**
* 解析大于、大于等于、小于、小于等于表达式
*
* @param eList 表达式列表
* @throws ExpressionException 除号格式不正确
*/
public static void parse_GtGteLtLte(ArrayList<Expression> eList) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
int type = expression.getType();
if (type != GT && type != GTE && type != LT && type != LTE)
continue;
if (i == 0 || i == eList.size()-1)
throw new ExpressionException("大于、大于等于、小于、小于等于格式不正确,前面或后面无内容");
Expression last = eList.get(i-1);
Expression next = eList.get(i+1);
Expression _te = null;
switch (type)
{
case GT: _te = new _GreateThen(last, next);break;
case GTE: _te = new _GreateThenEqual(last, next);break;
case LT: _te = new _LessThen(last, next);break;
case LTE: _te = new _LessThenEqual(last, next);break;
}
eList.remove(i);//当前
eList.remove(i);//NEXT
eList.remove(i-1);//LAST
eList.add(i-1, _te);//加入当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_GtGteLtLte(eList);
eList.trimToSize();
}
/**
* 解析加法或字符串连接表达式
*
* @param eList 表达式列表
* @throws ExpressionException 除号格式不正确
*/
public static void parse_AddSubtraction(ArrayList<Expression> eList) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
if (expression.getType() != PLUS && expression.getType() != MINUS)
continue;
if (i == 0 || i == eList.size()-1)
throw new ExpressionException("加减法格式不正确,前面或后面无内容");
Expression last = eList.get(i-1);
Expression next = eList.get(i+1);
Expression _te = null;
switch (expression.getType())
{
case PLUS: _te = new _Add(last, next);break;
case MINUS: _te = new _Subtraction(last, next);break;
}
eList.remove(i);//当前
eList.remove(i);//NEXT
eList.remove(i-1);//LAST
eList.add(i-1, _te);//加入当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_AddSubtraction(eList);
eList.trimToSize();
}
/**
* 解析乘除法表达式
*
* @param eList 表达式列表
* @throws ExpressionException 感叹号格式不正确
*/
public static void parse_MuliplicationDivisionModulus(ArrayList<Expression> eList) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
int type = expression.getType();
if (type != ASTERISK && type != SLASH && type != PERCENT)
continue;
if (i == 0 || i == eList.size()-1)
throw new ExpressionException("乘除表达式格式不正确,前面或后面无内容");
Expression last = eList.get(i-1);
Expression next = eList.get(i+1);
Expression _te = null;
switch (type)
{
case ASTERISK: _te = new _Multiplication(last, next);break;
case SLASH: _te = new _Division(last, next);break;
case PERCENT: _te = new _Modulus(last, next);break;
}
eList.remove(i);//当前
eList.remove(i);//NEXT
eList.remove(i-1);//LAST
eList.add(i-1, _te);//加入当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_MuliplicationDivisionModulus(eList);
eList.trimToSize();
}
/**
* 解析New,创建对象
*
* @param eList 表达式列表
* @throws ExpressionException 除号格式不正确
*/
public static void parse_New(ArrayList<Expression> eList) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
if (expression.getType() != NEW)
continue;
if (i == eList.size()-1)
throw new ExpressionException("new格式不正确,后面无构造方法");
Expression next = eList.get(i+1);
if (next.getType() != METHOD)
throw new ExpressionException("new格式不正确,后面不是方法");
_Method _method = (_Method)next;
Expression _variable = _method.getObject();
if (_variable != null && !(_variable instanceof _Variable))
throw new ExpressionException("new格式不正确,后面的类名不正确");
String className = (_variable==null)?_method.getMethodName():((_Variable)_variable).getValue() + "." + _method.getMethodName();
_method.setNew(expression, className);
eList.remove(i);//当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_New(eList);
eList.trimToSize();
}
/**
* 解析减号中的取负,取负表达式
*
* @param eList 表达式列表
* @throws ExpressionException 感叹号格式不正确
*/
public static void parse_Negative(ArrayList<Expression> eList) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
if (expression.getType() != MINUS)
continue;
if (i == eList.size()-1)
throw new ExpressionException("减号/取负号格式不正确,后面无内容");
if (i > 0)
{
Expression last = eList.get(i-1);
int type = last.getType();
if (type != CONNECTOR && type != VERTICAL && type != EQUAL && type != INEQUAL)
continue;//取负,前面有内容时仅支持(&&、|| == !=)四种情况,如果不是则认为是减号,不处理,等减号时再处理
}
Expression next = eList.get(i+1);
int type = next.getType();
if (type != NUMBERIC && type != DECIMAL && type != VARIABLE && type != BRACKET && type != METHOD && type != INDEXABLE)
continue;//取负,只支持整数、小数和括号、变量和方法、属性六种,前三种为数值,后三种为对象
_Negative _negative = new _Negative(next);
eList.remove(i);//当前
eList.remove(i);//NEXT
eList.add(i, _negative);//加入当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_Negative(eList);
eList.trimToSize();
}
/**
* 解析感叹号,取反表达式
*
* @param eList 表达式列表
* @throws ExpressionException 感叹号格式不正确
*/
public static void parse_Not(ArrayList<Expression> eList) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
if (expression.getType() != EXCLAMATION)
continue;
if (i == eList.size()-1)
throw new ExpressionException("感叹号格式不正确,后面无内容");
if (i > 0)
{
Expression last = eList.get(i-1);
if (last.getType() != CONNECTOR && last.getType() != VERTICAL)
throw new ExpressionException("感叹号格式不正确,前面有内容时仅支持&&、||两种情况");
}
Expression nextExpression = eList.get(i+1);
_Not _not = new _Not(nextExpression);
eList.remove(i);//当前
eList.remove(i);//NEXT
eList.add(i, _not);//加入当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_Not(eList);
eList.trimToSize();
}
/**
* 解析双点号,整型数组表达式
*
* @param eList 表达式列表
* @throws ExpressionException 除号格式不正确
*/
public static void parse_DotDot(ArrayList<Expression> eList) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
if (expression.getType() != DOTDOT)
continue;
if (i == 0 || i == eList.size()-1)
throw new ExpressionException("双点号格式不正确,前面或后面无内容");
Expression last = eList.get(i-1);
if (last.getType() != NUMBERIC && last.getType() != VARIABLE && last.getType() != METHOD && last.getType() != INDEXABLE && last.getType() != BRACKET)
throw new ExpressionException("双点号格式不正确,前后必须整型或变量、方法、属性");
Expression next = eList.get(i+1);
if (next.getType() != NUMBERIC && next.getType() != VARIABLE && next.getType() != METHOD && next.getType() != INDEXABLE && next.getType() != BRACKET)
throw new ExpressionException("双点号格式不正确,前后必须整型变量、方法、属性");
Expression _te = new _IntegerArray(last, next);
eList.remove(i);//当前
eList.remove(i);//NEXT
eList.remove(i-1);//LAST
eList.add(i-1, _te);//加入当前
isDoLoop = true;
break;
}
if (isDoLoop)
parse_DotDot(eList);
eList.trimToSize();
}
/**
* 解析点号,生成1、小数表达式,2、方法表达式
*
* @param eList 表达式列表
* @throws ExpressionException 点号格式不正确
*/
public static boolean parse_Dot(ArrayList<Expression> eList, int i) throws ExpressionException
{
if (i == 0 || i == eList.size()-1)
throw new ExpressionException("点号格式不正确,前面或后面无内容");
//找到_Dot,有两种情况1、_Numberic,2、_Method
Expression last = eList.get(i-1);
Expression nextExpression = eList.get(i+1);
if (last.getType() == NUMBERIC)
{//前面是整数
if (nextExpression.getType() != NUMBERIC)//要求后面也是整数
throw new ExpressionException("点号格式不正确,不是正确的小数类型");
_Integer lastInteger = (_Integer)last;
_Integer nextInteger = (_Integer)nextExpression;
_Decimal _double = new _Decimal(lastInteger.toString()+"."+nextInteger.toString());
eList.remove(i);//当前
eList.remove(i);//NEXT
eList.remove(i-1);//LAST
eList.add(i-1, _double);//加入当前
}
else if (last.getType() == VARIABLE)
{//前面是变量
if (nextExpression.getType() == METHOD)
{//后面要求是方法,对象或方法并到后面的方法中
_Method _method = (_Method)nextExpression;
_method.setObject(last);
eList.remove(i);//当前
eList.remove(i-1);//LAST
}
else if (nextExpression.getType() == VARIABLE)
{//后面也是变量,则认为是含点号的变量或包名,如rmi.secret或org.zhiqim.kernel.Global,注意属性请使用rmi["secret"]
_Variable _last = (_Variable)last;
_Variable _next = (_Variable)nextExpression;
_next.setValue(_last.getValue()+"."+_next.getValue());
eList.remove(i);//当前
eList.remove(i-1);//LAST
}
else if (nextExpression.getType() == CLASS)
{//后面是类,则认为是包名,如org.zhiqim.kernel.Global.class
_Variable _last = (_Variable)last;
_Class _next = (_Class)nextExpression;
_next.setValue(_last.getValue()+"."+_next.getValue());
eList.remove(i);//当前
eList.remove(i-1);//LAST
}
else
{//其他的不支持
throw new ExpressionException("点号格式不正确,不是正确的方法F.类型");
}
}
else if (last.getType() == METHOD || last.getType() == INDEXABLE)
{//前面是方法或属性
if (nextExpression.getType() == METHOD)
{//后面要求是方法,对象或方法并到后面的方法中
_Method _method = (_Method)nextExpression;
_method.setObject(last);
eList.remove(i);//当前
eList.remove(i-1);//LAST
}
else
{//其他的不支持
throw new ExpressionException("点号格式不正确,不是正确的方法类型");
}
}
else
{//不支持的类型
throw new ExpressionException("点号格式不正确,不是正确的方法类型或小数类型");
}
eList.trimToSize();
return true;
}
/**
* 解析点号对应的小数、方法,方括号对应的属性,以及双点号对应的整数数组
*
* @param eList 表达式列表
* @throws ExpressionException 点号格式不正确
*/
public static void parse_DotIndexable(ArrayList<Expression> eList) throws ExpressionException
{
boolean isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
int type = expression.getType();
if (type != DOT && type != INDEXABLE)
continue;
switch (type)
{
case DOT:isDoLoop = parse_Dot(eList, i);break;
case INDEXABLE:isDoLoop = parse_Indexable(eList, i);break;
}
if (isDoLoop)
break;
}
if (isDoLoop)
parse_DotIndexable(eList);
eList.trimToSize();
}
/**
* 解析方括号对应的可索引变量
*
* @param eList 原型表达式
* @throws ExpressionException 括号未成对出现
*/
public static boolean parse_Indexable(ArrayList<Expression> eList, int i) throws ExpressionException
{
Expression expression = eList.get(i);
_Indexable _indexKey = (_Indexable)expression;
if (_indexKey.hasObject())
return false;//已有索引目标对象不重新循环处理
if (i == 0)
{//前面没有
throw new ExpressionException("解析方括号时,前面没有要求的格式");
}
Expression last = eList.get(i-1);
if (last.getType() != BRACKET && last.getType() != VARIABLE && last.getType() != STRING && last.getType() != METHOD && last.getType() != INDEXABLE)
{//前面不是括号,变量,字符串,整数数组,方法,属性有问题
if (last.getType() == NUMBERIC)
throw new ExpressionException("解析方括号时,如果前面是整数数组如1..3,请使用括号(1..3)");
else
throw new ExpressionException("解析方括号时,前面不是要求的格式");
}
//把上一个作为方括号的目标对象,找到退出再找
_indexKey.setObject(last);
_indexKey.parseBracketSquare();
eList.remove(i-1);//LAST
return true;
}
/**
* 解析左右方括号,成方括号表达式
*
* @param eList 原型表达式
* @throws ExpressionException 括号未成对出现
*/
public static void parse_BracketSquare(ArrayList<Expression> eList) throws ExpressionException
{
int num = 0;_Indexable _bracket = null;
for (ListIterator<Expression> it=eList.listIterator();it.hasNext();)
{
Expression expression = it.next();
if (expression.getType() == BRACKET_SQUARE_LEFT)
{//左方括号
num++;
it.remove();
if (num == 1)
{//开始
_bracket = null;
_bracket = new _Indexable();
it.add(_bracket);
}
_bracket.addExpression(expression);
}
else if (expression.getType() == BRACKET_SQUARE_RIGHT)
{//右方括号
num--;
it.remove();
_bracket.addExpression(expression);
}
else
{//其他表达式
if (num > 0)
{//如果在方括号中,删除该节点,加入到括号中
it.remove();
_bracket.addExpression(expression);
}
}
}
if (num > 0)
throw new ExpressionException("方括号[]未成对出现");
eList.trimToSize();
}
/**
* 解析左右括号,成括号表达式
*
* @param eList 原型表达式
* @throws ExpressionException 括号未成对出现
*/
public static void parse_Bracket(ArrayList<Expression> eList) throws ExpressionException
{
int num = 0;_Bracket _bracket = null;
for (ListIterator<Expression> it=eList.listIterator();it.hasNext();)
{
Expression expression = it.next();
if (expression.getType() == BRACKET_LEFT)
{//左括号
num++;
it.remove();
if (num == 1)
{//开始
_bracket = null;
_bracket = new _Bracket();
it.add(_bracket);
}
_bracket.addExpression(expression);
}
else if (expression.getType() == BRACKET_RIGHT)
{//右括号
num--;
it.remove();
_bracket.addExpression(expression);
}
else
{//其他表达式
if (num > 0)
{//如果在括号中,删除该节点,加入到括号中
it.remove();
_bracket.addExpression(expression);
}
}
}
if (num > 0)
throw new ExpressionException("括号()未成对出现");
//判断是否前面是 _Variable,如果是则该括号是_Method
boolean isDoLoop = true;
while(isDoLoop)
{
isDoLoop = false;
for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
if (expression.getType() != BRACKET)
continue;
if (i == 0)
continue;//前面没有
Expression last = eList.get(i-1);
if (last.getType() != VARIABLE)
continue;//前面不是_Variable
//前面是_Variable,找到一个则退出重新查询
_Variable _variable = (_Variable)last;
_Bracket bracket = (_Bracket)expression;
_Method _method = new _Method(_variable.getValue());
_method.parseBracketParamList(bracket);
eList.remove(i);//当前
eList.remove(i-1);//LAST
eList.add(i-1, _method);//加入当前
//再判断i-2是不是_New,如果是合并为构造函数
if (i >= 2 && eList.get(i-2).getType() == NEW)
{
_method.setObject(eList.get(i-2));
eList.remove(i-1);//当前
eList.remove(i-2);//_New
eList.add(i-2, _method);//加入当前
}
isDoLoop = true;
break;
}
}
for (Expression expression : eList)
{
if (expression.getType() != BRACKET)
continue;
((_Bracket)expression).parseBracket();
}
eList.trimToSize();
}
/**
* 根据操作符整理成由原型表达式组成的表达式
*
* @param list 原型表达式和操作符混合的表达式列表
* @return 全部原型表达式列表
* @throws ExpressionException 不支持的字符格式
*/
public static ArrayList<Expression> parse_Symbol(ArrayList<Object> list) throws ExpressionException
{
ArrayList<Expression> eList = new ArrayList<Expression>();
for (Object obj : list)
{
if (!(obj instanceof String))
{
Expression expression = (Expression)obj;
eList.add(expression);
continue;
}
//检查操作符
String str = ((String)obj).trim();
if (Validates.isEmpty(str))
continue;
//当前支持的操作符
for (int i=0;i<str.length();i++)
{
char c = str.charAt(i);
switch (c)
{
case ' ':break;//空格过滤掉
//13个
case DOT:eList.add(new _Dot());break; //.
case PLUS:eList.add(new _Plus());break; //+
case MINUS:eList.add(new _Minus());break; //-
case ASTERISK:eList.add(new _Asterisk());break; //*
case SLASH:eList.add(new _Slash());break; ///
case PERCENT:eList.add(new _Percent());break; //%
case EXCLAMATION:eList.add(new _Exclamation());break; //!
case BRACKET_LEFT:eList.add(new _OpenParenthesis());break; //(
case BRACKET_RIGHT:eList.add(new _CloseParenthesis());break; //)
case BRACKET_SQUARE_LEFT:eList.add(new _OpenBracket());break; //[
case BRACKET_SQUARE_RIGHT:eList.add(new _CloseBracket());break; //]
case COMMA:eList.add(new _Comma());break; //,
case EQUAL:eList.add(new _Equal());break; //=
case QUESTION:eList.add(new _Question());break; //?
case COLON:eList.add(new _Colon());break; //:
//2个扩展
case CONNECTOR:eList.add(new _Ampersand());break; //&
case VERTICAL:eList.add(new _VerticalBar());break; //|
default:
throw new ExpressionException("遇到不支持的字符串格式:{"+str+"}");
}
}
}
//对双标点和扩展标点进行处理,包括&&,||,..,!=,==共5个
boolean hasDoLoop = true;
while(hasDoLoop)
{
hasDoLoop = false;
lable_for:for (int i=0;i<eList.size();i++)
{
Expression expression = eList.get(i);
if (!(expression instanceof ExpressionPair))
continue;
ExpressionPair pair = (ExpressionPair)expression;
if (pair.isPaired())
continue;
if (i == eList.size() - 1)
throw new ExpressionException("遇到需配对的字符串格式:{"+expression+"},但不支持");
//设置为已配对
pair.setPaired();
Expression next = eList.get(i+1);
int type = expression.getType();
switch (type)
{//共五种情况
case CONNECTOR:
{//&&
if (next.getType() != CONNECTOR)
throw new ExpressionException("遇到需配对的字符串格式:{"+expression+"},但不支持");
eList.remove(i+1);
hasDoLoop = true;
break lable_for;
}
case VERTICAL:
{//||
if (next.getType() != VERTICAL)
throw new ExpressionException("遇到需配对的字符串格式:{"+expression+"},但不支持");
eList.remove(i+1);
hasDoLoop = true;
break lable_for;
}
case EQUAL:
{//==
if (next.getType() != EQUAL)
continue;
eList.remove(i+1);
hasDoLoop = true;
break lable_for;
}
case DOT:
{//..
if (next.getType() != DOT)
continue;
eList.remove(i);//当前的.
eList.remove(i);//NEXT的.
eList.add(i, new _DotDot());
hasDoLoop = true;
break lable_for;
}
case EXCLAMATION:
{//!=
if (next.getType() != EQUAL)
continue;
eList.remove(i);//当前的!
eList.remove(i);//NEXT的=
eList.add(i, new _Inequal());
hasDoLoop = true;
break lable_for;
}
}
}
}
eList.trimToSize();
return eList;
}
/**
* 对表达式中的字符\下划线和数值进行解析
*
* @param expression 原表达式
* @return 返回由_Variable/_Null/_Boolean/_Gt/_Gte/_Lt/_Lte和字符串表组成的列表
* @throws ExpressionException 字符串结束符不匹配
*/
public static ArrayList<Object> parse_Variable(String expression) throws ExpressionException
{
ArrayList<Object> expList = new ArrayList<Object>();char lastChar = 0;
boolean isVariableString = false;StringBuilder strb = new StringBuilder();
for (int i=0;i<expression.length();i++)
{
char c = expression.charAt(i);
if (!isVariableChar(c))
{//不是变量字符
if (isExpressionSeparator(c))
{//如果是分隔符
if (isVariableString)
{
expList.add(buildNameValue(strb.toString()));
strb = null;
strb = new StringBuilder();
strb.append(c);
lastChar = c;
isVariableString = false;
continue;
}
}
//不是分隔符,或者是分隔符但以前不是整数
strb.append(c);
lastChar = c;
continue;
}
//是变量字符
if (isVariableString)
{//还是变量字符
strb.append(c);
lastChar = c;
continue;
}
if (lastChar == 0)
{//第一个字符是变量字符
isVariableString = true;
strb.append(c);
lastChar = c;
continue;
}
if (isExpressionSeparator(lastChar))
{//上一个是分隔符,当前是变量字符,置为变量字符,结束上一次字符串
isVariableString = true;
if (strb.length() > 0)
{
expList.add(strb.toString());
}
strb = null;
strb = new StringBuilder();
}
strb.append(c);
lastChar = c;
}
if (isVariableString)
expList.add(buildNameValue(strb.toString()));
else
expList.add(strb.toString());
strb = null;
expList.trimToSize();
return expList;
}
/**
* 对表达式中的整型进行解析
*
* @param expression 原表达式
* @return 返回由_Integer和字符串表组成的列表
* @throws ExpressionException 字符串结束符不匹配
*/
public static ArrayList<Object> parse_Numberic(String expression) throws ExpressionException
{
ArrayList<Object> expList = new ArrayList<Object>();char lastChar = 0;
boolean isInteger = false;StringBuilder strb = new StringBuilder();
for (int i=0;i<expression.length();i++)
{
char c = expression.charAt(i);
if (!isValidChar(c))
throw new ExpressionException("表达式中有不支持的字符["+c+"]");
if (c < '0' || c > '9')
{//不是数字
if (isExpressionSeparator(c))
{//如果是分隔符
if (isInteger)
{
expList.add(new _Integer(strb.toString()));
strb = null;
strb = new StringBuilder();
strb.append(c);
lastChar = c;
isInteger = false;
continue;
}
}
//不是分隔符,或者是分隔符但以前不是整数
strb.append(c);
lastChar = c;
continue;
}
//是数字
if (isInteger)
{//还是数字
strb.append(c);
lastChar = c;
continue;
}
if (lastChar == 0)
{//第一个字符是变量字符
isInteger = true;
strb.append(c);
lastChar = c;
continue;
}
if (isExpressionSeparator(lastChar))
{//上一个是分隔符,当前是数字,置为数字,结束上一次字符串
isInteger = true;
if (strb.length() > 0)
{
expList.add(strb.toString());
}
strb = null;
strb = new StringBuilder();
}
strb.append(c);
lastChar = c;
}
if (isInteger)
expList.add(new _Integer(strb.toString()));
else if (strb.length() > 0)
expList.add(strb.toString());
strb = null;
expList.trimToSize();
return expList;
}
/**
* 对表达式中的字符进行解析
*
* @param expression 原表达式
* @return 返回由_Char和字符串表组成的列表
* @throws ExpressionException 字符串结束符不匹配
*/
public static ArrayList<Object> parse_Char(String expression) throws ExpressionException
{
ArrayList<Object> expList = new ArrayList<Object>();char lastChar = 0;
boolean isChar = false;StringBuilder strb = new StringBuilder();
for (int i=0;i<expression.length();i++)
{
char c = expression.charAt(i);
if (c == ' ' && (lastChar == 0 || lastChar == ' '))
{
lastChar = c;
continue;
}
if (c != '\'')
{
strb.append(c);
lastChar = c;
continue;
}
if (!isChar)
{
isChar = true;
if (strb.length() > 0)
{
expList.add(strb.toString());
strb = null;
strb = new StringBuilder();
strb.append(c);
}
}
else
{
//在字符中,如果前面是转义符,则认为是字符为需转义的字符
if (lastChar == '\\')
{
strb.append(c);
}
else
{
//字符串内遇到下一个双引号,且前面不是转议符,则认为该字符串结束
strb.append(c);
expList.add(new _Char(strb.toString()));
strb = null;
strb = new StringBuilder();
isChar = false;
}
}
lastChar = c;
}
if (isChar)
throw new ExpressionException("字符结束符不匹配");
if (strb.length() > 0)
{
expList.add(strb.toString());
strb = null;
}
expList.trimToSize();
return expList;
}
/**
* 对表达式中的字符串进行解析
*
* @param expression 原表达式
* @return 返回由_String和字符串表组成的列表
* @throws ExpressionException 字符串结束符不匹配
*/
public static ArrayList<Object> parse_String(String expression) throws ExpressionException
{
ArrayList<Object> expList = new ArrayList<Object>();char lastChar = 0;
boolean isString = false;StringBuilder strb = new StringBuilder();
for (int i=0;i<expression.length();i++)
{
char c = expression.charAt(i);
if (c != '\"')
{
if (isString || c != ' ' || (lastChar != 0 && lastChar != ' '))
{//不在字符串中第一个空格去掉,多个空格只保留一个
strb.append(c);
}
lastChar = c;
continue;
}
//是双引号,前面不是字符串,遇到双引号认为是字符串开始,不管前面是否有转义符
if (!isString)
{
isString = true;
if (strb.length() > 0)
{
expList.add(strb.toString());
}
strb = null;
strb = new StringBuilder();
strb.append(c);//第一个双引号加入
}
else
{
//在字符串中,如果前面是转义符,则认为是字符串中的双引号
if (lastChar == '\\')
{
strb.append(c);
}
else
{
//字符串内遇到下一个双引号,且前面不是转议符,则认为该字符串结束
strb.append(c);
expList.add(new _String(strb.toString()));
strb = null;
strb = new StringBuilder();
isString = false;
}
}
lastChar = c;
}
if (isString)
throw new ExpressionException("字符串结束符不匹配");
if (strb.length() > 0)
{
expList.add(strb.toString());
strb = null;
}
expList.trimToSize();
return expList;
}
/**
* 判断字符是否是表达式分隔符
*
* @param c 要求判断的字符
* @return =true表示是/=false表示否
*/
public static boolean isExpressionSeparator(char c)
{
return (c == ' '//前面是空格的情况,如${ 1 + 3 }, 1 gt 3
|| c == ','//前面是逗号的情况,如${abc.getValue(1,3)}
|| c == '(' || c == ')'//如(1+3)
|| c == '[' || c == ']'//如[1]
|| c == '.'//如1.1
|| c == '!'//如!item.isSuccess()
|| c == '-' || c == '+' || c == '*' || c == '/' || c == '%'//四则运算
|| c == '&' || c == '|'//如 item.isSuccess()&&item.isFailure(), item.isSuccess()||item.isFailure()
|| c == '?' || c == ':'//三目运算
|| c == '='//如 1!=2,3==4
//gt,gte,lt,lte这些两边要求空格
);
}
/**
* 判断是字符是否是变量字符
*
* @param c 要求判断的字符
* @return =true表示是/=false表示否
*/
public static boolean isVariableChar(char c)
{
return (c == '_' || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
}
/**
* 判断字符是表达式支持的字符
*
* @param c 要求判断的字符
* @return =true表示是/=false表示否
*/
public static boolean isValidChar(char c)
{
if (isVariableChar(c))
return true;
if (isExpressionSeparator(c))
return true;
if (c == '\"' || c == '\'')
return true;
return false;
}
/**
* 根据名称的值创建对象的表达式原型
*
* @param value 名称对称的值
* @return 原型表达式对象
*/
private static Expression buildNameValue(String value)
{
if ("true".equals(value) || "false".equals(value))
return new _Boolean(Boolean.parseBoolean(value));
else if ("null".equals(value))
return new _Null();
else if ("gt".equals(value))
return new _Gt();
else if ("gte".equals(value))
return new _Gte();
else if ("lt".equals(value))
return new _Lt();
else if ("lte".equals(value))
return new _Lte();
else if ("class".equals(value))
return new _Class(value);
else if ("new".equals(value))
return new _New();
else
return new _Variable(value);
}
/**
* 去除表达式中多余的空格,有利于分析表达式
*
* @param expression 表达式
* @return 去除空格后的表达式
* @throws ExpressionException
*/
public static String replaceBlank(String expression)
{
StringBuilder strb = new StringBuilder();
boolean isString = false;char lastChar = 0;
for (int i=0;i<expression.length();i++)
{
char c = expression.charAt(i);
if (c != '\"')
{
if (isString || c != ' ' || (lastChar != 0 && lastChar != '\"' && !isExpressionSeparator(c)))
{//不在字符串中第一个空格/上一个是分隔符第一个空格去掉,多个空格只保留一个
strb.append(c);
}
lastChar = c;
continue;
}
//是双引号,前面不是字符串,遇到双引号认为是字符串开始,不判断前面是否有转义符
if (!isString)
{
isString = true;
strb.append(c);
lastChar = c;
continue;
}
else
{
//在字符串中,如果前面不是转义符,则认为是字符串中的双引号,字符串结束
if (lastChar != '\\')
isString = false;
strb.append(c);
}
lastChar = c;
}
return strb.toString();
}
/**
* 大小比较
*
* @param privous 前值
* @param next 后值
* @param expression 表达式
* @return 大小比较结果
* @throws ExpressionException 表达式异常
*/
public static boolean compare(Object privous, Object next, Expression expression) throws ExpressionException
{
String typeDesc = null;
switch (expression.getType())
{
case GTHEN:typeDesc="大于";break;
case GTEQUAL:typeDesc="大于等于";break;
case LTHEN:typeDesc="小于";break;
case LTEQUAL:typeDesc="小于等于";break;
default:throw new ExpressionException("不支持的表达式");
}
if (privous == null || next == null)
{//有一个为null
return false;
}
else if (privous instanceof String || next instanceof String)
{//有一个是字符串则认为是字符串相连
String str1 = String.valueOf(privous);
String str2 = String.valueOf(next);
return str1.compareTo(str2) > 0;
}
else if ((!Types.isNumber(privous) && !Types.isChar(privous))
|| (!Types.isNumber(next) && !Types.isChar(next)))
{//不是整数和小数
throw new ExpressionException(typeDesc+"表达式{"+expression+"},格式不正确,出现值不是数值型和字符串");
}
else
{
if (Types.isInteger(privous))
{//整数
long num1 = ((Number)privous).longValue();
if (Types.isInteger(next))
{
long num2 = ((Number)next).longValue();
switch (expression.getType())
{
case GTHEN:return num1 > num2;
case GTEQUAL:return num1 >= num2;
case LTHEN:return num1 < num2;
case LTEQUAL:return num1 <= num2;
}
}
else if (Types.isDecimal(next))
{
double num2 = ((Number)next).doubleValue();
switch (expression.getType())
{
case GTHEN:return num1 > num2;
case GTEQUAL:return num1 >= num2;
case LTHEN:return num1 < num2;
case LTEQUAL:return num1 <= num2;
}
}
else
{
char num2 = (Character)next;
switch (expression.getType())
{
case GTHEN:return num1 > num2;
case GTEQUAL:return num1 >= num2;
case LTHEN:return num1 < num2;
case LTEQUAL:return num1 <= num2;
}
}
}
else if (Types.isDecimal(privous))
{//小数
double num1 = ((Number)privous).doubleValue();
if (Types.isInteger(next))
{
long num2 = ((Number)next).longValue();
switch (expression.getType())
{
case GTHEN:return num1 > num2;
case GTEQUAL:return num1 >= num2;
case LTHEN:return num1 < num2;
case LTEQUAL:return num1 <= num2;
}
}
else if (Types.isDecimal(next))
{
double num2 = ((Number)next).doubleValue();
switch (expression.getType())
{
case GTHEN:return num1 > num2;
case GTEQUAL:return num1 >= num2;
case LTHEN:return num1 < num2;
case LTEQUAL:return num1 <= num2;
}
}
else
{
char num2 = (Character)next;
switch (expression.getType())
{
case GTHEN:return num1 > num2;
case GTEQUAL:return num1 >= num2;
case LTHEN:return num1 < num2;
case LTEQUAL:return num1 <= num2;
}
}
}
else
{//字符
char num1 = (Character)privous;
if (Types.isInteger(next))
{
long num2 = ((Number)next).longValue();
switch (expression.getType())
{
case GTHEN:return num1 > num2;
case GTEQUAL:return num1 >= num2;
case LTHEN:return num1 < num2;
case LTEQUAL:return num1 <= num2;
}
}
else if (Types.isDecimal(next))
{
double num2 = ((Number)next).doubleValue();
switch (expression.getType())
{
case GTHEN:return num1 > num2;
case GTEQUAL:return num1 >= num2;
case LTHEN:return num1 < num2;
case LTEQUAL:return num1 <= num2;
}
}
else
{
char num2 = (Character)next;
switch (expression.getType())
{
case GTHEN:return num1 > num2;
case GTEQUAL:return num1 >= num2;
case LTHEN:return num1 < num2;
case LTEQUAL:return num1 <= num2;
}
}
}
}
throw new ExpressionException("不支持的表达式");
}
}

