/** *Pushesanewoperatorontotheoppstack,resolvingexistingoppsas *needed. *@paramnodeTheoperatornode
*/ privatevoid pushOpp(OppNode node) { // If node is null then it's just a group marker if (node == null) {
oppStack.add(0, node); return;
} while (true) { if (oppStack.size() == 0) { break;
}
OppNode top = oppStack.get(0); // If the top is a spacer then don't pop // anything if (top == null) { break;
} // If the top node has a lower precedence then // let it stay if (top.getPrecedence() < node.getPrecedence()) { break;
} // Remove the top node
oppStack.remove(0); // Let it fill its branches
top.popValues(nodeStack); // Stick it on the resolved node stack
nodeStack.add(0, top);
} // Add the new node to the opp stack
oppStack.add(0, node);
}
/** *Resolvesallpendingoppnodesonthestackuntilthenextgroupmarker *isreached.
*/ privatevoid resolveGroup() {
OppNode top = null; while ((top = oppStack.remove(0)) != null) { // Let it fill its branches
top.popValues(nodeStack); // Stick it on the resolved node stack
nodeStack.add(0, top);
}
}
/** *Parsesthespecifiedexpressionintoatreeofparsenodes. *@paramexprTheexpressiontoparse *@throwsParseExceptionaparsingerroroccurred
*/ privatevoid parseExpression(String expr) throws ParseException {
StringNode currStringNode = null; // We cheat a little and start an artificial // group right away. It makes finishing easier.
pushOpp(null);
ExpressionTokenizer et = new ExpressionTokenizer(expr); while (et.hasMoreTokens()) { int token = et.nextToken(); if (token != ExpressionTokenizer.TOKEN_STRING) {
currStringNode = null;
} switch (token) { case ExpressionTokenizer.TOKEN_STRING : if (currStringNode == null) {
currStringNode = new StringNode(et.getTokenValue());
nodeStack.add(0, currStringNode);
} else { // Add to the existing
currStringNode.value.append(' ');
currStringNode.value.append(et.getTokenValue());
} break; case ExpressionTokenizer.TOKEN_AND :
pushOpp(new AndNode()); break; case ExpressionTokenizer.TOKEN_OR :
pushOpp(new OrNode()); break; case ExpressionTokenizer.TOKEN_NOT :
pushOpp(new NotNode()); break; case ExpressionTokenizer.TOKEN_EQ :
pushOpp(new EqualNode()); break; case ExpressionTokenizer.TOKEN_NOT_EQ :
pushOpp(new NotNode()); // Sneak the regular node in. The NOT will // be resolved when the next opp comes along.
oppStack.add(0, new EqualNode()); break; case ExpressionTokenizer.TOKEN_RBRACE : // Closeout the current group
resolveGroup(); break; case ExpressionTokenizer.TOKEN_LBRACE : // Push a group marker
pushOpp(null); break; case ExpressionTokenizer.TOKEN_GE :
pushOpp(new NotNode()); // Similar strategy to NOT_EQ above, except this // is NOT less than
oppStack.add(0, new LessThanNode()); break; case ExpressionTokenizer.TOKEN_LE :
pushOpp(new NotNode()); // Similar strategy to NOT_EQ above, except this // is NOT greater than
oppStack.add(0, new GreaterThanNode()); break; case ExpressionTokenizer.TOKEN_GT :
pushOpp(new GreaterThanNode()); break; case ExpressionTokenizer.TOKEN_LT :
pushOpp(new LessThanNode()); break; case ExpressionTokenizer.TOKEN_END : break;
}
} // Finish off the rest of the opps
resolveGroup(); if (nodeStack.size() == 0) { thrownew ParseException(sm.getString("expressionParseTree.noNodes"), et.getIndex());
} if (nodeStack.size() > 1) { thrownew ParseException(sm.getString("expressionParseTree.extraNodes"), et.getIndex());
} if (oppStack.size() != 0) { thrownew ParseException(sm.getString("expressionParseTree.unusedOpCodes"), et.getIndex());
}
root = nodeStack.get(0);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.