Search in sources :

Example 26 with ASTNode

use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.

the class Parser method parsePackage.

/**
	 * Parse a package.
	 * 
	 * @param expression
	 * @return
	 * @throws SyntaxError
	 */
public List<ASTNode> parsePackage(final String expression) throws SyntaxError {
    initialize(expression);
    while (fToken == TT_NEWLINE) {
        getNextToken();
    }
    ASTNode temp = parseExpression();
    fNodeList.add(temp);
    while (fToken != TT_EOF) {
        if (fToken == TT_PRECEDENCE_CLOSE) {
            throwSyntaxError("Too many closing ')'; End-of-file not reached.");
        }
        if (fToken == TT_LIST_CLOSE) {
            throwSyntaxError("Too many closing '}'; End-of-file not reached.");
        }
        if (fToken == TT_ARGUMENTS_CLOSE) {
            throwSyntaxError("Too many closing ']'; End-of-file not reached.");
        }
        while (fToken == TT_NEWLINE) {
            getNextToken();
        }
        if (fToken == TT_EOF) {
            return fNodeList;
        }
        temp = parseExpression();
        fNodeList.add(temp);
    }
    return fNodeList;
}
Also used : ASTNode(org.matheclipse.parser.client.ast.ASTNode)

Example 27 with ASTNode

use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.

the class DoubleEvaluator method derivative.

/**
	 * 
	 * TODO: add more derivation rules
	 * 
	 * @param node
	 * @param var
	 * @return
	 */
public ASTNode derivative(final ASTNode node, SymbolNode var) {
    if (node.isFree(var)) {
        return new DoubleNode(0.0);
    }
    if (node instanceof FunctionNode) {
        FunctionNode f = (FunctionNode) node;
        if (f.size() > 1 && f.getNode(0) instanceof SymbolNode) {
            SymbolNode head = (SymbolNode) f.getNode(0);
            if (f.size() == 2) {
                ASTNode arg1Derived = derivative(f.getNode(1), var);
                if (isSymbol(head, "Exp")) {
                    FunctionNode fun = new FunctionNode(fASTFactory.createSymbol("Exp"));
                    fun.add(f.getNode(1));
                    return getDerivativeResult(arg1Derived, fun);
                }
                if (isSymbol(head, "Cos")) {
                    FunctionNode fun = new FunctionNode(fASTFactory.createSymbol("Times"));
                    fun.add(new DoubleNode(-1.0));
                    fun.add(new FunctionNode(fASTFactory.createSymbol("Cos"), f.getNode(1)));
                    return getDerivativeResult(arg1Derived, fun);
                }
                if (isSymbol(head, "Sin")) {
                    FunctionNode fun = new FunctionNode(fASTFactory.createSymbol("Cos"));
                    fun.add(f.getNode(1));
                    return getDerivativeResult(arg1Derived, fun);
                }
            } else if (f.size() == 3 && isSymbol(head, "Power")) {
                if (f.get(2).isFree(var)) {
                    // derive x^r
                    ASTNode arg1Derived = derivative(f.getNode(1), var);
                    // (r-1)
                    FunctionNode exponent = fASTFactory.createFunction(fASTFactory.createSymbol("Plus"), new DoubleNode(-1.0), f.get(2));
                    // r*x^(r-1)
                    FunctionNode fun = fASTFactory.createFunction(fASTFactory.createSymbol("Times"), f.get(2), fASTFactory.createFunction(fASTFactory.createSymbol("Power"), f.get(1), exponent));
                    return getDerivativeResult(arg1Derived, fun);
                }
                if (f.get(1).isFree(var)) {
                    // derive a^x
                    ASTNode arg2Derived = derivative(f.getNode(2), var);
                    // log(a) * a^x
                    FunctionNode fun = fASTFactory.createFunction(fASTFactory.createSymbol("Times"), fASTFactory.createFunction(fASTFactory.createSymbol("Log"), f.get(1)), f);
                    return getDerivativeResult(arg2Derived, fun);
                }
            } else {
                if (isSymbol(head, "Plus")) {
                    FunctionNode result = new FunctionNode(f.getNode(0));
                    for (int i = 1; i < f.size(); i++) {
                        ASTNode deriv = derivative(f.getNode(i), var);
                        if (!deriv.equals(new DoubleNode(0.0))) {
                            result.add(deriv);
                        }
                    }
                    return result;
                }
                if (isSymbol(head, "Times")) {
                    FunctionNode plusResult = new FunctionNode(fASTFactory.createSymbol("Plus"));
                    for (int i = 1; i < f.size(); i++) {
                        FunctionNode timesResult = new FunctionNode(f.getNode(0));
                        boolean valid = true;
                        for (int j = 1; j < f.size(); j++) {
                            if (j == i) {
                                ASTNode deriv = derivative(f.getNode(j), var);
                                if (deriv.equals(new DoubleNode(0.0))) {
                                    valid = false;
                                } else {
                                    timesResult.add(deriv);
                                }
                            } else {
                                timesResult.add(f.getNode(j));
                            }
                        }
                        if (valid) {
                            plusResult.add(timesResult);
                        }
                    }
                    return plusResult;
                }
            }
        }
        return new FunctionNode(new SymbolNode("D"), node, var);
    // return evaluateFunction((FunctionNode) node);
    }
    if (node instanceof SymbolNode) {
        if (isSymbol((SymbolNode) node, var)) {
            return new DoubleNode(1.0);
        }
        IDoubleValue v = fVariableMap.get(node.toString());
        if (v != null) {
            return new DoubleNode(0.0);
        }
        Double dbl = SYMBOL_DOUBLE_MAP.get(node.toString());
        if (dbl != null) {
            return new DoubleNode(0.0);
        }
        return new DoubleNode(0.0);
    } else if (node instanceof NumberNode) {
        return new DoubleNode(0.0);
    }
    throw new ArithmeticMathException("EvalDouble#evaluate(ASTNode) not possible for: " + node.toString());
}
Also used : SymbolNode(org.matheclipse.parser.client.ast.SymbolNode) ArithmeticMathException(org.matheclipse.parser.client.math.ArithmeticMathException) NumberNode(org.matheclipse.parser.client.ast.NumberNode) FunctionNode(org.matheclipse.parser.client.ast.FunctionNode) ASTNode(org.matheclipse.parser.client.ast.ASTNode)

