예제 #1
0
        internal void ApplyToken(ExpressionToken token)
        {
            if (token.IsRightParen && _lastWasFunction)
            {
                _functionStack.Peek().NumTerms = 0;
            }

            _lastWasFunction = false;

            if (token.IsFunction)
            {
                _functionStack.Push(token);

                _lastWasFunction = true;

                token.NumTerms = 1;
            }

            if (token.IsLeftParen)
            {
                if (!_lastWasOperator)
                {
                    ExpressionToken callToken = new FunctionCallToken(token.Text, _functionEvaluator, token.TokenPosition);

                    ApplyToken(callToken);
                }

                _operatorStack.Push(token);

                _lastWasOperator = true;

                return;
            }

            if (token.IsTerm)
            {
                _tokenQueue.Enqueue(token);

                _lastWasOperator = false;

                return;
            }

            if (token.IsArgumentSeparator)
            {
                while (_operatorStack.Count > 0 && !_operatorStack.Peek().IsLeftParen)
                {
                    _tokenQueue.Enqueue(_operatorStack.Pop());
                }

                _functionStack.Peek().NumTerms++;

                _lastWasOperator = true;

                return;
            }

            if (token.IsRightParen)
            {
                while (_operatorStack.Count > 0)
                {
                    ExpressionToken stackOperator = _operatorStack.Pop();

                    if (stackOperator.IsLeftParen)
                    {
                        if (_operatorStack.Count > 0 && _operatorStack.Peek().IsFunction)
                        {
                            _tokenQueue.Enqueue(_operatorStack.Pop());

                            _functionStack.Pop();
                        }

                        break;
                    }

                    _tokenQueue.Enqueue(stackOperator);
                }

                _lastWasOperator = false;

                return;
            }

            if (_lastWasOperator != token.IsUnary)
            {
                if (token.Alternate != null)
                {
                    ApplyToken(token.Alternate);
                    return;
                }

                throw new LexerException("Misplaced operator " + token.Text, token.TokenPosition, token.Text);
            }

            // When we get here, it certainly is an operator or function call

            while (_operatorStack.Count > 0)
            {
                ExpressionToken stackOperator = _operatorStack.Peek();

                if ((token.Associativity == OperatorAssociativity.Right && token.Precedence < stackOperator.Precedence) ||
                    (token.Associativity == OperatorAssociativity.Left && token.Precedence <= stackOperator.Precedence))
                {
                    _tokenQueue.Enqueue(_operatorStack.Pop());
                }
                else
                {
                    break;
                }
            }

            _operatorStack.Push(token);

            _lastWasOperator = true;
        }