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