コード例 #1
0
        public Operation Build(IList <Token> tokens)
        {
            resultStack.Clear();
            operatorStack.Clear();

            foreach (Token token in tokens)
            {
                object value = token.Value;

                switch (token.TokenType)
                {
                case TokenType.Integer:
                    resultStack.Push(new IntegerConstant((int)token.Value));
                    break;

                case TokenType.FloatingPoint:
                    resultStack.Push(new FloatingPointConstant((double)token.Value));
                    break;

                case TokenType.Text:
                    if (EngineUtil.IsFunctionName((string)token.Value))
                    {
                        operatorStack.Push(token);
                    }
                    else
                    {
                        resultStack.Push(new Variable((string)token.Value));
                    }
                    break;

                case TokenType.LeftBracket:
                    operatorStack.Push(token);
                    break;

                case TokenType.RightBracket:
                    PopOperations(true, token);
                    break;

                case TokenType.Operation:
                    Token operation1Token = token;
                    char  operation1      = (char)operation1Token.Value;

                    if (operatorStack.Count == 0)
                    {
                        operatorStack.Push(operation1Token);
                    }
                    else
                    {
                        Token operation2Token        = operatorStack.Peek();
                        bool  isFunctionOnTopOfStack = operation2Token.TokenType == TokenType.Text;

                        if (!isFunctionOnTopOfStack)
                        {
                            char operation2 = (char)operation2Token.Value;

                            if ((IsLeftAssociativeOperation(operation1) && operationPrecedence[operation1] <= operationPrecedence[operation2]) ||
                                (operationPrecedence[operation1] < operationPrecedence[operation2]))
                            {
                                operatorStack.Pop();
                                operatorStack.Push(operation1Token);
                                resultStack.Push(ConvertOperation(operation2Token));
                            }
                            else
                            {
                                operatorStack.Push(operation1Token);
                            }
                        }
                        else
                        {
                            operatorStack.Pop();
                            operatorStack.Push(operation1Token);
                            resultStack.Push(ConvertFunction(operation2Token));
                        }
                    }

                    break;
                }
            }

            PopOperations(false, null);

            VerifyResultStack();

            return(resultStack.First());
        }