/// <summary>
        /// Read open bracket
        /// </summary>
        public static bool TryProceedOpenBracket(List <BaseFormulaNode> nodes, ReadOnlySpan <char> formula, BracketCounters negativeBracketCounters, ref int index)
        {
            // Read unary minus
            var localIndex = UnaryMinusReader.ReadUnaryMinus(nodes, formula, index, out var isNegativeLocal);

            // Check out of range
            if (localIndex >= formula.Length)
            {
                return(false);
            }

            // Check open bracket
            if (formula[localIndex] == OPEN_BRACKET_CHAR)
            {
                if (isNegativeLocal)
                {
                    AddAdditionalNodesForUnaryMinus(nodes);
                }

                // Add bracket
                var bracket = AddOpenBracket(nodes);

                // Is unary minus
                if (isNegativeLocal)
                {
                    negativeBracketCounters.CreateNewCounter();
                }
                else
                {
                    negativeBracketCounters.Proceed(bracket);
                }

                index = localIndex;
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Read close bracket
        /// </summary>
        public static bool TryProceedCloseBracket(List <BaseFormulaNode> nodes, ReadOnlySpan <char> formula, BracketCounters negativeBracketCounters, ref int index)
        {
            if (formula[index] != CLOSE_BRACKET_CHAR)
            {
                return(false);
            }

            // Add bracket
            var bracket = AddCloseBracket(nodes);

            // If there is unary minus, we must add close bracket
            if (negativeBracketCounters.Proceed(bracket))
            {
                AddCloseBracket(nodes);
            }

            return(true);
        }
        /// <summary>
        /// Return parsed formula nodes without RPN
        /// </summary>
        public List <BaseFormulaNode> ParseWithoutRpn(ReadOnlySpan <char> formula)
        {
            var negativeBracketCounters = new BracketCounters();
            var nodes = new List <BaseFormulaNode>();

            for (int i = 0; i < formula.Length; i++)
            {
                var ch = formula[i];

                if (ch.IsWhiteSpace())
                {
                    continue;
                }

                if (FunctionCharReader.TryProceedFunctionChar(nodes, ch))
                {
                    continue;
                }

                if (BracketReader.TryProceedOpenBracket(nodes, formula, negativeBracketCounters, ref i))
                {
                    continue;
                }

                if (BracketReader.TryProceedCloseBracket(nodes, formula, negativeBracketCounters, ref i))
                {
                    continue;
                }

                if (VariableReader.TryProceedBorderedVariable(nodes, formula, ref i))
                {
                    continue;
                }

                if (NumberReader.TryProceedNumber(nodes, formula, ref i))
                {
                    continue;
                }

                if (FunctionsReader.TryProceedFunction(nodes, formula, ref i))
                {
                    continue;
                }

                if (VariableReader.TryProceedSimpleVariable(nodes, formula, ref i))
                {
                    continue;
                }

                if (WordReader.TryProceedWord(nodes, formula, ref i))
                {
                    continue;
                }

                if (ListReader.TryProceedList(nodes, formula, ref i))
                {
                    continue;
                }

                if (OperatorReader.TryProceedOperator(nodes, formula, ref i))
                {
                    continue;
                }
            }

            return(nodes);
        }