Search in sources :

Example 6 with PostfixOperator

use of org.matheclipse.parser.client.operator.PostfixOperator in project symja_android_library by axkr.

the class Parser method parseExpression.

/**
 * See <a href="http://en.wikipedia.org/wiki/Operator-precedence_parser">Operator -precedence
 * parser</a> for the idea, how to parse the operators depending on their precedence.
 *
 * @param lhs the already parsed left-hand-side of the operator
 * @param min_precedence
 * @return
 */
private ASTNode parseExpression(ASTNode lhs, final int min_precedence) {
    ASTNode rhs;
    Operator oper;
    while (true) {
        if (fToken == TT_NEWLINE) {
            return lhs;
        }
        if ((fToken == TT_LIST_OPEN) || (fToken == TT_PRECEDENCE_OPEN) || (fToken == TT_IDENTIFIER) || (fToken == TT_STRING) || (fToken == TT_DIGIT) || (fToken == TT_SLOT) || (fToken == TT_SLOTSEQUENCE)) {
            if (!ParserConfig.EXPLICIT_TIMES_OPERATOR) {
                // lazy evaluation of multiplication
                oper = fFactory.get("Times");
                if (ParserConfig.DOMINANT_IMPLICIT_TIMES || oper.getPrecedence() >= min_precedence) {
                    rhs = parseLookaheadOperator(oper.getPrecedence());
                    lhs = fFactory.createFunction(fFactory.createSymbol(oper.getFunctionName()), lhs, rhs);
                    continue;
                }
            }
        } else {
            if (fToken == TT_DERIVATIVE) {
                lhs = parseDerivative(lhs);
            }
            if (fToken != TT_OPERATOR) {
                break;
            }
            InfixOperator infixOperator = determineBinaryOperator();
            if (infixOperator != null) {
                if (infixOperator.getPrecedence() >= min_precedence) {
                    getNextToken();
                    ASTNode compoundExpressionNull = parseCompoundExpressionNull(infixOperator, lhs);
                    if (compoundExpressionNull != null) {
                        return compoundExpressionNull;
                    }
                    while (fToken == TT_NEWLINE) {
                        getNextToken();
                    }
                    lhs = parseInfixOperator(lhs, infixOperator);
                    continue;
                }
            } else {
                PostfixOperator postfixOperator = determinePostfixOperator();
                if (postfixOperator != null && postfixOperator.getPrecedence() >= min_precedence) {
                    lhs = parsePostfixOperator(lhs, postfixOperator);
                    continue;
                }
            }
        }
        break;
    }
    return lhs;
}
Also used : InfixOperator(org.matheclipse.parser.client.operator.InfixOperator) PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator) PrefixOperator(org.matheclipse.parser.client.operator.PrefixOperator) Operator(org.matheclipse.parser.client.operator.Operator) PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator) ASTNode(org.matheclipse.parser.client.ast.ASTNode) InfixOperator(org.matheclipse.parser.client.operator.InfixOperator)

Example 7 with PostfixOperator

use of org.matheclipse.parser.client.operator.PostfixOperator in project symja_android_library by axkr.

the class ComplexFormFactory method convertInfixOperator.

