protected override void ReadTree(string input, CompoundStack root, ref int currentIndex) { if (currentIndex >= input.Length) { return; } var currentChar = input[currentIndex]; currentIndex++; var nextChar = currentIndex < input.Length ? input[currentIndex] : char.Parse("@"); if (char.IsUpper(currentChar)) { if (char.IsLower(nextChar)) { ReadTree(input, root, ref currentIndex); return; } var numberOfAtoms = 1; if (nextChar == ')' && currentIndex + 1 < input.Length) { if (char.IsNumber(input[currentIndex + 1])) // We can have a number after closing bracket ') { currentIndex++; } else if (char.IsNumber(input[currentIndex + 2])) // We can have a number after line '|' which is after the closing bracket ') { currentIndex += 2; } numberOfAtoms = GetFullNumber(input, ref currentIndex); } var stack = new ElementStack(currentChar.ToString().ToElement(), numberOfAtoms); AddStackToRoot(root, stack); ReadTree(input, root, ref currentIndex); } else if (char.IsLower(currentChar)) { var numberOfAtoms = 1; var toMoveBack = 1; if ((nextChar == ')' || nextChar == '|') && currentIndex + 1 < input.Length) { if (char.IsNumber(input[currentIndex + 1])) // We can have a number after closing bracket ') { currentIndex++; toMoveBack = 3; } else if (char.IsNumber(input[currentIndex + 2])) // We can have a number after line '|' which is after the closing bracket ') { currentIndex += 2; toMoveBack = 4; } numberOfAtoms = GetFullNumber(input, ref currentIndex); } var previousChar = input[currentIndex - numberOfAtoms.ToString().Length - toMoveBack]; var stack = new ElementStack($"{ previousChar }{ currentChar }".ToElement(), numberOfAtoms); AddStackToRoot(root, stack); ReadTree(input, root, ref currentIndex); } else if (currentChar.Equals('(')) { var stack = new CompoundStack(); root.Nodes.Add(stack); InnerStacks.Push(stack); ReadTree(input, stack, ref currentIndex); ReadTree(input, InnerStacks.Peek(), ref currentIndex); } else if (currentChar.Equals(')')) { var numberOfAtoms = 1; if (char.IsNumber(nextChar)) { numberOfAtoms = GetFullNumber(input, ref currentIndex); } root.IncreaseStackSize(numberOfAtoms); InnerStacks.Pop(); } else if (currentChar == '-' || currentChar == '=') { // Possible format's of chars next to the '-' or '=' // Where: C - upper char; r - lower char; 0 - number; // C - ( // ) - C // C - C // ) - ( // 0 - ( // 0 - C // r - ( // For now on it will skip parsing the connections - not supported yet // There is no support (yet) of how to store the number of connections between atoms // This is something that will need to be added later on // TODO: Add support for storing the information about number of connections between atoms if (char.IsNumber(nextChar)) { while (input[currentIndex] != '|') { currentIndex++; } } ReadTree(input, root, ref currentIndex); } else if (currentChar == '|') { // Possible format's of chars next to the '|' // Where: C - upper char; r - lower char; 0 - number; // C | 0 // r | 0 // 0 | C // 0 | ( // For now on it will skip parsing the number of connections - not supported yet // There is no support (yet) of how to store the number of connections between atoms // This is something that will need to be added later on // TODO: Add support for storing the information about number of connections between atoms if (char.IsNumber(nextChar)) { while (input[currentIndex] != '|') { currentIndex++; } } ReadTree(input, root, ref currentIndex); } else { throw new FormatException($"Unknown char: '{ currentChar }', at position: { currentIndex }"); } }
protected override void ReadTree(string input, CompoundStack root, ref int currentIndex) { if (currentIndex >= input.Length) { return; } var currentChar = input[currentIndex]; currentIndex++; var nextChar = currentIndex < input.Length ? input[currentIndex] : char.Parse("@"); if (char.IsUpper(currentChar)) { if (char.IsLower(nextChar)) { ReadTree(input, root, ref currentIndex); return; } var numberOfAtoms = 1; if (char.IsNumber(nextChar)) { numberOfAtoms = GetFullNumber(input, ref currentIndex); } var stack = new ElementStack(currentChar.ToString().ToElement(), numberOfAtoms); root.Nodes.Add(stack); ReadTree(input, root, ref currentIndex); } else if (currentChar.Equals('(')) { var stack = new CompoundStack(); root.Nodes.Add(stack); InnerStacks.Push(stack); ReadTree(input, stack, ref currentIndex); ReadTree(input, InnerStacks.Peek(), ref currentIndex); } else if (currentChar.Equals(')')) { var numberOfAtoms = 1; if (char.IsNumber(nextChar)) { numberOfAtoms = GetFullNumber(input, ref currentIndex); } root.IncreaseStackSize(numberOfAtoms); InnerStacks.Pop(); } else if (char.IsLower(currentChar)) { var numberOfAtoms = 1; if (char.IsNumber(nextChar)) { numberOfAtoms = GetFullNumber(input, ref currentIndex); } var previousChar = GetPreviousUpperChar(input, currentIndex, numberOfAtoms); var stack = new ElementStack($"{ previousChar }{ currentChar }".ToElement(), numberOfAtoms); root.Nodes.Add(stack); ReadTree(input, root, ref currentIndex); } else if (char.IsNumber(currentChar) && currentIndex < 2) // Only for the number before the compound { currentIndex = 0; var numberOfMoles = GetFullNumber(input, ref currentIndex); if (input[currentIndex] == '(') { currentIndex++; numberOfMoles--; } root.Count = numberOfMoles; ReadTree(input, root, ref currentIndex); } else { throw new FormatException($"Unknown char: '{ currentChar }', at position: { currentIndex }"); } }