翻译方法调用
解析方法调用的语法,支持常量(双引号包含)、变量、函数(嵌套调用)作为入参。
自动机:
java实现:
// 方法执行 public String excuteMethod(String expression, JSONObject formData) throws Exception { if (null == expression) return ""; while (expression.contains(" ")) expression = expression.replace(" ", ""); Token token = this.excuteMethod(expression, 0, formData); if (null == token) throw new RuntimeException("error expression"); return token.val; } // 方法执行,表达式不要有空格 public Token excuteMethod(String expression, int left, JSONObject formData) throws Exception { String methodName = ""; Stack<Token> paramStack = new Stack<Token>(); STATE state = STATE.START; int len = expression.length(), right = left; while (right < len) { char c = expression.charAt(right); if (c == ')') { if (state == STATE.PARAM) { // TODO 调用方法 String currentRes = this.methodSplit(methodName, paramStack); Token token = new Token(currentRes, left, right); return token; } else throw new RuntimeException(") error at " + right); } if (c == ',') { if (state == STATE.PARAM) { right++; state = STATE.WAIT_PARAM; } else throw new RuntimeException(", error at " + right); continue; } if (c == '(') { if (state == STATE.METHED_START) { right++; state = STATE.WAIT_PARAM; } else if (state == STATE.PARAM) { // 递归调用 Token methodNameToken = paramStack.pop(); Token currentResToken = this.excuteMethod(expression, methodNameToken.getLeft(), formData); if (null == currentResToken) throw new RuntimeException("error at " + right); paramStack.push(currentResToken); right = currentResToken.right + 1; state = STATE.PARAM; } else { System.out.println(state); throw new RuntimeException("( error at " + right); } continue; } Token token = this.getToken(expression, right, formData); right = token.right + 1; if (state == STATE.START) { state = STATE.METHED_START; methodName = token.getVal(); } else if (state == STATE.WAIT_PARAM) { // 常量、变量判断,变量取值 String fieldVal = this.transField(token.getVal(), formData); token.setVal(fieldVal); paramStack.push(token); state = STATE.PARAM; } else throw new RuntimeException("token error at " + right); } return null; } private Token getToken(String expression, int left, JSONObject formData) { int len = expression.length(), right = left; if (right >= len) throw new RuntimeException("right:" + right + " out of len:" + len); StringBuilder builder = new StringBuilder(); while (right < len) { char c = expression.charAt(right); if (c == '(' || c == ')' || c == ',') { // 不是转义符号的话,就是关键字符号,终止取值 if (right <= 0 || expression.charAt(right - 1) != '/') { right--; break; } } builder.append(c); right++; } String val = builder.toString(); return new Token(val, left, right); } public String transField(String val, JSONObject formData) { String reVal = ""; if (val.charAt(0) == '"' && val.charAt(val.length() - 1) == '"') { // 常量 reVal = val.substring(1, val.length() - 1); } else { // 表单数据 String[] array = val.split("\\."); if ("baseInfo".equals(array[0])) reVal = formData.getJSONObject("baseInfo").getString(array[1]); else reVal = formData.getString(array[0]); System.out.println("field " + val + "::" + reVal); } return reVal; } @Data class Token { String val; int left, right; Token(String val, int left, int right) { this.val = val; this.left = left; this.right = right; } } enum STATE { START, METHED_START, WAIT_PARAM, PARAM, METHED_END; }
当你看清人们的真相,于是你知道了,你可以忍受孤独