public void convertInfixOperator(ISymbol head, final StringBuilder buf, final IAST list, final InfixOperator oper, final int precedence) {
    if (list.isAST2()) {
        if (oper.getPrecedence() < precedence) {
            append(buf, "(");
        }
        if (oper.getGrouping() == InfixOperator.RIGHT_ASSOCIATIVE && list.arg1().head().equals(list.head())) {
            append(buf, "(");
        } else {
            if (oper.getOperatorString().equals("^")) {
                final Operator operator = getOperator(list.arg1().topHead());
                if (operator instanceof PostfixOperator) {
                    append(buf, "(");
                }
            }
        }
        convertInternal(buf, list.arg1(), oper.getPrecedence(), false);
        if (oper.getGrouping() == InfixOperator.RIGHT_ASSOCIATIVE && list.arg1().head().equals(list.head())) {
            append(buf, ")");
        } else {
            if (oper.getOperatorString().equals("^")) {
                final Operator operator = getOperator(list.arg1().topHead());
                if (operator instanceof PostfixOperator) {
                    append(buf, ")");
                }
            }
        }
        append(buf, oper.getOperatorString());
        if (oper.getGrouping() == InfixOperator.LEFT_ASSOCIATIVE && list.arg2().head().equals(list.head())) {
            append(buf, "(");
        }
        convertInternal(buf, list.arg2(), oper.getPrecedence(), false);
        if (oper.getGrouping() == InfixOperator.LEFT_ASSOCIATIVE && list.arg2().head().equals(list.head())) {
            append(buf, ")");
        }
        if (oper.getPrecedence() < precedence) {
            append(buf, ")");
        }
        return;
    }
    if (oper.getPrecedence() < precedence) {
        append(buf, "(");
    }
    if (// 
    list.size() > 3 && (head.equals(S.Equal) || head.equals(S.Unequal) || head.equals(S.Greater) || head.equals(S.GreaterEqual) || head.equals(S.Less) || head.equals(S.LessEqual))) {
        convertInternal(buf, list.arg1(), oper.getPrecedence(), false);
        for (int i = 2; i < list.size(); i++) {
            append(buf, oper.getOperatorString());
            convertInternal(buf, list.get(i), oper.getPrecedence(), false);
            if (i < list.size() - 1) {
                buf.append(" && ");
                convertInternal(buf, list.get(i), oper.getPrecedence(), false);
            }
        }
    } else {
        if (list.size() > 1) {
            convertInternal(buf, list.arg1(), oper.getPrecedence(), false);
        }
        for (int i = 2; i < list.size(); i++) {
            append(buf, oper.getOperatorString());
            convertInternal(buf, list.get(i), oper.getPrecedence(), false);
        }
    }
    if (oper.getPrecedence() < precedence) {
        append(buf, ")");
    }
}
Also used : PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator) Operator(org.matheclipse.parser.client.operator.Operator) InfixOperator(org.matheclipse.parser.client.operator.InfixOperator) PrefixOperator(org.matheclipse.parser.client.operator.PrefixOperator) PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator)

Example 8 with PostfixOperator

use of org.matheclipse.parser.client.operator.PostfixOperator in project symja_android_library by axkr.

the class ComplexFormFactory method convertOperator.

protected boolean convertOperator(final Operator operator, final IAST list, final StringBuilder buf, final int precedence, ISymbol head) {
    if ((operator instanceof PrefixOperator) && (list.isAST1())) {
        convertPrefixOperator(buf, list, (PrefixOperator) operator, precedence);
        return true;
    }
    if ((operator instanceof InfixOperator) && (list.size() > 2)) {
        InfixOperator infixOperator = (InfixOperator) operator;
        if (head.equals(S.Plus)) {
            if (fPlusReversed) {
                convertInfixOperatorReversed(buf, list, "add");
            } else {
                convertInfixOperator(buf, list, "add");
            }
            return true;
        } else if (head.equals(S.Times)) {
            convertInfixOperator(buf, list, "multiply");
            return true;
        } else if (list.isPower()) {
            convertInfixOperator(buf, list, "pow");
            return true;
        } else if (list.isAST(S.Apply)) {
            if (list.size() == 3) {
                convertInfixOperator(head, buf, list, ASTNodeFactory.APPLY_OPERATOR, precedence);
                return true;
            }
            if (list.size() == 4 && list.arg2().equals(F.CListC1)) {
                convertInfixOperator(head, buf, list, ASTNodeFactory.APPLY_LEVEL_OPERATOR, precedence);
                return true;
            }
            return false;
        } else if (list.size() != 3 && infixOperator.getGrouping() != InfixOperator.NONE) {
            return false;
        }
        convertInfixOperator(head, buf, list, (InfixOperator) operator, precedence);
        return true;
    }
    if ((operator instanceof PostfixOperator) && (list.isAST1())) {
        convertPostfixOperator(buf, list, (PostfixOperator) operator, precedence);
        return true;
    }
    return false;
}
Also used : PrefixOperator(org.matheclipse.parser.client.operator.PrefixOperator) PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator) InfixOperator(org.matheclipse.parser.client.operator.InfixOperator)

