private bool TryNumber(char lastChar)
        {
            bool isNumber = NumberExpression.IsNumber(_currentChar);
            // only negative when last char is group start or symbol
            bool isNegative = NumberExpression.IsNegativeSign(_currentChar) &&
                              (lastChar == '\0' || OperatorExpression.IsSymbol(lastChar));

            if (!isNumber && !isNegative)
            {
                return(false);
            }

            _buffer.Length = 0;
            _buffer.Append(_currentChar);

            char p = (char)_expressionReader.Peek();

            while (NumberExpression.IsNumber(p))
            {
                _currentChar = (char)_expressionReader.Read();
                _buffer.Append(_currentChar);
                p = (char)_expressionReader.Peek();
            }

            if (!(double.TryParse(_buffer.ToString(), out double value)))
            {
                throw new ParseException(Resources.InvalidNumberFormat + _buffer);
            }

            NumberExpression expression = new NumberExpression(value);

            _expressionQueue.Enqueue(expression);

            return(true);
        }
        private IExpression GetExpressionFromSymbol(string p)
        {
            IExpression e;

            if (_expressionCache.ContainsKey(p))
            {
                e = _expressionCache[p];
            }
            else if (OperatorExpression.IsSymbol(Convert.ToChar(p)))
            {
                e = new OperatorExpression(p);
                _expressionCache.Add(p, e);
            }
            else
            {
                throw new ParseException(Resources.InvalidSymbolOnStack + p);
            }

            return(e);
        }
        private bool TryOperator()
        {
            if (!OperatorExpression.IsSymbol(_currentChar))
            {
                return(false);
            }

            bool   repeat;
            string s = _currentChar.ToString();

            do
            {
                string p = _symbolStack.Count == 0 ? string.Empty : _symbolStack.Peek();
                repeat = false;
                if (_symbolStack.Count == 0)
                {
                    _symbolStack.Push(s);
                }
                else if (p == "(")
                {
                    _symbolStack.Push(s);
                }
                else if (Precedence(s) > Precedence(p))
                {
                    _symbolStack.Push(s);
                }
                else
                {
                    IExpression e = GetExpressionFromSymbol(_symbolStack.Pop());
                    _expressionQueue.Enqueue(e);
                    repeat = true;
                }
            } while (repeat);

            return(true);
        }