calc_version4/Analaizer.cs
2025-12-01 17:19:00 +04:00

496 lines
20 KiB
C#

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