Exemplo n.º 1
0
        ExpressionizeResult CreateExpression(int basePrecedence)
        {
            Expression single = null;

            // Make an atom.
            ExpressionizeResult atomResult = CreateAtom();

            if (!atomResult.Success)
            {
                return(atomResult);
            }

            // Atomizing succeeded.
            single = atomResult.CalculatedExpression;

            while (true)
            {
                // After an atom might be an operator, an argument or another expression.

                // End of the token list.
                if (currentToken == null)
                {
                    break;
                }

                // Operator after an atom.
                if (TokenType.Operator.HasFlag(currentToken.Type))
                {
                    BinaryType binaryType = currentToken.Type.ToBinaryType();

                    int opPrecedence = binaryType.GetPrecedence();

                    if (opPrecedence < basePrecedence)
                    {
                        break;
                    }

                    int nextPrecedence = binaryType.IsLeftAssociative() ? (opPrecedence + 1) : opPrecedence;

                    GetNextToken();
                    ExpressionizeResult rightResult = CreateExpression(nextPrecedence);

                    if (!rightResult.Success)
                    {
                        return(rightResult);
                    }

                    Expression left  = single;
                    Expression right = rightResult.CalculatedExpression;

                    single = new BinaryExpression(left, right, binaryType);
                }
                else
                {
                    // Variable or left parenthesis after an atom,
                    // connect them with implied multiplication.
                    if (currentToken.Type == TokenType.Variable || currentToken.Type == TokenType.ParenLeft)
                    {
                        BinaryType binaryType = BinaryType.ImpliedMultiply;

                        int opPrecedence = binaryType.GetPrecedence();

                        if (opPrecedence < basePrecedence)
                        {
                            break;
                        }

                        int nextPrecedence = binaryType.IsLeftAssociative() ? (opPrecedence + 1) : opPrecedence;

                        // No need to consume the operator token.

                        ExpressionizeResult rightResult = CreateExpression(nextPrecedence);

                        if (!rightResult.Success)
                        {
                            return(rightResult);
                        }

                        Expression right = rightResult.CalculatedExpression;

                        single = new BinaryExpression(single, right, binaryType);
                    }
                    else
                    {
                        if (currentToken.Type == TokenType.Constant)
                        {
                            return(ExpressionizeResult.NewError(ErrorInfo.ExpectOperator));
                        }

                        // The current expression ends if we encounter anything else.
                        break;
                    }
                }
            }

            return(ExpressionizeResult.NewSuccess(single));
        }