use of org.cytoscape.equations.AbstractNode in project cytoscape-impl by cytoscape.
the class EquationParserImpl method parseExpr.
//
// The actual parsing takes place here.
//
/**
* Implements expr --> term | term {+ term } | term {- term} | term {& term} | term compOp term.
*/
private AbstractNode parseExpr() {
AbstractNode exprNode = parseTerm();
for (; ; ) {
final Token token = tokeniser.getToken();
final int sourceLocation = tokeniser.getStartPos();
if (token == Token.PLUS || token == Token.MINUS || token == Token.AMPERSAND) {
final TreeNode term = parseTerm();
if (token == Token.PLUS || token == Token.MINUS)
exprNode = handleBinaryArithmeticOp(token, sourceLocation, exprNode, term);
else
// String concatenation.
exprNode = new BinOpNode(sourceLocation, Token.AMPERSAND, exprNode, term);
} else if (token.isComparisonOperator()) {
final TreeNode term = parseTerm();
// No chaining for comparison operators!
return handleComparisonOp(token, sourceLocation, exprNode, term);
} else {
tokeniser.ungetToken(token);
return exprNode;
}
}
}
use of org.cytoscape.equations.AbstractNode in project cytoscape-impl by cytoscape.
the class EquationParserImpl method parseFunctionCall.
/**
* Implements func_call --> ident "(" ")" | ident "(" expr {"," expr} ")".
*/
private AbstractNode parseFunctionCall() {
Token token = tokeniser.getToken();
final int functionNameStartPos = tokeniser.getStartPos();
if (token != Token.IDENTIFIER)
throw new IllegalStateException(functionNameStartPos + ": function name expected.");
final String originalName = tokeniser.getIdent();
final String functionNameCandidate = originalName.toUpperCase();
if (functionNameCandidate.equals("DEFINED"))
return parseDefined();
final Function func = nameToFunctionMap.get(functionNameCandidate);
if (func == null) {
if (tokeniser.getToken() == Token.OPEN_PAREN)
throw new IllegalStateException(functionNameStartPos + ": call to unknown function " + originalName + "().");
else
throw new IllegalStateException(functionNameStartPos + ": unknown text \"" + originalName + "\", maybe you forgot to put quotes around this text?");
}
token = tokeniser.getToken();
final int openParenPos = tokeniser.getStartPos();
if (token != Token.OPEN_PAREN)
throw new IllegalStateException(openParenPos + ": expected '(' after function name \"" + functionNameCandidate + "\".");
// Parse the comma-separated argument list.
final ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>();
ArrayList<AbstractNode> args = new ArrayList<AbstractNode>();
int sourceLocation;
for (; ; ) {
token = tokeniser.getToken();
sourceLocation = tokeniser.getStartPos();
if (token == Token.CLOSE_PAREN)
break;
tokeniser.ungetToken(token);
final AbstractNode exprNode = parseExpr();
argTypes.add(exprNode.getType());
args.add(exprNode);
token = tokeniser.getToken();
sourceLocation = tokeniser.getStartPos();
if (token != Token.COMMA)
break;
}
final Class<?> returnType = func.validateArgTypes(argTypes.toArray(new Class<?>[argTypes.size()]));
if (returnType == null)
throw new IllegalStateException((openParenPos + 1) + ": invalid number or type of arguments in call to " + functionNameCandidate + "().");
if (token != Token.CLOSE_PAREN)
throw new IllegalStateException(sourceLocation + ": expected the closing parenthesis of a call to " + functionNameCandidate + ".");
AbstractNode[] nodeArray = new AbstractNode[args.size()];
return new FuncCallNode(functionNameStartPos, func, returnType, args.toArray(nodeArray));
}
use of org.cytoscape.equations.AbstractNode in project cytoscape-impl by cytoscape.
the class EquationParserImpl method parseTerm.
/**
* Implements term --> power {* power} | power {/ power}
*/
private AbstractNode parseTerm() {
AbstractNode termNode = parsePower();
for (; ; ) {
final Token token = tokeniser.getToken();
final int sourceLocation = tokeniser.getStartPos();
if (token == Token.MUL || token == Token.DIV) {
final TreeNode powerNode = parsePower();
termNode = handleBinaryArithmeticOp(token, sourceLocation, termNode, powerNode);
} else {
tokeniser.ungetToken(token);
return termNode;
}
}
}
use of org.cytoscape.equations.AbstractNode in project cytoscape-impl by cytoscape.
the class EquationParserImpl method parseFactor.
/**
* Implements factor --> constant | variable_ref | "(" expr ")" | ("-"|"+") factor | func_call
*/
private AbstractNode parseFactor() {
Token token = tokeniser.getToken();
int sourceLocation = tokeniser.getStartPos();
// 1. a constant
if (token == Token.FLOAT_CONSTANT)
return new FloatConstantNode(sourceLocation, tokeniser.getFloatConstant());
else if (token == Token.STRING_CONSTANT)
return new StringConstantNode(sourceLocation, tokeniser.getStringConstant());
else if (token == Token.BOOLEAN_CONSTANT)
return new BooleanConstantNode(sourceLocation, tokeniser.getBooleanConstant());
// 2. a variable reference
if (token == Token.DOLLAR) {
final int varRefStartPos = sourceLocation;
token = tokeniser.getToken();
sourceLocation = tokeniser.getStartPos();
final boolean usingOptionalBraces = token == Token.OPEN_BRACE;
if (usingOptionalBraces) {
token = tokeniser.getToken();
sourceLocation = tokeniser.getStartPos();
}
if (token != Token.IDENTIFIER)
throw new IllegalStateException(sourceLocation + ": identifier expected.");
final String ident = tokeniser.getIdent();
final Class<?> varRefType = variableNameToTypeMap.get(ident);
if (varRefType == null)
throw new IllegalStateException(sourceLocation + ": unknown variable reference name: \"" + ident + "\".");
variableReferences.add(ident);
Object defaultValue = null;
if (usingOptionalBraces) {
token = tokeniser.getToken();
// Do we have a default value?
if (token == Token.COLON) {
token = tokeniser.getToken();
sourceLocation = tokeniser.getStartPos();
if (token != Token.FLOAT_CONSTANT && token != Token.STRING_CONSTANT && token != Token.BOOLEAN_CONSTANT)
throw new IllegalStateException(sourceLocation + ": expected default value for variable reference.");
switch(token) {
case FLOAT_CONSTANT:
defaultValue = new Double(tokeniser.getFloatConstant());
break;
case BOOLEAN_CONSTANT:
defaultValue = new Boolean(tokeniser.getBooleanConstant());
break;
case STRING_CONSTANT:
defaultValue = new String(tokeniser.getStringConstant());
break;
}
token = tokeniser.getToken();
sourceLocation = tokeniser.getStartPos();
}
if (token != Token.CLOSE_BRACE)
throw new IllegalStateException(sourceLocation + ": closing brace expected.");
defaultVariableValues.put(ident, defaultValue);
}
return new IdentNode(varRefStartPos, tokeniser.getIdent(), defaultValue, varRefType);
}
// 3. a parenthesised expression
if (token == Token.OPEN_PAREN) {
final AbstractNode exprNode = parseExpr();
token = tokeniser.getToken();
if (token != Token.CLOSE_PAREN)
throw new IllegalStateException(sourceLocation + ": '(' expected.");
return exprNode;
}
// 4. a unary operator
if (token == Token.PLUS || token == Token.MINUS) {
final TreeNode factor = parseFactor();
return handleUnaryOp(sourceLocation, token, factor);
}
// 5. function call
if (token == Token.IDENTIFIER) {
tokeniser.ungetToken(token);
return parseFunctionCall();
}
if (token == Token.ERROR)
throw new IllegalStateException(sourceLocation + ": " + tokeniser.getErrorMsg());
throw new IllegalStateException(sourceLocation + ": unexpected input token: " + token + ".");
}
use of org.cytoscape.equations.AbstractNode in project cytoscape-impl by cytoscape.
the class EquationParserImpl method parsePower.
/**
* Implements power --> factor | factor ^ power
*/
private AbstractNode parsePower() {
AbstractNode powerNode = parseFactor();
final Token token = tokeniser.getToken();
final int sourceLocation = tokeniser.getStartPos();
if (token == Token.CARET) {
final TreeNode rhs = parsePower();
powerNode = handleBinaryArithmeticOp(token, sourceLocation, powerNode, rhs);
} else
tokeniser.ungetToken(token);
return powerNode;
}
Aggregations