Пример #1
0
        // Internal

        private void AddItem(ExpressionItem itm)
        {
            if (itm is Operand)
            {
                ++_validationCounter;
            }
            else if (itm is Operation)
            {
                if (itm.IsUnary)
                {
                    --_validationCounter;
                    if (_validationCounter < 0)
                    {
                        throw new InvalidExprException();
                    }
                    ++_validationCounter;
                }
                else
                {
                    _validationCounter -= 2;
                    if (_validationCounter < 0)
                    {
                        throw new InvalidExprException();
                    }
                    ++_validationCounter;
                }
            }

            _result.Add(itm);
        }
Пример #2
0
        private static Operation ReadOperator(StringReader reader, ExpressionItem prevItem)
        {
            char sign   = (char)reader.Read();
            var  result = Operation.BySign[sign];

            if (result == Operation.Substract)
            {
                if (prevItem is Divisor || prevItem == null)    // to use negation after operator brackets are necessary
                {
                    result = Operation.Negation;
                }
            }
            return(result);
        }
Пример #3
0
        /// <summary>
        /// Parse string expression to List of <code>ExpressionItems</code> in postfix notation.
        /// </summary>
        /// <returns>List of <code>ExpressionItems</code> in postfix notation</returns>
        /// <exception cref="InvalidExprException"></exception>
        /// <exception cref="InvalidBracketsException"></exception>
        public List <ExpressionItem> GetPostfixNotation()
        {
            _result = new List <ExpressionItem>();

            using (var reader = new StringReader(_expression))
            {
                int            peek;
                ExpressionItem previous = null;
                while ((peek = reader.Peek()) > -1)
                {
                    char next = (char)peek;

                    if (char.IsDigit(next))
                    {
                        if (previous is Operand)
                        {
                            throw new InvalidExprException("Unexpexted token.");
                        }

                        previous = ReadOperand(reader);
                        AddItem(previous);
                    }
                    else if (Operation.IsOperator(next))
                    {
                        var nextOp = ReadOperator(reader, previous);
                        while ((_evalStack.Count > 0) && (_evalStack.Peek().StackPriority > nextOp.Priority))
                        {
                            AddItem(_evalStack.Pop());
                        }
                        _evalStack.Push(nextOp);
                        previous = nextOp;
                    }
                    else if (Divisor.IsDivisor(next))
                    {
                        var bracket = ReadDivisor(reader);
                        previous = bracket;

                        if (bracket == Divisor.OpenBracket)
                        {
                            _evalStack.Push(bracket);
                        }
                        else if (bracket == Divisor.CloseBracket)
                        {
                            try
                            {
                                while (_evalStack.Peek() != Divisor.OpenBracket)
                                {
                                    AddItem(_evalStack.Pop());
                                }
                                _evalStack.Pop();
                            }
                            catch (InvalidOperationException)
                            {
                                throw new InvalidBracketsException();
                            }
                        }
                    }
                    else if (char.IsWhiteSpace(next))
                    {
                        reader.Read();
                    }
                    else
                    {
                        throw new InvalidExprException("Unknown symbols detected.");
                    }
                }

                while (_evalStack.Count > 0)
                {
                    var tmp = _evalStack.Pop();
                    if (!(tmp is Divisor))
                    {
                        AddItem(tmp);
                    }
                    else
                    {
                        throw new InvalidBracketsException();
                    }
                }

                if (_validationCounter != 1)
                {
                    throw new InvalidExprException();
                }

                return(_result);
            }
        }