expressManager.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. package cn.cslg.pas.common.utils.parseQueryToTree;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Stack;
  6. public class expressManager {
  7. HashMap<String, Symbol> hSymbols = new HashMap<String, Symbol>();
  8. private static expressManager instance = new expressManager();
  9. private expressManager() {
  10. //#region 添加逻辑符号
  11. operate oAnd = new operate();
  12. oAnd.Code = "AND";
  13. oAnd.ShowName = "AND";
  14. oAnd.type = enuType.Logic;
  15. oAnd.priorityVale = 11;
  16. oAnd.operateValue = 2;
  17. hSymbols.put(oAnd.Code, oAnd);
  18. operate oOR = new operate();
  19. oOR.Code = "OR";
  20. oOR.ShowName = "OR";
  21. oOR.type = enuType.Logic;
  22. oOR.priorityVale = 11;
  23. oOR.operateValue = 2;
  24. hSymbols.put(oOR.Code, oOR);
  25. oOR = new operate();
  26. oOR.Code = "NOT";
  27. oOR.ShowName = "NOT";
  28. oOR.type = enuType.Logic;
  29. oOR.priorityVale = 12;
  30. oOR.operateValue = 1;
  31. hSymbols.put(oOR.Code, oOR);
  32. oOR = new operate();
  33. oOR.Code = "TO";
  34. oOR.ShowName = "TO";
  35. oOR.type = enuType.Logic;
  36. oOR.priorityVale = 13;
  37. oOR.operateValue = 2;
  38. hSymbols.put(oOR.Code, oOR);
  39. oOR = new operate();
  40. oOR.Code = "~";
  41. oOR.ShowName = "TO";
  42. oOR.type = enuType.Logic;
  43. oOR.priorityVale = 13;
  44. oOR.operateValue = 2;
  45. hSymbols.put(oOR.Code, oOR);
  46. oOR = new operate();
  47. oOR.Code = "=";
  48. oOR.ShowName = "=";
  49. oOR.type = enuType.Assignment;
  50. oOR.priorityVale = 20;
  51. oOR.operateValue = 2;
  52. hSymbols.put(oOR.Code, oOR);
  53. oOR = new operate();
  54. oOR.Code = ">";
  55. oOR.ShowName = ">";
  56. oOR.type = enuType.Assignment;
  57. oOR.priorityVale = 20;
  58. oOR.operateValue = 2;
  59. hSymbols.put(oOR.Code, oOR);
  60. oOR = new operate();
  61. oOR.Code = "<";
  62. oOR.ShowName = "<";
  63. oOR.type = enuType.Assignment;
  64. oOR.priorityVale = 20;
  65. oOR.operateValue = 2;
  66. hSymbols.put(oOR.Code, oOR);
  67. oOR = new operate();
  68. oOR.Code = ">=";
  69. oOR.ShowName = ">=";
  70. oOR.type = enuType.Assignment;
  71. oOR.priorityVale = 20;
  72. oOR.operateValue = 2;
  73. hSymbols.put(oOR.Code, oOR);
  74. oOR = new operate();
  75. oOR.Code = "<=";
  76. oOR.ShowName = "<=";
  77. oOR.type = enuType.Assignment;
  78. oOR.priorityVale = 20;
  79. oOR.operateValue = 2;
  80. hSymbols.put(oOR.Code, oOR);
  81. oOR = new operate();
  82. oOR.Code = "CONTAIN";
  83. oOR.ShowName = " LIKE ";
  84. oOR.type = enuType.Assignment;
  85. oOR.priorityVale = 20;
  86. oOR.operateValue = 2;
  87. hSymbols.put(oOR.Code, oOR);
  88. //#endregion
  89. //#region 添加成对出现的符号
  90. pairSymbol first = new pairSymbol();
  91. first.Code = "(";
  92. first.isEndSymbol = false;
  93. pairSymbol end = new pairSymbol();
  94. end.Code = ")";
  95. end.previewSymbol = first;
  96. end.isEndSymbol = true;
  97. hSymbols.put(first.Code, first);
  98. hSymbols.put(end.Code, end);
  99. pairSymbol first1 = new pairSymbol();
  100. first1.Code = "[";
  101. first1.isEndSymbol = false;
  102. pairSymbol end1 = new pairSymbol();
  103. end1.Code = "]";
  104. end1.previewSymbol = first1;
  105. end1.isEndSymbol = true;
  106. hSymbols.put(first1.Code, first1);
  107. hSymbols.put(end1.Code, end1);
  108. end = new pairSymbol();
  109. end.Code = "\"";
  110. end.previewSymbol = end;
  111. hSymbols.put(end.Code, end);
  112. //#endregion
  113. }
  114. public static expressManager getInstance() {
  115. return instance;
  116. }
  117. public Symbol getSymbol(String strSymbol) {
  118. String strKey = strSymbol.trim().toUpperCase();
  119. if ((strKey != null && !strKey.trim().equals("")) && hSymbols.containsKey(strKey)) {
  120. return hSymbols.get(strKey);
  121. } else {
  122. return null;
  123. }
  124. }
  125. /// <summary>
  126. /// 解析表达式字符串,返回表达式树
  127. /// </summary>
  128. /// <param name="strExpress">表达式字符串</param>
  129. /// <param name="isAnd">如果输入的是多个条件,之间的关系是and还是or,true为and,false为or</param>
  130. /// <returns>表达式树节点</returns>
  131. public treeNode Parse(String strExpress, boolean isAnd) throws Exception {
  132. ArrayList<String> Tokens = GetTokens(strExpress);
  133. Stack<Symbol> symbolStack = new Stack<Symbol>();
  134. Stack<treeNode> valueStack = new Stack<treeNode>();
  135. for (String strTem : Tokens) {
  136. Symbol temSymbol = expressManager.getInstance().getSymbol(strTem);
  137. if (temSymbol != null) {
  138. if (temSymbol instanceof operate) {
  139. //#region 如果是操作符,从操作符堆栈中取出优先级大于等于该操作符的结合值堆栈生成节点后压入值堆栈,然后将该操作符压入堆栈
  140. operate temOperate = (operate) temSymbol;
  141. if (symbolStack.size() > 0) {
  142. Symbol lastSymbol = symbolStack.peek();
  143. while (lastSymbol instanceof operate && ((operate) lastSymbol).priorityVale >= temOperate.priorityVale) {
  144. operateNode temSymbolNode = new operateNode();
  145. temSymbolNode.operate = (operate) lastSymbol;
  146. if (((operate) lastSymbol).operateValue == 1) {
  147. temSymbolNode.Right = valueStack.pop();
  148. } else {
  149. temSymbolNode.Right = valueStack.pop();
  150. temSymbolNode.Left = valueStack.pop();
  151. }
  152. valueStack.push(temSymbolNode);
  153. symbolStack.pop();
  154. if (symbolStack.size() > 0) {
  155. lastSymbol = symbolStack.peek();
  156. } else {
  157. break;
  158. }
  159. }
  160. }
  161. symbolStack.push(temSymbol);
  162. //#endregion
  163. } else {
  164. //#region 括号处理
  165. if (temSymbol instanceof pairSymbol && ((pairSymbol) temSymbol).isEndSymbol) {
  166. Symbol lastSymbol = symbolStack.peek();
  167. if (lastSymbol == null) {
  168. throw new Exception("无效的括号!");
  169. }
  170. while (lastSymbol instanceof operate ||
  171. (lastSymbol instanceof pairSymbol && ((pairSymbol) lastSymbol).Code != ((pairSymbol) temSymbol).previewSymbol.Code)) {
  172. operateNode temSymbolNode = new operateNode();
  173. temSymbolNode.operate = (operate) lastSymbol;
  174. if (((operate) lastSymbol).operateValue == 1) {
  175. temSymbolNode.Right = valueStack.pop();
  176. } else {
  177. temSymbolNode.Right = valueStack.pop();
  178. temSymbolNode.Left = valueStack.pop();
  179. }
  180. valueStack.push(temSymbolNode);
  181. symbolStack.pop();
  182. lastSymbol = symbolStack.peek();
  183. }
  184. if ((lastSymbol instanceof pairSymbol && ((pairSymbol) temSymbol).previewSymbol.Code == ((pairSymbol) lastSymbol).Code)) {
  185. symbolStack.pop();
  186. } else {
  187. throw new Exception("无效的括号");
  188. }
  189. } else {
  190. symbolStack.push(temSymbol);
  191. }
  192. //#endregion
  193. }
  194. } else {
  195. valueNode temNode = new valueNode();
  196. temNode.value = strTem;
  197. valueStack.push(temNode);
  198. }
  199. }
  200. while (symbolStack.size() > 0) {
  201. Symbol temSymbol = symbolStack.pop();
  202. if (temSymbol instanceof operate) {
  203. operateNode temNode = new operateNode();
  204. temNode.operate = (operate) temSymbol;
  205. if (((operate) temSymbol).operateValue == 1) {
  206. temNode.Right = valueStack.pop();
  207. } else {
  208. temNode.Right = valueStack.pop();
  209. temNode.Left = valueStack.pop();
  210. }
  211. valueStack.push(temNode);
  212. } else {
  213. throw new Exception("无效的括号!");
  214. }
  215. }
  216. if (valueStack.size() == 1) {
  217. return valueStack.pop();
  218. } else {
  219. if (valueStack.size() > 1) {
  220. List<treeNode> lstValues = new ArrayList<treeNode>();
  221. while (valueStack.size() > 0) {
  222. treeNode temNode = valueStack.pop();
  223. if (temNode instanceof valueNode) {
  224. lstValues.add(temNode);
  225. } else {
  226. throw new Exception("无效的检索式!");
  227. }
  228. }
  229. treeNode retNode = null;
  230. for (treeNode temNode : lstValues) {
  231. if (retNode == null) {
  232. retNode = temNode;
  233. } else {
  234. operateNode sNode = new operateNode();
  235. if (!isAnd) {
  236. sNode.operate = (operate) expressManager.getInstance().getSymbol("OR");
  237. } else {
  238. sNode.operate = (operate) expressManager.getInstance().getSymbol("AND");
  239. }
  240. sNode.Left = retNode;
  241. sNode.Right = temNode;
  242. retNode = sNode;
  243. }
  244. }
  245. return retNode;
  246. }
  247. throw new Exception("无效的检索式!");
  248. }
  249. }
  250. /// <summary>
  251. /// 语法分析,将表达式字符按照空格分开,
  252. /// 且将双引号或者是括号从字符串中拿出来
  253. /// </summary>
  254. /// <param name="strExpress"></param>
  255. /// <returns></returns>
  256. public ArrayList<String> GetTokens(String strExpress) {
  257. if (strExpress != null) {
  258. ArrayList<String> Tokens = new ArrayList<String>();
  259. //#region
  260. String strTem = strExpress.trim();
  261. String strTemToken = "";
  262. Boolean isFindingEndYinHao = false;
  263. int step = -1;
  264. for (int i = 0; i < strTem.length(); i++) {
  265. char c = strTem.charAt(i);
  266. switch (c) {
  267. case '"':
  268. if (!isFindingEndYinHao) {
  269. isFindingEndYinHao = true;
  270. step = i;
  271. } else {
  272. if ((i < strTem.length() - 1 && strTem.charAt(i + 1) == ' ')
  273. || (i < strTem.length() - 1 && strTem.charAt(i + 1) == ')')
  274. || (i < strTem.length() - 1 && strTem.charAt(i + 1) == ']')
  275. || i == strTem.length() - 1) {
  276. strTemToken = strTem.substring(step + 1, i);
  277. Tokens.add(strTemToken);
  278. step = i;
  279. isFindingEndYinHao = false;
  280. }
  281. }
  282. break;
  283. case ' ':
  284. if (!isFindingEndYinHao) {
  285. if (step == (i - 1)) {
  286. step = i;
  287. } else {
  288. strTemToken = strTem.substring(step + 1, i);
  289. Tokens.add(strTemToken);
  290. step = i;
  291. }
  292. }
  293. break;
  294. case '(':
  295. case '[':
  296. if (i == 0 || strTem.charAt(i - 1) == ' ' || (Tokens.size() > 0 && Tokens.get(Tokens.size() - 1) == String.valueOf(c)) || strTem.charAt(i - 1) == '=') {
  297. Tokens.add(String.valueOf(c));
  298. step = i;
  299. }
  300. break;
  301. case ')':
  302. case ']':
  303. if ((i < strTem.length() - 1 && (strTem.charAt(i + 1) == ' ' || strTem.charAt(i + 1) == c)) || i == strTem.length() - 1) {
  304. Boolean isAdd = false;
  305. for (int index = Tokens.size() - 1; index >= 0; index--) {
  306. if ((c == ')' && Tokens.get(index).equals("(")) || (c == ']' && Tokens.get(index).equals("["))) {
  307. isAdd = true;
  308. break;
  309. }
  310. }
  311. if (isAdd) {
  312. strTemToken = strTem.substring(step + 1, i);
  313. if (strTemToken != null && !strTemToken.equals("")) {
  314. Tokens.add(strTemToken);
  315. }
  316. Tokens.add(String.valueOf(c));
  317. step = i;
  318. }
  319. }
  320. break;
  321. case '=':
  322. case '~':
  323. case '>':
  324. case '>':
  325. case '<':
  326. case '<':
  327. strTemToken = strTem.substring(step + 1, i);
  328. if (strTemToken != null && strTemToken != "") {
  329. Tokens.add(strTemToken);
  330. }
  331. if (strTem.charAt(i + 1) == '=') {
  332. Tokens.add(String.valueOf(c) + "=");
  333. step = i + 1;
  334. i++;
  335. } else {
  336. Tokens.add(String.valueOf(c));
  337. step = i;
  338. }
  339. break;
  340. }
  341. }
  342. if (step < strTem.length() - 1) {
  343. Tokens.add(strTem.substring(step + 1));
  344. }
  345. //#endregion
  346. return Tokens;
  347. } else {
  348. return null;
  349. }
  350. }
  351. }