Arithmetica.Tokenization.Rewriting.ShuntingYardRewriter.Rewrite C# (CSharp) Метод

Rewrite() публичный Метод

public Rewrite ( TokenStream tokens ) : TokenStream
tokens TokenStream
Результат TokenStream
        public override TokenStream Rewrite(TokenStream tokens)
        {
            // Token stream needs to be in infix notation.
            if (tokens.Notation != TokenNotation.Infix)
            {
                throw new MathExpressionException("Token stream is not in infix notation.");
            }

            Queue<Token> output = new Queue<Token>();
            Stack<Token> stack = new Stack<Token>();

            foreach (Token token in tokens)
            {
                if (token.IsOperand())
                {
                    output.Enqueue(token);
                }
                else if (token.Type == TokenType.Function)
                {
                    stack.Push(token);
                }
                else if (token.Type == TokenType.Separator)
                {
                    while (stack.Count > 0)
                    {
                        // Did we encounter a left parenthesis?
                        if (stack.Peek().Type == TokenType.OpeningParenthesis)
                        {
                            break;
                        }
                        output.Enqueue(stack.Pop());
                    }
                    Debug.Assert(stack.Count != 0, "Left parenthesis is missing from function!");
                }
                else if (token.IsOperator())
                {
                    while (stack.Count > 0)
                    {
                        // Current operator is left asociative and has a precedence less or equal than the operator on the stack,
                        // OR the current operator right associative and has a precedence less than the operator on the stack.
                        // This expression should be cleaned up for readability...
                        bool cond1 = stack.Peek().IsOperator() && token.IsLeftAssociative() && token.GetPrecedence() <= stack.Peek().GetPrecedence();
                        bool cond2 = stack.Peek().IsOperator() && !token.IsLeftAssociative() && token.GetPrecedence() < stack.Peek().GetPrecedence();
                        if (cond1 || cond2)
                        {
                            output.Enqueue(stack.Pop());
                        }
                        else
                        {
                            break;
                        }
                    }
                    // Push the current operator onto the stack.
                    stack.Push(token);
                }
                else if (token.Type == TokenType.OpeningParenthesis)
                {
                    stack.Push(token);
                }
                else if (token.Type == TokenType.ClosingParenthesis)
                {
                    bool foundLeftParenthesis = false;
                    while (stack.Count > 0)
                    {
                        if (stack.Peek().Type == TokenType.OpeningParenthesis)
                        {
                            foundLeftParenthesis = true;
                            break;
                        }
                        output.Enqueue(stack.Pop());
                    }

                    if (!foundLeftParenthesis)
                    {
                        throw new MathExpressionException("Missing left parenthesis in expression.");
                    }

                    // Pop the left parenthesis from the stack.
                    stack.Pop();

                    if (stack.Count > 0)
                    {
                        // A function left on the stack?
                        if (stack.Peek().Type == TokenType.Function)
                        {
                            output.Enqueue(stack.Pop());
                        }
                    }
                }
            }

            // Pop all operators from the stack.
            while (stack.Count > 0)
            {
                if (stack.Peek().Type == TokenType.OpeningParenthesis)
                {
                    throw new MathExpressionException("Missing right parenthesis in expression.");
                }
                output.Enqueue(stack.Pop());
            }

            return new TokenStream(output.ToArray(), TokenNotation.Postfix);
        }
ShuntingYardRewriter