翻译简易逻辑表达式
自定义逻辑表达式,关键字:"="等于,"&"与,"|"或,"(",")","<>"包含,"><"不包含,"#"不等于。
表达式支持括号标识作用域。
自动机分析如下:
JAVA 代码实现:
public class ConditionAnalysis { public static void main(String[] args) { String expression = "(1=1&(1=2|1=1) )"; ConditionAnalysis conditionAnalysis = new ConditionAnalysis(); Context context = conditionAnalysis.new Context(ContextStatus.WAIT); Res res = conditionAnalysis.analysis(expression, 0, context); System.out.println(res.data); } // 终止符号 Set<Character> signSet; ConditionAnalysis() { this.signSet = new HashSet<Character>(); signSet.add(' '); signSet.add('='); signSet.add('('); signSet.add(')'); signSet.add('#'); signSet.add('<'); signSet.add('>'); signSet.add('&'); signSet.add('|'); } public Res analysis(String expression, int left, Context context) { int len = expression.length(), right = left; while (right < len) { char c = expression.charAt(right); if (c == ' ') { right++; continue; } // 回归条件 if (c == ')') { right++; Res res = new Res(context.currentRes, left, right); System.out.println(expression.substring(left - 1, right) + " >>>>>> " + context.currentRes); return res; } // 关键字处理 if (c == '&') { if (context.innerStatus != ContextStatus.RES) throw new RuntimeException("error at point:" + right); context.innerStatus = ContextStatus.AND; right++; continue; } else if (c == '|') { if (context.innerStatus != ContextStatus.RES) throw new RuntimeException("error at point:" + right); context.innerStatus = ContextStatus.OR; right++; continue; } else if (c == '=') { context.innerStatus = ContextStatus.EQ; right++; continue; } else if (c == '#') { context.innerStatus = ContextStatus.NOTEQ; right++; continue; } else if (c == '<') { if (context.innerStatus == ContextStatus.TOKEN) context.innerStatus = ContextStatus.XYW; else if (context.innerStatus == ContextStatus.DYW) context.innerStatus = ContextStatus.NOTCON; right++; continue; } else if (c == '>') { if (context.innerStatus == ContextStatus.TOKEN) context.innerStatus = ContextStatus.DYW; else if (context.innerStatus == ContextStatus.XYW) context.innerStatus = ContextStatus.CON; right++; continue; } // 内部作用域处理 if (c == '(') { Res res = analysis(expression, right + 1, new Context(ContextStatus.WAIT)); // 重要!内部作用域计算完成,外部作用域此时的状态是没有跟上计算的 context.outerStatus = context.innerStatus; context.innerStatus = ContextStatus.RES; if (null == context.currentRes) context.currentRes = res.data; else if (context.outerStatus == ContextStatus.AND) context.currentRes = context.currentRes && res.data; else if (context.outerStatus == ContextStatus.OR) context.currentRes = context.currentRes || res.data; right = res.right; continue; } // 线性处理,拿 token Token token = this.getToken(expression, right); if (context.innerStatus == ContextStatus.WAIT) { context.innerStatus = ContextStatus.TOKEN; context.leftToken = token; right = token.right; continue; } if (context.innerStatus == ContextStatus.AND || context.innerStatus == ContextStatus.OR) { context.leftToken = token; context.outerStatus = context.innerStatus; context.innerStatus = ContextStatus.TOKEN; right = token.right; continue; } // token 拿在计算线性局部结果的节点上 Res res = null; if (context.innerStatus == ContextStatus.EQ) { res = new Res(context.leftToken.data.equals(token.data), left, token.right); } else if (context.innerStatus == ContextStatus.NOTEQ) { res = new Res(!context.leftToken.data.equals(token.data), left, token.right); } else if (context.innerStatus == ContextStatus.CON) { res = new Res(context.leftToken.data.contains(token.data), left, token.right); } else if (context.innerStatus == ContextStatus.NOTCON) { Boolean currentRes = !context.leftToken.data.contains(token.data); res = new Res(currentRes, left, token.right); } else if (context.innerStatus == ContextStatus.XYW) { res = new Res(Integer.valueOf(context.leftToken.data) < Integer.valueOf(token.data), left, token.right); } else if (context.innerStatus == ContextStatus.DYW) { res = new Res(Integer.valueOf(context.leftToken.data) > Integer.valueOf(token.data), left, token.right); } context.leftToken = null; context.rightToken = null; context.innerStatus = ContextStatus.RES; if (null == context.currentRes) context.currentRes = res.data; else if (context.outerStatus == ContextStatus.AND) context.currentRes = context.currentRes && res.data; else if (context.outerStatus == ContextStatus.OR) context.currentRes = context.currentRes || res.data; context.outerStatus = null; right = res.right; } return new Res(context.currentRes, left, right); } private Token getToken(String expression, int left) { int len = expression.length(), right = left; if (right >= len) throw new RuntimeException("left:" + left + " out of length:" + len); StringBuilder sb = new StringBuilder(); char c = expression.charAt(right); while (right < len && !this.signSet.contains(c)) { sb.append(c); right++; c = expression.charAt(right); } Token reToken = new Token(sb.toString(), left, right); return reToken; } // 作用域的上下文 class Context { ContextStatus innerStatus; ContextStatus outerStatus; Boolean currentRes; Token leftToken; Token rightToken; Context(ContextStatus innerStatus) { this.innerStatus = innerStatus; } } class Res { Boolean data; int left; int right; Res(Boolean data, int left, int right) { this.data = data; this.left = left; this.right = right; } } class Token { String data; int left; int right; Token(String data, int left, int right) { this.data = data; this.left = left; this.right = right; } } // 自动机状态 private enum ContextStatus { WAIT, TOKEN, EQ, NOTEQ, XYW, DYW, CON, NOTCON, RES, AND, OR, DONE } }
当你看清人们的真相,于是你知道了,你可以忍受孤独