package cn.cslg.pas.common.utils.parseQueryToTree; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Stack; public class expressManager { HashMap hSymbols = new HashMap(); private static expressManager instance = new expressManager(); private expressManager() { //#region 添加逻辑符号 operate oAnd = new operate(); oAnd.Code = "AND"; oAnd.ShowName = "AND"; oAnd.type = enuType.Logic; oAnd.priorityVale = 11; oAnd.operateValue = 2; hSymbols.put(oAnd.Code, oAnd); operate oOR = new operate(); oOR.Code = "OR"; oOR.ShowName = "OR"; oOR.type = enuType.Logic; oOR.priorityVale = 11; oOR.operateValue = 2; hSymbols.put(oOR.Code, oOR); oOR = new operate(); oOR.Code = "NOT"; oOR.ShowName = "NOT"; oOR.type = enuType.Logic; oOR.priorityVale = 12; oOR.operateValue = 1; hSymbols.put(oOR.Code, oOR); oOR = new operate(); oOR.Code = "TO"; oOR.ShowName = "TO"; oOR.type = enuType.Logic; oOR.priorityVale = 13; oOR.operateValue = 2; hSymbols.put(oOR.Code, oOR); oOR = new operate(); oOR.Code = "~"; oOR.ShowName = "TO"; oOR.type = enuType.Logic; oOR.priorityVale = 13; oOR.operateValue = 2; hSymbols.put(oOR.Code, oOR); oOR = new operate(); oOR.Code = "="; oOR.ShowName = "="; oOR.type = enuType.Assignment; oOR.priorityVale = 20; oOR.operateValue = 2; hSymbols.put(oOR.Code, oOR); oOR = new operate(); oOR.Code = ">"; oOR.ShowName = ">"; oOR.type = enuType.Assignment; oOR.priorityVale = 20; oOR.operateValue = 2; hSymbols.put(oOR.Code, oOR); oOR = new operate(); oOR.Code = "<"; oOR.ShowName = "<"; oOR.type = enuType.Assignment; oOR.priorityVale = 20; oOR.operateValue = 2; hSymbols.put(oOR.Code, oOR); oOR = new operate(); oOR.Code = ">="; oOR.ShowName = ">="; oOR.type = enuType.Assignment; oOR.priorityVale = 20; oOR.operateValue = 2; hSymbols.put(oOR.Code, oOR); oOR = new operate(); oOR.Code = "<="; oOR.ShowName = "<="; oOR.type = enuType.Assignment; oOR.priorityVale = 20; oOR.operateValue = 2; hSymbols.put(oOR.Code, oOR); oOR = new operate(); oOR.Code = "CONTAIN"; oOR.ShowName = " LIKE "; oOR.type = enuType.Assignment; oOR.priorityVale = 20; oOR.operateValue = 2; hSymbols.put(oOR.Code, oOR); //#endregion //#region 添加成对出现的符号 pairSymbol first = new pairSymbol(); first.Code = "("; first.isEndSymbol = false; pairSymbol end = new pairSymbol(); end.Code = ")"; end.previewSymbol = first; end.isEndSymbol = true; hSymbols.put(first.Code, first); hSymbols.put(end.Code, end); pairSymbol first1 = new pairSymbol(); first1.Code = "["; first1.isEndSymbol = false; pairSymbol end1 = new pairSymbol(); end1.Code = "]"; end1.previewSymbol = first1; end1.isEndSymbol = true; hSymbols.put(first1.Code, first1); hSymbols.put(end1.Code, end1); end = new pairSymbol(); end.Code = "\""; end.previewSymbol = end; hSymbols.put(end.Code, end); //#endregion } public static expressManager getInstance() { return instance; } public Symbol getSymbol(String strSymbol) { String strKey = strSymbol.trim().toUpperCase(); if ((strKey != null && !strKey.trim().equals("")) && hSymbols.containsKey(strKey)) { return hSymbols.get(strKey); } else { return null; } } /// /// 解析表达式字符串,返回表达式树 /// /// 表达式字符串 /// 如果输入的是多个条件,之间的关系是and还是or,true为and,false为or /// 表达式树节点 public treeNode Parse(String strExpress, boolean isAnd) throws Exception { ArrayList Tokens = GetTokens(strExpress); Stack symbolStack = new Stack(); Stack valueStack = new Stack(); for (String strTem : Tokens) { Symbol temSymbol = expressManager.getInstance().getSymbol(strTem); if (temSymbol != null) { if (temSymbol instanceof operate) { //#region 如果是操作符,从操作符堆栈中取出优先级大于等于该操作符的结合值堆栈生成节点后压入值堆栈,然后将该操作符压入堆栈 operate temOperate = (operate) temSymbol; if (symbolStack.size() > 0) { Symbol lastSymbol = symbolStack.peek(); while (lastSymbol instanceof operate && ((operate) lastSymbol).priorityVale >= temOperate.priorityVale) { operateNode temSymbolNode = new operateNode(); temSymbolNode.operate = (operate) lastSymbol; if (((operate) lastSymbol).operateValue == 1) { temSymbolNode.Right = valueStack.pop(); } else { temSymbolNode.Right = valueStack.pop(); temSymbolNode.Left = valueStack.pop(); } valueStack.push(temSymbolNode); symbolStack.pop(); if (symbolStack.size() > 0) { lastSymbol = symbolStack.peek(); } else { break; } } } symbolStack.push(temSymbol); //#endregion } else { //#region 括号处理 if (temSymbol instanceof pairSymbol && ((pairSymbol) temSymbol).isEndSymbol) { Symbol lastSymbol = symbolStack.peek(); if (lastSymbol == null) { throw new Exception("无效的括号!"); } while (lastSymbol instanceof operate || (lastSymbol instanceof pairSymbol && ((pairSymbol) lastSymbol).Code != ((pairSymbol) temSymbol).previewSymbol.Code)) { operateNode temSymbolNode = new operateNode(); temSymbolNode.operate = (operate) lastSymbol; if (((operate) lastSymbol).operateValue == 1) { temSymbolNode.Right = valueStack.pop(); } else { temSymbolNode.Right = valueStack.pop(); temSymbolNode.Left = valueStack.pop(); } valueStack.push(temSymbolNode); symbolStack.pop(); lastSymbol = symbolStack.peek(); } if ((lastSymbol instanceof pairSymbol && ((pairSymbol) temSymbol).previewSymbol.Code == ((pairSymbol) lastSymbol).Code)) { symbolStack.pop(); } else { throw new Exception("无效的括号"); } } else { symbolStack.push(temSymbol); } //#endregion } } else { valueNode temNode = new valueNode(); temNode.value = strTem; valueStack.push(temNode); } } while (symbolStack.size() > 0) { Symbol temSymbol = symbolStack.pop(); if (temSymbol instanceof operate) { operateNode temNode = new operateNode(); temNode.operate = (operate) temSymbol; if (((operate) temSymbol).operateValue == 1) { temNode.Right = valueStack.pop(); } else { temNode.Right = valueStack.pop(); temNode.Left = valueStack.pop(); } valueStack.push(temNode); } else { throw new Exception("无效的括号!"); } } if (valueStack.size() == 1) { return valueStack.pop(); } else { if (valueStack.size() > 1) { List lstValues = new ArrayList(); while (valueStack.size() > 0) { treeNode temNode = valueStack.pop(); if (temNode instanceof valueNode) { lstValues.add(temNode); } else { throw new Exception("无效的检索式!"); } } treeNode retNode = null; for (treeNode temNode : lstValues) { if (retNode == null) { retNode = temNode; } else { operateNode sNode = new operateNode(); if (!isAnd) { sNode.operate = (operate) expressManager.getInstance().getSymbol("OR"); } else { sNode.operate = (operate) expressManager.getInstance().getSymbol("AND"); } sNode.Left = retNode; sNode.Right = temNode; retNode = sNode; } } return retNode; } throw new Exception("无效的检索式!"); } } /// /// 语法分析,将表达式字符按照空格分开, /// 且将双引号或者是括号从字符串中拿出来 /// /// /// public ArrayList GetTokens(String strExpress) { if (strExpress != null) { ArrayList Tokens = new ArrayList(); //#region String strTem = strExpress.trim(); String strTemToken = ""; Boolean isFindingEndYinHao = false; int step = -1; for (int i = 0; i < strTem.length(); i++) { char c = strTem.charAt(i); switch (c) { case '"': if (!isFindingEndYinHao) { isFindingEndYinHao = true; step = i; } else { if ((i < strTem.length() - 1 && strTem.charAt(i + 1) == ' ') || (i < strTem.length() - 1 && strTem.charAt(i + 1) == ')') || (i < strTem.length() - 1 && strTem.charAt(i + 1) == ']') || i == strTem.length() - 1) { strTemToken = strTem.substring(step + 1, i); Tokens.add(strTemToken); step = i; isFindingEndYinHao = false; } } break; case ' ': if (!isFindingEndYinHao) { if (step == (i - 1)) { step = i; } else { strTemToken = strTem.substring(step + 1, i); Tokens.add(strTemToken); step = i; } } break; case '(': case '[': if (i == 0 || strTem.charAt(i - 1) == ' ' || (Tokens.size() > 0 && Tokens.get(Tokens.size() - 1) == String.valueOf(c)) || strTem.charAt(i - 1) == '=') { Tokens.add(String.valueOf(c)); step = i; } break; case ')': case ']': if ((i < strTem.length() - 1 && (strTem.charAt(i + 1) == ' ' || strTem.charAt(i + 1) == c)) || i == strTem.length() - 1) { Boolean isAdd = false; for (int index = Tokens.size() - 1; index >= 0; index--) { if ((c == ')' && Tokens.get(index).equals("(")) || (c == ']' && Tokens.get(index).equals("["))) { isAdd = true; break; } } if (isAdd) { strTemToken = strTem.substring(step + 1, i); if (strTemToken != null && !strTemToken.equals("")) { Tokens.add(strTemToken); } Tokens.add(String.valueOf(c)); step = i; } } break; case '=': case '~': case '>': case '>': case '<': case '<': strTemToken = strTem.substring(step + 1, i); if (strTemToken != null && strTemToken != "") { Tokens.add(strTemToken); } if (strTem.charAt(i + 1) == '=') { Tokens.add(String.valueOf(c) + "="); step = i + 1; i++; } else { Tokens.add(String.valueOf(c)); step = i; } break; } } if (step < strTem.length() - 1) { Tokens.add(strTem.substring(step + 1)); } //#endregion return Tokens; } else { return null; } } }