List <Token> tokens = new List <Token>();//список усіх токенів internal bool ParseTokens(string Code, bool display_out, bool inRecursion, bool Body) { try { bool performed = false; int CheckIfClosed = 0; //індекс } тіла checkIf bool ResultPredicate = false; //результат умови checkIf(___) while (Code.Length > 0) //допоки є текст { var code_length = Code.Length; var current_char = Code.ElementAt(0); bool next_bracket = false, again = false; switch (current_char) { case ' ': Code = Code.Remove(0, 1); continue; case '\n': { Code = Code.Remove(0, 1); outputTextBox.Text += '\n'; } continue; case '}': tokens.Add(new Token(Code.ElementAt(0).ToString(CultureInfo.InvariantCulture), Types.Braces, outputTextBox, display_out)); Code = Code.Remove(0, 1); continue; case '{': tokens.Add(new Token(Code.ElementAt(0).ToString(CultureInfo.InvariantCulture), Types.Braces, outputTextBox, display_out)); Code = Code.Remove(0, 1); continue; case '.': tokens.Add(new Token(Code.ElementAt(0).ToString(CultureInfo.InvariantCulture), Types.Dot, outputTextBox, display_out)); Code = Code.Remove(0, 1); continue; case ',': tokens.Add(new Token(Code.ElementAt(0).ToString(CultureInfo.InvariantCulture), Types.Comma, outputTextBox, display_out)); Code = Code.Remove(0, 1); continue; case '(': int index_close_parenthesis = 0, x; var parameters = ""; if (Code.Length > 1) { if (!Code.ElementAt(1).Equals(')')) { int opened_parenthesis = 1, opened = 0, closed = 0; while (!Code.ElementAt(closed).Equals(")") && opened_parenthesis != 0) { if (Code.Length > closed) { if (opened_parenthesis > 0) { if (!Code.ElementAt(closed + 1).Equals(')')) { closed = Code.IndexOf(")", closed + 1); } else { closed++; } opened_parenthesis--; } else { break; } if (!Code.ElementAt(opened + 1).Equals('(')) { opened = Code.IndexOf("(", opened + 1); } else { opened++; } if (opened < closed && opened != -1) { opened_parenthesis++; } if (closed == -1) { throw new Exception("Error.Check () after function. ) is missing"); } } else { throw new Exception("Error. ')' is missing. Check this and try again"); } } index_close_parenthesis = closed; if (index_close_parenthesis != 1) { parameters = Code.Substring(1, index_close_parenthesis - 1); } } else { index_close_parenthesis = 1; } } else { throw new Exception("Error. ) is missing!"); } tokens.Add(new Token(Code.ElementAt(0).ToString(CultureInfo.InvariantCulture), Types.Parentheses, outputTextBox, display_out)); if (parameters != "") { ParseTokens(parameters, true, true, false); // розбити на токени те, що в дужках } tokens.Add(new Token(Code.ElementAt(index_close_parenthesis).ToString(CultureInfo.InvariantCulture), Types.Parentheses, outputTextBox, display_out)); Code = Code.Remove(0, index_close_parenthesis + 1); continue; case '"': if (Code.Length > 1) { int index_close_quote = Code.IndexOf('"', 1); if (index_close_quote == -1) { throw new Exception("Error. \" is missing!"); } tokens.Add(new Token(Code.ElementAt(0).ToString(CultureInfo.InvariantCulture), Types.Quotes, outputTextBox, display_out)); tokens.Add(new Token(Code.Substring(1, index_close_quote - 1), Types.Value, outputTextBox, display_out)); tokens.Add(new Token(Code.ElementAt(index_close_quote).ToString(CultureInfo.InvariantCulture), Types.Quotes, outputTextBox, display_out)); Code = Code.Remove(0, index_close_quote + 1); } else { throw new Exception("Error. \" is missing!"); } continue; case '[': if (Code.Length > 1) { var index_close_bracket = Code.IndexOf(']', 1); if (index_close_bracket == -1) { throw new Exception("Error. ] is missing!"); } var param = Code.Substring(1, index_close_bracket - 1); tokens.Add(new Token(Code[0].ToString(CultureInfo.InvariantCulture), Types.Brackets, outputTextBox, display_out)); //tokens.Add(new Token(param.ToString(CultureInfo.InvariantCulture),Types.Param, outputTextBox)); ParseTokens(param, true, true, false); // розбити на токени те, що в дужках tokens.Add(new Token(Code[index_close_bracket].ToString(CultureInfo.InvariantCulture), Types.Brackets, outputTextBox, display_out)); Code = Code.Remove(0, index_close_bracket + 1); } else { throw new Exception("Error. ] is missing!"); } continue; case '/': { if (Code[1].Equals('/')) { Code = Code.Remove(0, Code.IndexOf('\n')); continue; } if (Code[1].Equals('*')) { Code = Code.Remove(0, Code.IndexOf("*/", StringComparison.Ordinal) + 2); continue; } } break; case ';'://віддаємо команду на виконання { tokens.Add(new Token(Code.ElementAt(0).ToString(CultureInfo.InvariantCulture), Types.Semicolon, outputTextBox, display_out)); Code = Code.Remove(0, 1); performed = MyTree.CreateTree(tokens, 0, tokens.Count, false); tokens.Clear(); //очищуємо токени if (performed) { performed = false; } } continue; } foreach (var type in MyTree.DataTypes) //тип даних та змінна { if ((Code.IndexOf(type, StringComparison.Ordinal) == 0 && Code[type.Length] == ' ')) { Code = Code.Remove(0, type.Length + 1);//видаляємо тип List <int> pos_chars = new List <int> { Code.IndexOf(":=", StringComparison.Ordinal), Code.IndexOf(" ", StringComparison.Ordinal), Code.IndexOf(";", StringComparison.Ordinal) }; string VarName = Code.Substring(0, pos_chars.Where(p => p > 0).Min()); //кінець назви змінної tokens.Add(new Token(VarName, Types.Var, outputTextBox, display_out)); //додаємо назву змінної try { Trees.Variables.Add(VarName, new VarInfo(type, null)); //додаємо нову змінну до загального списку } catch (Exception e) { throw new Exception("Error. Variable with name " + VarName + " was already added!"); } Grid.Rows.Add(Trees.Variables.Last().Key, Trees.Variables.Last().Value.Type, "null"); Code = Code.Remove(0, VarName.Length); again = true; break; } } if (again) { continue; } foreach (var operation in Operations)//обробка операцій { if (Code.IndexOf(operation, StringComparison.Ordinal) == 0) { tokens.Add(new Token(operation.ToString(CultureInfo.InvariantCulture), Types.Operation, outputTextBox, display_out)); Code = Code.Remove(0, operation.Length); again = true; break; } } if (again) { continue; } foreach (var method in MyTree.Methods.Keys)//Методи { if (Code.IndexOf(method, StringComparison.Ordinal) == 0) { tokens.Add(new Token(method.ToString(CultureInfo.InvariantCulture), Types.Method, outputTextBox, display_out)); Code = Code.Remove(0, method.Length); next_bracket = true; again = true; break; } } if (again || next_bracket) { continue; //якщо наступними мають бути дужки } int index; foreach (var oper in Operators) //оператори (цикл і умова) ДОРОБИТИ { if (Code.IndexOf(oper, StringComparison.Ordinal) == 0) { tokens.Add(new Token(oper.ToString(CultureInfo.InvariantCulture), Types.Operator, outputTextBox, display_out)); Code = Code.Remove(0, oper.Length); index = 0; if (tokens[0].value.Equals("}")) { index = 1; } switch ((string)tokens[index].value) { case "checkIf": //оператор умови { if (Code.Length > 1) { if (Code.IndexOf('{', 1) != -1) { var p = Code.Substring(0, Code.IndexOf('{', 1)); //вирізати те, що йде після оператора умови або циклу аж до { if (p[0].Equals("(") && p[0].Equals(")")) { throw new Exception("Error. Empty statement between checkIf(____)"); } if (!p.Equals("")) { ParseTokens(p, true, true, false); } else { throw new Exception("Error.Invalid call checkIf operator without (_)"); } ResultPredicate = MyTree.CreateTree(tokens, 0, tokens.Count, true); tokens.Clear(); Code = Code.Remove(0, p.Length); p = Code.Substring(0, Code.IndexOf("{", 0)); if (!p.Equals("")) { ParseTokens(p, false, true, false); } if (tokens.Count == 0) { if (Code.IndexOf("{", 0) > 0) { Code = Code.Remove(0, Code.IndexOf("{", 0)); } Token temp = new Token("{", Tokens.Types.Braces, outputTextBox, display_out); int opened_braces = 1, opened = 1, closed = 0; while (!Code.ElementAt(closed).Equals("}") && opened_braces != 0) { if (Code.Length > closed + 1) { if (opened_braces > 0) { if (Code[closed + 1].Equals("}")) { opened_braces--; } else { closed = Code.IndexOf("}", closed + 1); opened_braces--; } } else { break; } opened = Code.IndexOf("{", opened + 1); if (opened < closed && opened != -1) { opened_braces++; } if (closed == -1) { throw new Exception("Error.Check { } . } is missing"); } } else { throw new Exception("Error. '}' is missing!"); } } CheckIfClosed = closed; } else { throw new Exception("Error.Invalid using operator checkIf(). You missed {} - body!"); } if (ResultPredicate) { //без дужок string temp = Code.Substring(1, CheckIfClosed - 1); if (temp.Length > 0) { ParseTokens(temp, true, true, true); } //кидаємо тіло CheckIf на розбиття на токени і виконання } Code = Code.Remove(0, CheckIfClosed); tokens.Clear(); } else { throw new Exception("Error. '{' is missing after checkIf"); } } else { throw new Exception("Error. Nothing after checkIf operator!"); } } break; case "otherwise": { if (tokens.Count > 0) { if (tokens[0].value.Equals("}") && tokens.Count == 2)//перевірка чи перед цим був checkIf(){} { tokens.Clear(); var p = Code.Substring(0, Code.IndexOf("{", 0)); if (p.Length > 0) { ParseTokens(p, false, true, false); } if (tokens.Count == 0) { if (Code.IndexOf("{", 0) > 0) { Code = Code.Remove(0, Code.IndexOf("{", 0)); } Token temp = new Token("{", Tokens.Types.Braces, outputTextBox, display_out); int opened_braces = 1, opened = 1, closed = 0; try { while (!Code.ElementAt(closed).Equals("}") && opened_braces != 0) { if (opened_braces > 0) { closed = Code.IndexOf("}", closed + 1); opened_braces--; } else { break; } opened = Code.IndexOf("{", opened + 1); if (opened < closed && opened != -1) { opened_braces++; } if (closed == -1) { throw new Exception("Error. } is missing"); } } } catch (Exception e) { throw new Exception("Error. Invalid call otherwise {}"); } if (ResultPredicate == false) { string temp1 = (Code.Substring(1, closed - 1)); if (temp1.Length > 0) { ParseTokens(temp1, true, true, true); //кидаємо тіло otherwise на розбиття на токени і виконання } } Token temp11 = new Token("}", Tokens.Types.Braces, outputTextBox, display_out); Code = Code.Remove(0, closed + 1); } else { throw new Exception("Error.Invalid using operator otherwise"); } } else { throw new Exception("Error.Invalid using otherwise. Allowed only after checkIf(){}!"); } } else { throw new Exception("Error.Invalid using otherwise{}"); } } break; case "cycle": { if (Code.IndexOf('{', 1) > 1) { var p = Code.Substring(0, Code.IndexOf('{', 1) - 1); //вирізати те, що йде після оператора умови або циклу аж до { if (!p.Equals("")) { ParseTokens(p, true, true, false); } else { throw new Exception("Error.Invalid call cycle operator without (_)"); } Code = Code.Remove(0, p.Length); var temp_tokens = new List <Tokens.Token>(); if (tokens.Count > 0) { foreach (var t in tokens) { temp_tokens.Add(t); } tokens.Clear(); } else { throw new Exception("Error. Invalid call cycle(statement) {}"); } p = Code.Substring(0, Code.IndexOf("{", 0)); if (p.Length > 0) { ParseTokens(p, false, true, false); } if (tokens.Count == 0) { Code = Code.Remove(0, Code.IndexOf("{", 0)); Token temp = new Token("{", Tokens.Types.Braces, outputTextBox, display_out); int opened_braces = 1, opened = 1, closed = 0; while (!Code.ElementAt(closed).Equals("}") && opened_braces != 0) { if (Code.Length > closed) { if (opened_braces > 0) { closed = Code.IndexOf("}", closed + 1); opened_braces--; } else { break; } opened = Code.IndexOf("{", opened + 1); if (opened < closed && opened != -1) { opened_braces++; } if (closed == -1) { throw new Exception("Error.Check { } after cycle(). } is missing"); } } else { throw new Exception("Error. } is missing after cycle(){ "); } } var substring = Code.Substring(1, closed - 1); //вирізаємо тіло циклу //допоки виконуєтося умова циклу bool show = true; bool result = MyTree.CreateTree(temp_tokens, 0, temp_tokens.Count, true); //умова циклу while (result) { try { bool res = ParseTokens(substring, show, true, true); if (!res) { break; } if (show) { show = false; } result = MyTree.CreateTree(temp_tokens, 0, temp_tokens.Count, true); //умова циклу } catch (Exception e) { throw new Exception("Error. The process is endless"); } } Token temp11 = new Token("}", Tokens.Types.Braces, outputTextBox, display_out); //вивід на екран закритої } Code = Code.Remove(0, closed); } else { throw new Exception("Error.Invalid call cycle()"); } } else { throw new Exception("Error. Invalid calling cycle!"); } } break; } again = true; break; } } if (again) { continue; } foreach (var varName in Trees.Variables.Keys)//якщо змінна уже занесена у загальну таблицю змінних але відрізняються закінченням { if (Code.IndexOf(varName, StringComparison.Ordinal) == 0) { char ending = '\0'; if (Code.Length > varName.Length) { ending = Code[varName.Length]; } if (char.IsLetterOrDigit(ending)) { continue; //перевірка закінчення } tokens.Add(new Token(varName, Types.Var, outputTextBox, display_out)); Code = Code.Remove(0, varName.Length); again = true; break; } } if (again) { continue; } //якщо нічого із вищеперечисленого не підходить - одже це просте значення var value = ""; int[] indexes = new int[]//витягуємо число { Code.IndexOf(';'), Code.IndexOf(','), Code.IndexOf('+'), Code.IndexOf('-'), Code.IndexOf('*'), Code.IndexOf('/'), Code.IndexOf('>'), Code.IndexOf('<'), Code.IndexOf('=') }; if (indexes.Any(x => x > 0)) { index = indexes.Where(x => x > 0).Min(); } else { index = Code.Length; //якщо воно було в дужках (як параметр) } value = Code.Substring(0, index); tokens.Add(new Token(value, Types.Value, outputTextBox, display_out)); Code = Code.Remove(0, value.Length); } if (tokens.Count > 0) { if (!tokens[0].value.Equals("}")) { if (Code.Length == 0 && performed == false && tokens.Count > 0 && (inRecursion == false || Body == true)) { performed = MyTree.CreateTree(tokens, 0, tokens.Count, false); tokens.Clear(); //очищуємо токени } } } } catch (Exception e) { if (!e.Message.Equals("")) { if (!e.Message.IndexOf("Error", 0).Equals(0)) { string MyError = "Error. Check your code and try again!"; ErrorHandler(MyError); MessageBox.Show(MyError); } else { ErrorHandler(e.Message); MessageBox.Show(e.Message); return(false); } } return(false); } return(true); }