📄 parser.java
字号:
public void buildTree(Stack operands) { children = new Operator[2]; // need to preserve stack order for (int i = 0; i < 2; i++) { children[1 - i] = (Operator) operands.pop(); } operands.push(this); } public void toStringInfix(StringBuffer b) { b.append("("); for (int i = 0; i < children.length; i++) { Operator o = (Operator) children[i]; if (i > 0) { b.append("<="); } o.toStringInfix(b); } b.append(")"); } } private static class ApproxOperator extends Operator { public ApproxOperator() { } public void execute(Stack operands, Mapper mapper) throws EvaluationException { if (operands.empty()) { fewOperands("~="); } // We cheat and use the knowledge that top (right) operand // will always be a string because of the way code was generated String rhs = (String) operands.pop(); if (operands.empty()) { fewOperands("~="); } Object lhs = operands.pop(); operands.push(new Boolean(compare(lhs, rhs, APPROX))); } public String toString() { return "~=()"; } public void buildTree(Stack operands) { children = new Operator[2]; // need to preserve stack order for (int i = 0; i < 2; i++) { children[1 - i] = (Operator) operands.pop(); } operands.push(this); } public void toStringInfix(StringBuffer b) { b.append("("); for (int i = 0; i < children.length; i++) { Operator o = (Operator) children[i]; if (i > 0) { b.append("~="); } o.toStringInfix(b); } b.append(")"); } } private static class PresentOperator extends Operator { String attribute; public PresentOperator(String attribute) { this.attribute = attribute; } public void execute(Stack operands, Mapper mapper) throws EvaluationException { Object value = mapper.lookup(attribute); operands.push(new Boolean(value != null)); } public String toString() { return attribute + "=*"; } public void buildTree(Stack operands) { operands.push(this); } public void toStringInfix(StringBuffer b) { b.append("("); b.append(attribute + "=*"); b.append(")"); } } private static class PushOperator extends Operator { String attribute; public PushOperator(String attribute) { this.attribute = attribute; } public void execute(Stack operands, Mapper mapper) throws EvaluationException { // find and push the value of a given attribute Object value = mapper.lookup(attribute); if (value == null) { throw new AttributeNotFoundException( "attribute " + attribute + " not found"); } operands.push(value); } public String toString() { return "push(" + attribute + ")"; } public String toStringInfix() { return attribute; } public void buildTree(Stack operands) { operands.push(this); } public void toStringInfix(StringBuffer b) { b.append(attribute); } } private static class ConstOperator extends Operator { Object val; public ConstOperator(Object val) { this.val = val; } public void execute(Stack operands, Mapper mapper) throws EvaluationException { operands.push(val); } public String toString() { return "const(" + val + ")"; } public String toStringInfix() { return val.toString(); } public void buildTree(Stack operands) { operands.push(this); } public void toStringInfix(StringBuffer b) { b.append(val.toString()); } } private static class SubStringOperator extends Operator implements OperatorConstants { String[] pieces; public SubStringOperator(String[] pieces) { this.pieces = pieces; } public void execute(Stack operands, Mapper mapper) throws EvaluationException { if (operands.empty()) { fewOperands("SUBSTRING"); } Object op = operands.pop(); // The operand can either be a string or an array of strings. if (op instanceof String) { operands.push(check((String) op)); } else if (op instanceof String[]) { // If one element of the array matches, then push true. String[] ops = (String[]) op; boolean result = false; for (int i = 0; !result && (i < ops.length); i++) { if (check(ops[i]) == Boolean.TRUE) { result = true; } } operands.push((result) ? Boolean.TRUE : Boolean.FALSE); } else { unsupportedType("SUBSTRING", op.getClass()); } } private Boolean check(String s) { // Walk the pieces to match the string // There are implicit stars between each piece, // and the first and last pieces might be "" to anchor the match. // assert (pieces.length > 1) // minimal case is <string>*<string> Boolean result = Boolean.FALSE; int len = pieces.length; loop : for (int i = 0; i < len; i++) { String piece = (String) pieces[i]; int index = 0; if (i == len - 1) { // this is the last piece if (s.endsWith(piece)) { result = Boolean.TRUE; } else { result = Boolean.FALSE; } break loop; } // initial non-star; assert index == 0 else if (i == 0) { if (!s.startsWith(piece)) { result = Boolean.FALSE; break loop; } } // assert i > 0 && i < len-1 else { // Sure wish stringbuffer supported e.g. indexOf index = s.indexOf(piece, index); if (index < 0) { result = Boolean.FALSE; break loop; } } // start beyond the matching piece index += piece.length(); } return result; } public String toString() { StringBuffer b = new StringBuffer(); b.append("substring("); for (int i = 0; i < pieces.length; i++) { String piece = pieces[i]; if (i > 0) { b.append("*"); } b.append(escape(piece)); } b.append(")"); return b.toString(); } public String escape(String s) { int len = s.length(); StringBuffer buf = new StringBuffer(len); for (int i = 0; i < len; i++) { char c = s.charAt(i); if (c == ')' || c == '*') buf.append('\\'); buf.append(c); } return buf.toString(); } public void buildTree(Stack operands) { children = new Operator[1]; children[0] = (Operator) operands.pop(); operands.push(this); } public void toStringInfix(StringBuffer b) { b.append("("); children[0].toStringInfix(b); // dump attribute b.append("="); for (int i = 0; i < pieces.length; i++) { String piece = (String) pieces[i]; if (i > 0) { b.append("*"); } b.append(piece); } b.append(")"); } } // Utility classes and Interfaces private interface OperatorConstants { static final int SSINIT = 0; static final int SSFINAL = 1; static final int SSMIDDLE = 2; static final int SSANY = 3; } /** * Compare two operands in an expression with respect * to the following operators =, <=, >= and ~= * * Example: value=100 * * @param lhs an object that implements comparable or an array of * objects that implement comparable. * @param rhs a string representing the right operand. * @param operator an integer that represents the operator. * @return <tt>true</tt> or <tt>false</tt> according to the evaluation. * @throws EvaluationException if it is not possible to do the comparison. **/ public static boolean compare(Object lhs, String rhs, int operator) throws EvaluationException { // Determine class of LHS. Class lhsClass = null; // If LHS is an array, then call compare() on each element // of the array until a match is found. if (lhs.getClass().isArray()) { // First, if this is an array of primitives, then convert // the entire array to an array of the associated // primitive wrapper class instances. if (lhs.getClass().getComponentType().isPrimitive()) { lhs = convertPrimitiveArray(lhs); } // Now call compare on each element of array. Object[] array = (Object[]) lhs; for (int i = 0; i < array.length; i++) { if (compare(array[i], rhs, operator)) { return true; } } } // If LHS is a vector, then call compare() on each element // of the vector until a match is found. else if (lhs instanceof Vector) { for (Enumeration e = ((Vector) lhs).elements(); e.hasMoreElements();) { if (compare(e.nextElement(), rhs, operator)) { return true; } } } else { // Get the class of LHS. lhsClass = lhs.getClass(); // At this point we are expecting the LHS to be a comparable, // but Boolean is a special case since it is the only primitive // wrapper class that does not implement comparable; deal with // Boolean separately. if (lhsClass == Boolean.class) { return compareBoolean(lhs, rhs, operator); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -