|
@@ -0,0 +1,231 @@
|
|
|
+package com.ims.eval.expression;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+import com.ims.eval.util.MathCalculatorUtil;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+public class Analyzer {
|
|
|
+
|
|
|
+ public static final String FUNCODE = "Function";
|
|
|
+
|
|
|
+ //自定义函数名集合
|
|
|
+ public static final HashSet<String> CUSTOM_FUNS = new HashSet<String>() {{
|
|
|
+ add("max");
|
|
|
+ add("min");
|
|
|
+ add("abs");
|
|
|
+ add("acos");
|
|
|
+ add("asin");
|
|
|
+ add("atan");
|
|
|
+ add("ceil");
|
|
|
+ add("cos");
|
|
|
+ add("exp");
|
|
|
+ add("floor");
|
|
|
+ add("log");
|
|
|
+ add("pow");
|
|
|
+ add("round");
|
|
|
+ add("sin");
|
|
|
+ add("sqrt");
|
|
|
+ add("tan");
|
|
|
+ }};
|
|
|
+
|
|
|
+ public static AlarmExpression getAlarmExpression(String exp) {
|
|
|
+ ArrayList<Token> tokens = getTokens(exp);
|
|
|
+ return createAlarmExpression(tokens);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static ArrayList<Token> getTokens(String exp) {
|
|
|
+ ArrayList<Token> tokens = new ArrayList<>();
|
|
|
+ int expIndex = 0;
|
|
|
+ int tokenIndex = 0;
|
|
|
+ while (expIndex < exp.length()) {
|
|
|
+ char currentChar = exp.charAt(expIndex);
|
|
|
+ //如果当前字符是一个分隔符,则认为这是一个分隔符标记
|
|
|
+ //给当前标记和标记类型赋值,并将指针后移
|
|
|
+ if (isDelim(currentChar)) {
|
|
|
+ Token token = new Token();
|
|
|
+ token.setValue(currentChar + "");
|
|
|
+ if (currentChar == '(') {
|
|
|
+ token.setTokenType(TokenType.PARENTHESISL);
|
|
|
+ //识别出函数名
|
|
|
+ if (tokens.size() > 0) {
|
|
|
+ Token preToken = tokens.get(tokens.size() - 1);
|
|
|
+ if (preToken.getTokenType() == TokenType.VARIABE &&
|
|
|
+ CUSTOM_FUNS.contains(preToken.getValue())) {
|
|
|
+ preToken.setTokenType(TokenType.CUSTOMFUN);
|
|
|
+ } else {
|
|
|
+ preToken.setTokenType(TokenType.SYSFUN);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (currentChar == ')')
|
|
|
+ token.setTokenType(TokenType.PARENTHESISR);
|
|
|
+ else
|
|
|
+ token.setTokenType(TokenType.OTHER);
|
|
|
+
|
|
|
+ if (currentChar != ' ')
|
|
|
+ tokens.add(token);
|
|
|
+ tokenIndex = 0;
|
|
|
+ } else if (isVariable(currentChar)) {
|
|
|
+ if (tokenIndex == 0) {
|
|
|
+ Token token = new Token();
|
|
|
+ token.setValue(currentChar + "");
|
|
|
+ if (currentChar >= '0' && currentChar <= '9')
|
|
|
+ token.setTokenType(TokenType.CONST);
|
|
|
+ else
|
|
|
+ token.setTokenType(TokenType.VARIABE);
|
|
|
+ tokens.add(token);
|
|
|
+ } else {
|
|
|
+ Token token = tokens.get(tokens.size() - 1);
|
|
|
+ token.setValue(token.getValue() + currentChar);
|
|
|
+ }
|
|
|
+ tokenIndex++;
|
|
|
+ } else {
|
|
|
+ //其他字符,忽略
|
|
|
+ }
|
|
|
+ expIndex++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return tokens;
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断一个字符是否为分隔符
|
|
|
+ public static boolean isDelim(char c) {
|
|
|
+ if (("+-*/><=&|! ,()".indexOf(c) != -1))
|
|
|
+ return true;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断一个字符是否为字母数字或小数点
|
|
|
+ public static boolean isVariable(char c) {
|
|
|
+ if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '.' || c == '_')
|
|
|
+ return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static AlarmExpression createAlarmExpression(ArrayList<Token> tokens) {
|
|
|
+ AlarmExpression alarmExpression = new AlarmExpression();
|
|
|
+ alarmExpression.setFunCode("ROOT");
|
|
|
+
|
|
|
+ List<AlarmExpression> subFun = new ArrayList<>();
|
|
|
+ int funCnt = 0;
|
|
|
+ List<String> varList = new ArrayList<>();
|
|
|
+ StringBuilder sbExp = new StringBuilder();
|
|
|
+
|
|
|
+ int tokenIndex = 0;
|
|
|
+ while (tokenIndex < tokens.size()) {
|
|
|
+ Token token = tokens.get(tokenIndex);
|
|
|
+ if (token.getTokenType() == TokenType.VARIABE) {
|
|
|
+ if (varList.contains(token.getValue()) == false)
|
|
|
+ varList.add(token.getValue());
|
|
|
+ sbExp.append(token.getValue());
|
|
|
+ } else if (token.getTokenType() == TokenType.CUSTOMFUN) {
|
|
|
+ ArrayList<Token> subTokens = getFunTokens(tokens, tokenIndex);
|
|
|
+ AlarmExpression subExp = createCustomFunExpression(subTokens);
|
|
|
+ String subFunCode = FUNCODE + funCnt++;
|
|
|
+ subExp.setFunCode(subFunCode);
|
|
|
+ subExp.setParent(alarmExpression);
|
|
|
+ subFun.add(subExp);
|
|
|
+ varList.add(subFunCode);
|
|
|
+ sbExp.append(subFunCode);
|
|
|
+
|
|
|
+ tokenIndex += subTokens.size();
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ sbExp.append(token.getValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ tokenIndex++;
|
|
|
+ }
|
|
|
+
|
|
|
+ alarmExpression.setVarList(varList);
|
|
|
+ alarmExpression.setExpression(sbExp.toString());
|
|
|
+ alarmExpression.setChildren(subFun);
|
|
|
+
|
|
|
+ return alarmExpression;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static AlarmExpression createCustomFunExpression(ArrayList<Token> tokens) {
|
|
|
+ AlarmExpression alarmExpression = new AlarmExpression();
|
|
|
+
|
|
|
+ List<AlarmExpression> subExps = new ArrayList<>();
|
|
|
+ int funCnt = 0;
|
|
|
+ List<String> varList = new ArrayList<>();
|
|
|
+ List<String> paramList = new ArrayList<>();
|
|
|
+ StringBuilder sbExp = new StringBuilder();
|
|
|
+ alarmExpression.setFunType(tokens.get(0).getValue());
|
|
|
+ sbExp.append(tokens.get(0).getValue());
|
|
|
+
|
|
|
+ int tokenIndex = 1;
|
|
|
+ while (tokenIndex < tokens.size()) {
|
|
|
+ Token token = tokens.get(tokenIndex);
|
|
|
+ if (token.getTokenType() == TokenType.VARIABE) {
|
|
|
+ if (varList.contains(token.getValue()) == false)
|
|
|
+ varList.add(token.getValue());
|
|
|
+ sbExp.append(token.getValue());
|
|
|
+ } else if (token.getTokenType() == TokenType.CUSTOMFUN) {
|
|
|
+ ArrayList<Token> subTokens = getFunTokens(tokens, tokenIndex);
|
|
|
+ AlarmExpression subExp = createCustomFunExpression(subTokens);
|
|
|
+ subExp.setParent(alarmExpression);
|
|
|
+ String subFunCode = FUNCODE + funCnt++;
|
|
|
+ subExp.setFunCode(subFunCode);
|
|
|
+ subExps.add(subExp);
|
|
|
+ varList.add(subFunCode);
|
|
|
+ sbExp.append(subFunCode);
|
|
|
+ tokenIndex += subTokens.size();
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ sbExp.append(token.getValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ tokenIndex++;
|
|
|
+ }
|
|
|
+
|
|
|
+ alarmExpression.setVarList(varList);
|
|
|
+ alarmExpression.setExpression(sbExp.toString());
|
|
|
+ alarmExpression.setChildren(subExps);
|
|
|
+
|
|
|
+ return alarmExpression;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static ArrayList<Token> getFunTokens(ArrayList<Token> tokens, int startIndex) {
|
|
|
+ ArrayList<Token> result = new ArrayList<>();
|
|
|
+ int cntL = 0;
|
|
|
+ int cntR = 0;
|
|
|
+ while (startIndex < tokens.size()) {
|
|
|
+ Token token = tokens.get(startIndex);
|
|
|
+ result.add(token);
|
|
|
+ if (token.getTokenType() == TokenType.PARENTHESISL) {
|
|
|
+ cntL++;
|
|
|
+ } else if (token.getTokenType() == TokenType.PARENTHESISR) {
|
|
|
+ if (++cntR == cntL) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ startIndex++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+/* public static void main(String[] args) {
|
|
|
+ String exp = "max(1,3)>0 && min(2,4)<0";
|
|
|
+
|
|
|
+
|
|
|
+ ArrayList<Token> tokens = getTokens(exp);
|
|
|
+ for (Token token : tokens) {
|
|
|
+ System.out.println(token.getValue() + "----" + token.getTokenType());
|
|
|
+ }
|
|
|
+
|
|
|
+ AlarmExpression alarmExpression = createAlarmExpression(tokens);
|
|
|
+ List<AlarmExpression> children = alarmExpression.getChildren();
|
|
|
+ for (AlarmExpression alarmExpression1 : children){
|
|
|
+ String calculator = MathCalculatorUtil.calculator(alarmExpression1.getExpression());
|
|
|
+ alarmExpression.setExpression(alarmExpression.getExpression().replaceAll(alarmExpression1.getFunCode(), calculator));
|
|
|
+ }
|
|
|
+ System.out.println(alarmExpression.getFunType());
|
|
|
+
|
|
|
+ }*/
|
|
|
+}
|