Example 9 with PostfixOperator

use of org.matheclipse.parser.client.operator.PostfixOperator in project symja_android_library by axkr.

the class ComplexFormFactory method convertInternal.

private void convertInternal(final StringBuilder buf, final IExpr o, final int precedence, boolean isASTHead) {
    if (o instanceof IAST) {
        final IAST list = (IAST) o;
        if (list.head().isSymbol()) {
            ISymbol head = (ISymbol) list.head();
            final Operator operator = getOperator(head);
            if (operator != null) {
                if (operator instanceof PostfixOperator) {
                    if (list.isAST1()) {
                        convertPostfixOperator(buf, list, (PostfixOperator) operator, precedence);
                        return;
                    }
                } else {
                    if (convertOperator(operator, list, buf, isASTHead ? Integer.MAX_VALUE : precedence, head)) {
                        return;
                    }
                }
            }
        }
        convertAST(buf, list);
        return;
    }
    if (o instanceof ISignedNumber) {
        double d = o.evalDouble();
        if (fPackagePrefix) {
            buf.append("org.hipparchus.complex.");
        }
        buf.append("Complex.valueOf(" + d + ")");
        return;
    }
    if (o instanceof INumber) {
        Complex c = o.evalComplex();
        if (c != null) {
            if (fPackagePrefix) {
                buf.append("org.hipparchus.complex.");
            }
            buf.append("Complex.valueOf(" + c.getReal() + ", " + c.getImaginary() + ")");
        } else {
            buf.append("Complex.valueOf(" + o.toString() + ")");
        }
        return;
    }
    if (o instanceof ISymbol) {
        convertSymbol(buf, (ISymbol) o);
        return;
    }
    if (o instanceof IPatternObject) {
        convertPattern(buf, (IPatternObject) o);
        return;
    }
    convertString(buf, o.toString());
}
Also used : PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator) Operator(org.matheclipse.parser.client.operator.Operator) InfixOperator(org.matheclipse.parser.client.operator.InfixOperator) PrefixOperator(org.matheclipse.parser.client.operator.PrefixOperator) ISymbol(org.matheclipse.core.interfaces.ISymbol) PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator) ISignedNumber(org.matheclipse.core.interfaces.ISignedNumber) INumber(org.matheclipse.core.interfaces.INumber) IPatternObject(org.matheclipse.core.interfaces.IPatternObject) IAST(org.matheclipse.core.interfaces.IAST) Complex(org.hipparchus.complex.Complex)

Example 10 with PostfixOperator

use of org.matheclipse.parser.client.operator.PostfixOperator in project symja_android_library by axkr.

the class OutputFormFactory method convert.

