예제 #1
0
        /// <summary>
        /// Parses the specified string to a sequence of cells
        /// that may contain a number or symbols or arithmetic operation.
        /// </summary>
        public InputCell[] Parse(string input)
        {
            var result       = new LinkedList <InputCell>();
            var numberBuffer = new NumberBuilder();

            foreach (char ch in input)
            {
                if (ch.IsEmpty())
                {
                    continue;
                }

                if (ch.IsDigit() || ch.IsDot())
                {
                    numberBuffer.Append(ch);
                    continue;
                }

                result.AddIfNotNull(CreateCell(numberBuffer));

                if (ch.IsMinus() && IsMinusForNumber(result))
                {
                    numberBuffer.Append(ch);
                    continue;
                }

                result.AddLast(InputCell.Symbol(ch));
            }
            result.AddIfNotNull(CreateCell(numberBuffer));
            return(result.ToArray());
        }
예제 #2
0
 private static void PurgeTopStack(Stack <InputCell> stack,
                                   LinkedList <InputCell> output, InputCell element)
 {
     while (stack.Count > 0 && element.Weight <= stack.Peek().Weight)
     {
         output.AddLast(stack.Pop());
     }
     stack.Push(element);
 }
예제 #3
0
        public static InputCell CreateCell(NumberBuilder builder)
        {
            if (builder.IsEmpty())
            {
                return(null);
            }
            double number = builder.Build();

            builder.Clear();
            return(InputCell.Number(number));
        }
예제 #4
0
        /// <summary>
        /// Counts a result of expression that is represented as a sequence of input cells
        /// ordered according the order of the Reverse Polish notation (RPN).
        /// </summary>
        public double Count(InputCell[] input)
        {
            var stack = new Stack <InputCell>();

            foreach (var cell in input)
            {
                if (cell.IsNumber())
                {
                    stack.Push(cell);
                }
                else if (cell.IsOperation())
                {
                    var operandRight = GetOperand(stack);
                    var operandLeft  = GetOperand(stack);
                    var operation    = cell.Expr(operandLeft, operandRight);

                    var result = InvokeExpession(operation);

                    stack.Push(InputCell.Number(result));
                }
            }
            return((double)stack.Peek().Value);
        }
예제 #5
0
 private static Expression GetOperand(Stack <InputCell> stack)
 {
     return(stack.PopOrValue(InputCell.Number(0)).Expr.Invoke(null, null));
 }
예제 #6
0
        private static bool IsMinusForNumber(IEnumerable <InputCell> cells)
        {
            InputCell lastCell = cells.LastOrDefault();

            return(lastCell == null || lastCell.IsOperation() || lastCell.IsOpenBracket());
        }