Example 28 with ASTNode

use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.

the class Parser method getFactor.

private ASTNode getFactor() throws SyntaxError {
    ASTNode temp;
    if (fToken == TT_PRECEDENCE_OPEN) {
        fRecursionDepth++;
        try {
            getNextToken();
            temp = parseExpression();
            if (fToken != TT_PRECEDENCE_CLOSE) {
                throwSyntaxError("\')\' expected.");
            }
        } finally {
            fRecursionDepth--;
        }
        getNextToken();
        if (fToken == TT_PRECEDENCE_OPEN) {
            return getTimes(temp);
        }
        if (fToken == TT_ARGUMENTS_OPEN) {
            return getFunctionArguments(temp);
        }
        return temp;
    } else if (fToken == TT_LIST_OPEN) {
        return getList();
    } else if (fToken == TT_IDENTIFIER) {
        final SymbolNode symbol = getSymbol();
        if (fToken == TT_BLANK) {
            // read '_'
            if (isWhitespace()) {
                temp = fFactory.createPattern(symbol, null);
                getNextToken();
            } else {
                getNextToken();
                if (fToken == TT_IDENTIFIER) {
                    final ASTNode check = getSymbol();
                    temp = fFactory.createPattern(symbol, check);
                } else {
                    temp = fFactory.createPattern(symbol, null);
                }
            }
        } else if (fToken == TT_BLANK_BLANK) {
            // read '__'
            if (isWhitespace()) {
                temp = fFactory.createPattern2(symbol, null);
                getNextToken();
            } else {
                getNextToken();
                if (fToken == TT_IDENTIFIER) {
                    final ASTNode check = getSymbol();
                    temp = fFactory.createPattern2(symbol, check);
                } else {
                    temp = fFactory.createPattern2(symbol, null);
                }
            }
        } else if (fToken == TT_BLANK_BLANK_BLANK) {
            // read '___'
            if (isWhitespace()) {
                temp = fFactory.createPattern3(symbol, null);
                getNextToken();
            } else {
                getNextToken();
                if (fToken == TT_IDENTIFIER) {
                    final ASTNode check = getSymbol();
                    temp = fFactory.createPattern3(symbol, check);
                } else {
                    temp = fFactory.createPattern3(symbol, null);
                }
            }
        } else if (fToken == TT_BLANK_OPTIONAL) {
            // read '_.'
            if (isWhitespace()) {
                temp = fFactory.createPattern(symbol, null, true);
                getNextToken();
            } else {
                getNextToken();
                if (fToken == TT_IDENTIFIER) {
                    final ASTNode check = getSymbol();
                    temp = fFactory.createPattern(symbol, check, true);
                } else {
                    temp = fFactory.createPattern(symbol, null, true);
                }
            }
        } else if (fToken == TT_BLANK_COLON) {
            // read '_:'
            getNextToken();
            ASTNode defaultValue = parseExpression();
            temp = fFactory.createPattern(symbol, null, defaultValue);
        } else {
            temp = symbol;
        }
        return parseArguments(temp);
    } else if (fToken == TT_BLANK) {
        if (isWhitespace()) {
            getNextToken();
            temp = fFactory.createPattern(null, null);
        } else {
            getNextToken();
            if (fToken == TT_IDENTIFIER) {
                final ASTNode check = getSymbol();
                temp = fFactory.createPattern(null, check);
            } else {
                temp = fFactory.createPattern(null, null);
            }
        }
        return parseArguments(temp);
    } else if (fToken == TT_BLANK_BLANK) {
        // read '__'
        if (isWhitespace()) {
            getNextToken();
            temp = fFactory.createPattern2(null, null);
        } else {
            getNextToken();
            if (fToken == TT_IDENTIFIER) {
                final ASTNode check = getSymbol();
                temp = fFactory.createPattern2(null, check);
            } else {
                temp = fFactory.createPattern2(null, null);
            }
        }
        return parseArguments(temp);
    } else if (fToken == TT_BLANK_BLANK_BLANK) {
        // read '___'
        if (isWhitespace()) {
            getNextToken();
            temp = fFactory.createPattern3(null, null);
        } else {
            getNextToken();
            if (fToken == TT_IDENTIFIER) {
                final ASTNode check = getSymbol();
                temp = fFactory.createPattern3(null, check);
            } else {
                temp = fFactory.createPattern3(null, null);
            }
        }
        return parseArguments(temp);
    } else if (fToken == TT_BLANK_OPTIONAL) {
        // read '_.'
        if (isWhitespace()) {
            getNextToken();
            temp = fFactory.createPattern(null, null, true);
        } else {
            getNextToken();
            if (fToken == TT_IDENTIFIER) {
                final ASTNode check = getSymbol();
                temp = fFactory.createPattern(null, check, true);
            } else {
                temp = fFactory.createPattern(null, null, true);
            }
        }
        return parseArguments(temp);
    } else if (fToken == TT_BLANK_COLON) {
        // read '_:'
        getNextToken();
        ASTNode defaultValue = parseExpression();
        temp = fFactory.createPattern(null, null, defaultValue);
        return parseArguments(temp);
    } else if (fToken == TT_DIGIT) {
        return getNumber(false);
    } else if (fToken == TT_STRING) {
        return getString();
    } else if (fToken == TT_PERCENT) {
        final FunctionNode out = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.Out));
        int countPercent = 1;
        getNextToken();
        if (fToken == TT_DIGIT) {
            countPercent = getIntegerNumber();
            out.add(fFactory.createInteger(countPercent));
            return out;
        }
        while (fToken == TT_PERCENT) {
            countPercent++;
            getNextToken();
        }
        out.add(fFactory.createInteger(-countPercent));
        return parseArguments(out);
    } else if (fToken == TT_SLOT) {
        getNextToken();
        final FunctionNode slot = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.Slot));
        if (fToken == TT_DIGIT) {
            slot.add(getNumber(false));
        } else {
            slot.add(fFactory.createInteger(1));
        }
        return parseArguments(slot);
    } else if (fToken == TT_SLOTSEQUENCE) {
        getNextToken();
        final FunctionNode slotSequencce = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.SlotSequence));
        if (fToken == TT_DIGIT) {
            slotSequencce.add(getNumber(false));
        } else {
            slotSequencce.add(fFactory.createInteger(1));
        }
        return parseArguments(slotSequencce);
    }
    switch(fToken) {
        case TT_PRECEDENCE_CLOSE:
            throwSyntaxError("Too much closing ) in factor.");
            break;
        case TT_LIST_CLOSE:
            throwSyntaxError("Too much closing } in factor.");
            break;
        case TT_ARGUMENTS_CLOSE:
            throwSyntaxError("Too much closing ] in factor.");
            break;
    }
    throwSyntaxError("Error in factor at character: '" + fCurrentChar + "' (" + fToken + ")");
    return null;
}
Also used : SymbolNode(org.matheclipse.parser.client.ast.SymbolNode) ASTNode(org.matheclipse.parser.client.ast.ASTNode) FunctionNode(org.matheclipse.parser.client.ast.FunctionNode)

