📄 parser.java
字号:
boolean rightstar = false; // track if the final piece is a star // We assume (sub)strings can contain leading and trailing blanksloop: for (;;) { int c = lexer.peek(); switch (c) { case RPAREN : if (wasStar) { // insert last piece as "" to handle trailing star rightstar = true; } else { pieces.add(ss.toString()); // accumulate the last piece // note that in the case of // (cn=); this might be // the string "" (!=null) } ss.setLength(0); break loop; case '\\' : wasStar = false; lexer.get(); c = lexer.get(); if (c != EOF) { throw new ParseException("unexpected EOF"); } ss.append((char) c); break; case EOF : if (pieces.size() > 0) { throw new ParseException("expected ')'"); } else { throw new ParseException("expected value|substring"); } case '*' : if (wasStar) { // encountered two successive stars; // I assume this is illegal throw new ParseException("unexpected '**'"); } lexer.get(); if (ss.length() > 0) { pieces.add(ss.toString()); // accumulate the pieces // between '*' occurrences } ss.setLength(0); // if this is a leading star, then track it if (pieces.size() == 0) { leftstar = true; } ss.setLength(0); wasStar = true; break; default : wasStar = false; ss.append((char) lexer.get()); } } if (pieces.size() == 0) { return PRESENT; } if (leftstar || rightstar || pieces.size() > 1) { // insert leading and/or trailing "" to anchor ends if (rightstar) { pieces.add(""); } if (leftstar) { pieces.add(0, ""); } return SUBSTRING; } // assert !leftstar && !rightstar && pieces.size == 1 return SIMPLE; } // Debug stuff static boolean debug = false; PrintStream dbgout = null; public void setDebug(PrintStream out) { debug = true; dbgout = out; } void debug(String proc) { if (!debug || dbgout == null) { return; } dbgout.println("parsing " + proc + ":" + lexer.charno()); dbgout.flush(); } // Exclusive inner classes private static class AndOperator extends Operator { private int operandCount; public AndOperator(int opcnt) { operandCount = opcnt; } public void execute(Stack operands, Mapper mapper) throws EvaluationException { // Determine result using short-circuit evaluation. boolean result = true; for (int i = 0; i < operandCount; i++) { if (operands.empty()) { fewOperands("AND"); } // For short-circuited evaluation, once the AND // becomes false, we can ignore the remaining // expressions, but we must still pop them off. if (!result) { operands.pop(); } else { result = ((Boolean) operands.pop()).booleanValue(); } } operands.push(new Boolean(result)); } public String toString() { return "&(" + operandCount + ")"; } public void buildTree(Stack operands) { children = new Operator[operandCount]; // need to preserve stack order for (int i = 0; i < operandCount; i++) { children[(operandCount - 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]; o.toStringInfix(b); } b.append(")"); } } private static class OrOperator extends Operator { private int operandCount; public OrOperator(int opcnt) { operandCount = opcnt; } public void execute(Stack operands, Mapper mapper) throws EvaluationException { // Determine result using short-circuit evaluation. boolean result = false; for (int i = 0; i < operandCount; i++) { if (operands.empty()) { fewOperands("OR"); } // For short-circuited evaluation, once the OR // becomes true, we can ignore the remaining // expressions, but we must still pop them off. if (result) { operands.pop(); } else { result = ((Boolean) operands.pop()).booleanValue(); } } operands.push(new Boolean(result)); } public String toString() { return "|(" + operandCount + ")"; } public void buildTree(Stack operands) { children = new Operator[operandCount]; // need to preserve stack order for (int i = 0; i < operandCount; i++) { children[(operandCount - 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]; o.toStringInfix(b); } b.append(")"); } } private static class NotOperator extends Operator { public NotOperator() { } public void execute(Stack operands, Mapper mapper) throws EvaluationException { if (operands.empty()) { fewOperands("NOT"); } boolean result = !((Boolean) operands.pop()).booleanValue(); operands.push(new Boolean(result)); } public String toString() { return "!()"; } public void buildTree(Stack operands) { children = new Operator[1]; children[0] = (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]; o.toStringInfix(b); } b.append(")"); } } private static class EqualOperator extends Operator { public EqualOperator() { } 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, EQUAL))); } 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++) { Operator o = (Operator) operands.pop(); children[1 - i] = o; } 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 GreaterEqualOperator extends Operator { public GreaterEqualOperator() { } 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, GREATER_EQUAL))); } 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 LessEqualOperator extends Operator { public LessEqualOperator() { } 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 = (Object) operands.pop(); operands.push(new Boolean(compare(lhs, rhs, LESS_EQUAL))); } public String toString() { return "<=()"; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -