// 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); }
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); }
/// <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); } }