Search in sources :

Example 1 with AbstractNode

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;
        }
    }
}
Also used : BinOpNode(org.cytoscape.equations.internal.parse_tree.BinOpNode) AbstractNode(org.cytoscape.equations.AbstractNode) TreeNode(org.cytoscape.equations.TreeNode)

Example 2 with AbstractNode

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));
}
Also used : AbstractNode(org.cytoscape.equations.AbstractNode) ArrayList(java.util.ArrayList) FuncCallNode(org.cytoscape.equations.internal.parse_tree.FuncCallNode) ListToString(org.cytoscape.equations.internal.builtins.ListToString) Function(org.cytoscape.equations.Function)

Example 3 with AbstractNode

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;
        }
    }
}
Also used : AbstractNode(org.cytoscape.equations.AbstractNode) TreeNode(org.cytoscape.equations.TreeNode)

Example 4 with AbstractNode

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 + ".");
}
Also used : StringConstantNode(org.cytoscape.equations.internal.parse_tree.StringConstantNode) AbstractNode(org.cytoscape.equations.AbstractNode) ListToString(org.cytoscape.equations.internal.builtins.ListToString) BooleanConstantNode(org.cytoscape.equations.internal.parse_tree.BooleanConstantNode) TreeNode(org.cytoscape.equations.TreeNode) IdentNode(org.cytoscape.equations.internal.parse_tree.IdentNode) FloatConstantNode(org.cytoscape.equations.internal.parse_tree.FloatConstantNode)

Example 5 with AbstractNode

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;
}
Also used : AbstractNode(org.cytoscape.equations.AbstractNode) TreeNode(org.cytoscape.equations.TreeNode)

Aggregations

AbstractNode (org.cytoscape.equations.AbstractNode)5 TreeNode (org.cytoscape.equations.TreeNode)4 ListToString (org.cytoscape.equations.internal.builtins.ListToString)2 ArrayList (java.util.ArrayList)1 Function (org.cytoscape.equations.Function)1 BinOpNode (org.cytoscape.equations.internal.parse_tree.BinOpNode)1 BooleanConstantNode (org.cytoscape.equations.internal.parse_tree.BooleanConstantNode)1 FloatConstantNode (org.cytoscape.equations.internal.parse_tree.FloatConstantNode)1 FuncCallNode (org.cytoscape.equations.internal.parse_tree.FuncCallNode)1 IdentNode (org.cytoscape.equations.internal.parse_tree.IdentNode)1 StringConstantNode (org.cytoscape.equations.internal.parse_tree.StringConstantNode)1