private void convert(final Appendable buf, final IExpr o, final int precedence, boolean isASTHead) throws IOException {
    if (o instanceof IAST) {
        final IAST list = (IAST) o;
        if (!list.isPresent()) {
            append(buf, "NIL");
            return;
        }
        if (o.isDataset()) {
            // TODO improve output
            buf.append(o.toString());
            return;
        } else if (o.isAssociation()) {
            convertAssociation(buf, (IAssociation) o);
            return;
        } else if (o.isAST(S.Association, 1)) {
            buf.append("<||>");
            return;
        }
        IExpr header = list.head();
        if (!header.isSymbol()) {
            // print expressions like: f(#1, y)& [x]
            IAST[] derivStruct = list.isDerivativeAST1();
            if (derivStruct != null) {
                IAST a1Head = derivStruct[0];
                IAST headAST = derivStruct[1];
                if (a1Head.isAST1() && a1Head.arg1().isInteger() && headAST.isAST1() && (headAST.arg1().isSymbol() || headAST.arg1().isAST()) && derivStruct[2] != null) {
                    try {
                        int n = ((IInteger) a1Head.arg1()).toInt();
                        if (n == 1 || n == 2) {
                            IExpr symbolOrAST = headAST.arg1();
                            convert(buf, symbolOrAST, Integer.MIN_VALUE, false);
                            if (n == 1) {
                                append(buf, "'");
                            } else if (n == 2) {
                                append(buf, "''");
                            }
                            convertArgs(buf, symbolOrAST, list);
                            return;
                        }
                    } catch (ArithmeticException ae) {
                    }
                }
            }
            convert(buf, header, Integer.MIN_VALUE, true);
            // avoid fast StackOverflow
            append(buf, "[");
            for (int i = 1; i < list.size(); i++) {
                convert(buf, list.get(i), Integer.MIN_VALUE, false);
                if (i < list.argSize()) {
                    append(buf, ",");
                }
            }
            append(buf, "]");
            return;
        }
        if (header.isSymbol()) {
            ISymbol head = (ISymbol) header;
            int functionID = head.ordinal();
            if (functionID > ID.UNKNOWN) {
                switch(functionID) {
                    case ID.TwoWayRule:
                    case ID.UndirectedEdge:
                        if (list.isAST2()) {
                            convert(buf, list.arg1(), Integer.MIN_VALUE, false);
                            buf.append("<->");
                            convert(buf, list.arg2(), Integer.MIN_VALUE, false);
                            return;
                        }
                        break;
                    case ID.DirectedEdge:
                        if (list.isAST2()) {
                            convert(buf, list.arg1(), Integer.MIN_VALUE, false);
                            buf.append("->");
                            convert(buf, list.arg2(), Integer.MIN_VALUE, false);
                            return;
                        }
                        break;
                }
            }
            final Operator operator = getOperator(head);
            if (operator != null) {
                if (operator instanceof PostfixOperator) {
                    if (list.isAST1()) {
                        convertPostfixOperator(buf, list, (PostfixOperator) operator, precedence);
                        return;
                    }
                } else {
                    if (convertOperator(operator, list, buf, isASTHead ? Integer.MAX_VALUE : precedence, head)) {
                        return;
                    }
                }
            }
            if (functionID > ID.UNKNOWN) {
                switch(functionID) {
                    case ID.Inequality:
                        if (list.size() > 3 && convertInequality(buf, list, precedence)) {
                            return;
                        }
                        break;
                    case ID.Quantity:
                        // if (head.equals(F.SeriesData) && (list.size() == 7)) {
                        if (list instanceof IQuantity) {
                            if (convertQuantityData(buf, (IQuantity) list, precedence)) {
                                return;
                            }
                        }
                        break;
                    case ID.SeriesData:
                        // if (head.equals(F.SeriesData) && (list.size() == 7)) {
                        if (list instanceof ASTSeriesData) {
                            if (convertSeriesData(buf, (ASTSeriesData) list, precedence)) {
                                return;
                            }
                        }
                        break;
                    case ID.SparseArray:
                        if (list.isSparseArray()) {
                            buf.append(list.toString());
                            return;
                        }
                        break;
                    case ID.Parenthesis:
                        convertArgs(buf, S.Parenthesis, list);
                        return;
                    case ID.List:
                        convertList(buf, list, false);
                        return;
                    case ID.MatrixForm:
                        if (list.isASTOrAssociation() && list.size() > 1) {
                            // see also MatrixForm in MathML or TeX format for "graphical representation".
                            IExpr normal = list.arg1().normal(false);
                            if (normal.isList()) {
                                // && normal.isMatrix() != null) {
                                IntList dims = LinearAlgebra.dimensions((IAST) normal, S.List);
                                convertList(buf, (IAST) normal, dims.size() >= 2);
                                return;
                            }
                            convert(buf, normal, Integer.MIN_VALUE, false);
                            return;
                        }
                        break;
                    case ID.Out:
                        if (list.isAST1() && list.arg1().isInteger()) {
                            int lineNumber = list.arg1().toIntDefault();
                            if (lineNumber == -1) {
                                buf.append("%");
                                return;
                            } else if (lineNumber == -2) {
                                buf.append("%%");
                                return;
                            }
                        }
                        break;
                    case ID.Part:
                        if (list.size() >= 3) {
                            convertPart(buf, list);
                            return;
                        }
                        break;
                    case ID.Slot:
                        if (list.isAST1() && list.arg1().isInteger()) {
                            convertSlot(buf, list);
                            return;
                        }
                        break;
                    case ID.SlotSequence:
                        if (list.isAST1() && list.arg1().isInteger()) {
                            convertSlotSequence(buf, list);
                            return;
                        }
                        break;
                    case ID.Defer:
                    case ID.HoldForm:
                        if (list.isAST1()) {
                            convert(buf, list.arg1(), Integer.MIN_VALUE, false);
                            return;
                        }
                        break;
                    case ID.DirectedInfinity:
                        if (list.isDirectedInfinity()) {
                            // head.equals(F.DirectedInfinity))
                            if (list.isAST0()) {
                                append(buf, "ComplexInfinity");
                                return;
                            }
                            if (list.isAST1()) {
                                if (list.arg1().isOne()) {
                                    append(buf, "Infinity");
                                    return;
                                } else if (list.arg1().isMinusOne()) {
                                    if (Precedence.PLUS < precedence) {
                                        append(buf, "(");
                                    }
                                    append(buf, "-Infinity");
                                    if (Precedence.PLUS < precedence) {
                                        append(buf, ")");
                                    }
                                    return;
                                } else if (list.arg1().isImaginaryUnit()) {
                                    append(buf, "I*Infinity");
                                    return;
                                } else if (list.arg1().isNegativeImaginaryUnit()) {
                                    append(buf, "-I*Infinity");
                                    return;
                                }
                            }
                        }
                        break;
                    case ID.Optional:
                        if (list.isAST2() && (list.arg1().isBlank() || list.arg1().isPattern())) {
                            convert(buf, list.arg1(), Integer.MIN_VALUE, false);
                            buf.append(":");
                            convert(buf, list.arg2(), Integer.MIN_VALUE, false);
                            return;
                        }
                        break;
                    case ID.Complex:
                        if (list.isAST2()) {
                            // used for visual comparison of steps
                            boolean isZeroRealPart = list.arg1().isZero();
                            final int prec = isZeroRealPart ? Precedence.TIMES : Precedence.PLUS;
                            if (prec < precedence) {
                                append(buf, "(");
                            }
                            if (isZeroRealPart) {
                                buf.append("I*");
                                convert(buf, list.arg2(), Precedence.TIMES, false);
                            } else {
                                convert(buf, list.arg1(), Precedence.PLUS, false);
                                buf.append("+I*");
                                convert(buf, list.arg2(), Precedence.TIMES, false);
                            }
                            if (prec < precedence) {
                                append(buf, ")");
                            }
                            return;
                        }
                        break;
                    case ID.Rational:
                        if (list.isAST2()) {
                            // used for visual comparison of steps
                            IExpr numerator = list.arg1();
                            final boolean isNegative = numerator.isNegative();
                            final int prec = isNegative ? Precedence.PLUS : Precedence.TIMES;
                            if (prec < precedence) {
                                append(buf, "(");
                            }
                            convert(buf, list.arg1(), Precedence.DIVIDE, false);
                            buf.append("/");
                            convert(buf, list.arg2(), Precedence.DIVIDE, false);
                            if (prec < precedence) {
                                append(buf, ")");
                            }
                            return;
                        }
                        break;
                }
            } else {
                if (list instanceof ASTRealVector || list instanceof ASTRealMatrix) {
                    convertList(buf, list, false);
                    return;
                }
            }
        }
        convertAST(buf, list);
    } else if (o instanceof ISignedNumber) {
        convertNumber(buf, (ISignedNumber) o, precedence, NO_PLUS_CALL);
    } else if (o instanceof IComplexNum) {
        convertDoubleComplex(buf, (IComplexNum) o, precedence, NO_PLUS_CALL);
    } else if (o instanceof IComplex) {
        convertComplex(buf, (IComplex) o, precedence, NO_PLUS_CALL);
    } else if (o instanceof ISymbol) {
        convertSymbol(buf, (ISymbol) o);
    } else if (o instanceof IPatternObject) {
        convertPattern(buf, (IPatternObject) o);
    } else if (o instanceof IStringX) {
        convertString(buf, ((IStringX) o).toString());
    } else {
        convertString(buf, o.toString());
    }
}
Also used : PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator) Operator(org.matheclipse.parser.client.operator.Operator) InfixOperator(org.matheclipse.parser.client.operator.InfixOperator) PrefixOperator(org.matheclipse.parser.client.operator.PrefixOperator) IAssociation(org.matheclipse.core.interfaces.IAssociation) ISymbol(org.matheclipse.core.interfaces.ISymbol) IPatternObject(org.matheclipse.core.interfaces.IPatternObject) IntList(it.unimi.dsi.fastutil.ints.IntList) IQuantity(org.matheclipse.core.tensor.qty.IQuantity) ASTRealMatrix(org.matheclipse.core.expression.ASTRealMatrix) IComplex(org.matheclipse.core.interfaces.IComplex) PostfixOperator(org.matheclipse.parser.client.operator.PostfixOperator) ISignedNumber(org.matheclipse.core.interfaces.ISignedNumber) IInteger(org.matheclipse.core.interfaces.IInteger) IComplexNum(org.matheclipse.core.interfaces.IComplexNum) ASTSeriesData(org.matheclipse.core.expression.ASTSeriesData) IAST(org.matheclipse.core.interfaces.IAST) IExpr(org.matheclipse.core.interfaces.IExpr) IStringX(org.matheclipse.core.interfaces.IStringX) ASTRealVector(org.matheclipse.core.expression.ASTRealVector)