Example 29 with ASTNode

use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.

the class Parser method parseLookaheadOperator.

private ASTNode parseLookaheadOperator(final int min_precedence) {
    ASTNode rhs = parsePrimary();
    while (true) {
        final int lookahead = fToken;
        if (fToken == TT_NEWLINE) {
            return rhs;
        }
        if ((fToken == TT_LIST_OPEN) || (fToken == TT_PRECEDENCE_OPEN) || (fToken == TT_IDENTIFIER) || (fToken == TT_STRING) || (fToken == TT_DIGIT) || (fToken == TT_SLOT)) {
            // lazy evaluation of multiplication
            InfixOperator timesOperator = (InfixOperator) fFactory.get("Times");
            if (timesOperator.getPrecedence() > min_precedence) {
                rhs = parseExpression(rhs, timesOperator.getPrecedence());
                continue;
            } else if ((timesOperator.getPrecedence() == min_precedence) && (timesOperator.getGrouping() == InfixOperator.RIGHT_ASSOCIATIVE)) {
                rhs = parseExpression(rhs, timesOperator.getPrecedence());
                continue;
            }
        } else {
            if (fToken == TT_DERIVATIVE) {
                rhs = parseDerivative(rhs);
            }
            if (lookahead != TT_OPERATOR) {
                break;
            }
            InfixOperator infixOperator = determineBinaryOperator();
            if (infixOperator != null) {
                if (infixOperator.getPrecedence() > min_precedence || ((infixOperator.getPrecedence() == min_precedence) && (infixOperator.getGrouping() == InfixOperator.RIGHT_ASSOCIATIVE))) {
                    if (";".equals(infixOperator.getOperatorString())) {
                        if (fPackageMode && fRecursionDepth < 1) {
                            return infixOperator.createFunction(fFactory, rhs, fFactory.createSymbol("Null"));
                        }
                    }
                    rhs = parseExpression(rhs, infixOperator.getPrecedence());
                    continue;
                }
            } else {
                PostfixOperator postfixOperator = determinePostfixOperator();
                if (postfixOperator != null) {
                    if (postfixOperator.getPrecedence() >= min_precedence) {
                        getNextToken();
                        rhs = postfixOperator.createFunction(fFactory, rhs);
                        continue;
                    }
                }
            }
        }
        break;
    }
    return rhs;
}
Also used : PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator) ASTNode(org.matheclipse.parser.client.ast.ASTNode) InfixOperator(org.matheclipse.parser.client.operator.InfixOperator)

