using BaseCalculator; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Calculator { internal class Analaizer { private static int erposition = 0; public static string expression = ""; public static ArrayList opz = null; public static bool CheckCurrency() { bool result = true; int num = 0; for (int i = 0; i < expression.Length; i++) { if (expression[i] == '(') { num++; } else if (expression[i] == ')') { num--; } if (num < 0) { result = false; erposition = i; return result; } } if (num != 0) { result = false; } return result; } public static string Format() { string text = ""; string text2 = ""; if (expression.Length <= 65536) { for (int i = 0; i < expression.Length; i++) { switch (expression[i]) { case '0': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '1': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '2': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '3': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '4': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '5': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '6': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '7': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '8': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '9': text = ((!(text2 == "число") && !(text2 == "")) ? (text + " " + expression[i]) : (text + expression[i])); text2 = "число"; break; case '+': if (text2 != "") { if (!(text2 != "оператор")) { MessageBox.Show("Два подряд оператора на " + i + " символе."); return "&Error 04 at " + i; } text = text + " " + expression[i]; } else { text += expression[i]; } text2 = "оператор"; break; case '-': if (text2 != "") { if (!(text2 != "оператор")) { MessageBox.Show("Два подряд оператора на " + i + " символе."); return "&Error 04 at " + i; } text = text + " " + expression[i]; } else { text += expression[i]; } text2 = "оператор"; break; case '*': if (text2 != "") { if (!(text2 != "оператор")) { MessageBox.Show("Два подряд оператора на " + i + " символе."); return "&Error 04 at " + i; } text = text + " " + expression[i]; } else { text += expression[i]; } text2 = "оператор"; break; case '/': if (text2 != "") { if (!(text2 != "оператор")) { MessageBox.Show("Два подряд оператора на " + i + " символе."); return "&Error 04 at " + i; } text = text + " " + expression[i]; } else { text += expression[i]; } text2 = "оператор"; break; case '(': text = ((!(text2 != "")) ? (text + expression[i]) : (text + " " + expression[i])); text2 = "скобка"; break; case ')': text = ((!(text2 != "")) ? (text + expression[i]) : (text + " " + expression[i])); text2 = "скобка"; break; case 'm': if (i + 1 < expression.Length && expression[i + 1] == 'o' && expression[i + 2] == 'd') { if (text2 != "") { if (!(text2 != "оператор")) { MessageBox.Show("Два подряд оператора на " + i + " символе."); return "&Error 04 at " + i; } string text3 = text; text = text3 + " " + expression[i] + expression[i + 1] + expression[i + 2]; } else { text = text + expression[i] + expression[i + 1] + expression[i + 2]; } text2 = "оператор"; i += 2; } else { text = ((!(text2 != "")) ? (text + expression[i]) : (text + " " + expression[i])); text2 = "унарный оператор"; } break; case 'p': text = ((!(text2 != "")) ? (text + expression[i]) : (text + " " + expression[i])); text2 = "унарный оператор"; break; default: MessageBox.Show("Неизвестный оператор на " + i + " символе."); return "&Error 02 at " + i; case ' ': break; } } if (text2 != "оператор" && text2 != "унарный оператор") { return text + " "; } MessageBox.Show("Незаконченное выражение. "); return "&Error 05"; } MessageBox.Show("Слишком длинное выражение. Максмальная длина - 65536 символов."); return "&Error 07"; } public static ArrayList CreateStack() { ArrayList arrayList = new ArrayList(30); Stack stack = new Stack(15); string text = expression; while (text != "") { string text2 = text.Substring(0, text.IndexOf(" ")); text = text.Substring(text.IndexOf(" ") + 1); switch (text2) { case "(": stack.Push(text2); break; case "m": while (stack.Count != 0 && (stack.Peek().ToString() == "m" || stack.Peek().ToString() == "p")) { if (arrayList.Capacity > arrayList.Count) { arrayList.Add(stack.Pop()); continue; } return null; } stack.Push(text2); break; case "p": while (stack.Count != 0 && (stack.Peek().ToString() == "m" || stack.Peek().ToString() == "p")) { if (arrayList.Capacity > arrayList.Count) { arrayList.Add(stack.Pop()); continue; } return null; } stack.Push(text2); break; case "*": while (stack.Count != 0 && (stack.Peek().ToString() == "*" || stack.Peek().ToString() == "/" || stack.Peek().ToString() == "mod" || stack.Peek().ToString() == "m" || stack.Peek().ToString() == "p")) { if (arrayList.Capacity > arrayList.Count) { arrayList.Add(stack.Pop()); continue; } return null; } stack.Push(text2); break; case "/": while (stack.Count != 0 && (stack.Peek().ToString() == "*" || stack.Peek().ToString() == "/" || stack.Peek().ToString() == "mod" || stack.Peek().ToString() == "m" || stack.Peek().ToString() == "p")) { if (arrayList.Capacity > arrayList.Count) { arrayList.Add(stack.Pop()); continue; } return null; } stack.Push(text2); break; case "mod": while (stack.Count != 0 && (stack.Peek().ToString() == "*" || stack.Peek().ToString() == "/" || stack.Peek().ToString() == "mod" || stack.Peek().ToString() == "m" || stack.Peek().ToString() == "p")) { if (arrayList.Capacity > arrayList.Count) { arrayList.Add(stack.Pop()); continue; } return null; } stack.Push(text2); break; case "+": while (stack.Count != 0 && (stack.Peek().ToString() == "*" || stack.Peek().ToString() == "/" || stack.Peek().ToString() == "mod" || stack.Peek().ToString() == "+" || stack.Peek().ToString() == "-" || stack.Peek().ToString() == "m" || stack.Peek().ToString() == "p")) { if (arrayList.Capacity > arrayList.Count) { arrayList.Add(stack.Pop()); continue; } return null; } stack.Push(text2); break; case "-": while (stack.Count != 0 && (stack.Peek().ToString() == "*" || stack.Peek().ToString() == "/" || stack.Peek().ToString() == "mod" || stack.Peek().ToString() == "+" || stack.Peek().ToString() == "-" || stack.Peek().ToString() == "m" || stack.Peek().ToString() == "p")) { if (arrayList.Capacity > arrayList.Count) { arrayList.Add(stack.Pop()); continue; } return null; } stack.Push(text2); break; case ")": while (stack.Peek().ToString() != "(") { if (arrayList.Capacity > arrayList.Count) { arrayList.Add(stack.Pop()); continue; } return null; } stack.Pop(); break; default: if (arrayList.Capacity > arrayList.Count) { arrayList.Add(text2); break; } return null; } } while (stack.Count != 0) { arrayList.Add(stack.Pop()); } return arrayList; } public static string RunEstimate() { bool flag = false; while (!flag) { int i = 0; bool flag2 = false; for (; i < opz.Count; i++) { if (flag2) { break; } flag2 = true; try { switch (opz[i].ToString()) { case "+": opz[i - 2] = CalcClass.Add(Convert.ToInt64(opz[i - 2]), Convert.ToInt64(opz[i - 1])); opz.RemoveAt(i - 1); opz.RemoveAt(i - 1); break; case "-": opz[i - 2] = CalcClass.Sub(Convert.ToInt64(opz[i - 2]), Convert.ToInt64(opz[i - 1])); opz.RemoveAt(i - 1); opz.RemoveAt(i - 1); break; case "*": opz[i - 2] = CalcClass.Mult(Convert.ToInt64(opz[i - 2]), Convert.ToInt64(opz[i - 1])); opz.RemoveAt(i - 1); opz.RemoveAt(i - 1); break; case "/": opz[i - 2] = CalcClass.Div(Convert.ToInt64(opz[i - 2]), Convert.ToInt64(opz[i - 1])); opz.RemoveAt(i - 1); opz.RemoveAt(i - 1); break; case "mod": opz[i - 2] = CalcClass.Mod(Convert.ToInt64(opz[i - 2]), Convert.ToInt64(opz[i - 1])); opz.RemoveAt(i - 1); opz.RemoveAt(i - 1); break; case "m": opz[i - 1] = CalcClass.IABS(Convert.ToInt64(opz[i - 1])); opz.RemoveAt(i); break; case "p": opz[i - 1] = CalcClass.ABS(Convert.ToInt64(opz[i - 1])); opz.RemoveAt(i); break; default: flag2 = false; break; } } catch (DivideByZeroException) { MessageBox.Show("Ошибка деления на 0"); return "Error 09"; } catch (OverflowException) { MessageBox.Show("Слишком малое или слишком большое значение числа для int\n Числа должны быть в пределах от -2147483648 до 2147483647"); return "Error 06"; } } if (!flag2 && i == opz.Count) { flag = true; } string lastError = CalcClass.lastError; if (lastError != "") { return lastError; } } if (opz.Count != 1) { MessageBox.Show("Неверная синтаксическая конструкция входного выражения!"); return "Error 03"; } return opz[0].ToString(); } public static string Estimate() { if (CheckCurrency()) { string text = Format(); if (text[0] == '&') { return text.Substring(1); } expression = text; opz = CreateStack(); if (opz != null) { return RunEstimate(); } MessageBox.Show("Суммарное количество чисел и операторов превышает 30!"); return "Error 08"; } MessageBox.Show("Неправильная скобочная структура, ошибка на " + erposition + " символе !"); return "Error 01 at " + erposition; } } }