Aggregations

PostfixOperator (org.matheclipse.parser.client.operator.PostfixOperator)13 InfixOperator (org.matheclipse.parser.client.operator.InfixOperator)12 PrefixOperator (org.matheclipse.parser.client.operator.PrefixOperator)11 Operator (org.matheclipse.parser.client.operator.Operator)7 IAST (org.matheclipse.core.interfaces.IAST)4 ISymbol (org.matheclipse.core.interfaces.ISymbol)4 IExpr (org.matheclipse.core.interfaces.IExpr)3 IPatternObject (org.matheclipse.core.interfaces.IPatternObject)3 ISignedNumber (org.matheclipse.core.interfaces.ISignedNumber)3 ASTRealMatrix (org.matheclipse.core.expression.ASTRealMatrix)2 ASTRealVector (org.matheclipse.core.expression.ASTRealVector)2 ASTSeriesData (org.matheclipse.core.expression.ASTSeriesData)2 IComplex (org.matheclipse.core.interfaces.IComplex)2 IComplexNum (org.matheclipse.core.interfaces.IComplexNum)2 IInteger (org.matheclipse.core.interfaces.IInteger)2 ASTNode (org.matheclipse.parser.client.ast.ASTNode)2 IntList (it.unimi.dsi.fastutil.ints.IntList)1 Complex (org.hipparchus.complex.Complex)1 IAssociation (org.matheclipse.core.interfaces.IAssociation)1 INumber (org.matheclipse.core.interfaces.INumber)1