Example 30 with ASTNode

use of org.matheclipse.parser.client.ast.ASTNode in project symja_android_library by axkr.

the class Parser method parsePrimary.

private ASTNode parsePrimary() {
    if (fToken == TT_OPERATOR) {
        if (";;".equals(fOperatorString)) {
            FunctionNode function = fFactory.createFunction(fFactory.createSymbol(IConstantOperators.Span));
            function.add(fFactory.createInteger(1));
            getNextToken();
            if (fToken == TT_COMMA || fToken == TT_ARGUMENTS_CLOSE || fToken == TT_PRECEDENCE_CLOSE) {
                function.add(fFactory.createSymbol(IConstantOperators.All));
                return function;
            }
            function.add(parsePrimary());
            if (fToken == TT_OPERATOR && ";;".equals(fOperatorString)) {
                function.add(fFactory.createSymbol(IConstantOperators.All));
                getNextToken();
            }
            return function;
        }
        if (".".equals(fOperatorString)) {
            fCurrentChar = '.';
            return getNumber(false);
        }
        final PrefixOperator prefixOperator = determinePrefixOperator();
        if (prefixOperator != null) {
            getNextToken();
            final ASTNode temp = parseLookaheadOperator(prefixOperator.getPrecedence());
            if ("PreMinus".equals(prefixOperator.getFunctionName()) && temp instanceof NumberNode) {
                // special cases for negative numbers
                ((NumberNode) temp).toggleSign();
                return temp;
            }
            return prefixOperator.createFunction(fFactory, temp);
        }
        throwSyntaxError("Operator: " + fOperatorString + " is no prefix operator.");
    }
    return getPart();
}
Also used : PrefixOperator(org.matheclipse.parser.client.operator.PrefixOperator) NumberNode(org.matheclipse.parser.client.ast.NumberNode) FunctionNode(org.matheclipse.parser.client.ast.FunctionNode) ASTNode(org.matheclipse.parser.client.ast.ASTNode)

Aggregations

ASTNode (org.matheclipse.parser.client.ast.ASTNode)56 Parser (org.matheclipse.parser.client.Parser)32 IExpr (org.matheclipse.core.interfaces.IExpr)10 FunctionNode (org.matheclipse.parser.client.ast.FunctionNode)8 MathException (org.matheclipse.parser.client.math.MathException)6 PatternMatcher (org.matheclipse.core.patternmatching.PatternMatcher)5 SymbolNode (org.matheclipse.parser.client.ast.SymbolNode)5 IAST (org.matheclipse.core.interfaces.IAST)4 IOException (java.io.IOException)3 AST2Expr (org.matheclipse.core.convert.AST2Expr)3 NumberNode (org.matheclipse.parser.client.ast.NumberNode)3 FileReader (java.io.FileReader)2 ISymbol (org.matheclipse.core.interfaces.ISymbol)2 ArithmeticMathException (org.matheclipse.parser.client.math.ArithmeticMathException)2 InfixOperator (org.matheclipse.parser.client.operator.InfixOperator)2 PostfixOperator (org.matheclipse.parser.client.operator.PostfixOperator)2 PrefixOperator (org.matheclipse.parser.client.operator.PrefixOperator)2 BufferedReader (java.io.BufferedReader)1 File (java.io.File)1 FileNotFoundException (java.io.FileNotFoundException)1