Загрузка данных


using System;
using System.Globalization;
using System.Windows.Forms;

namespace CalculatorStudent
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            txtDisplay.Text = "";
        }

        // Добавление цифр
        private void Number_Click(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            txtDisplay.Text += btn.Text;
        }

        // Добавление операций
        private void Operation_Click(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            txtDisplay.Text += btn.Text;
        }

        // Добавление скобок
        private void Bracket_Click(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            txtDisplay.Text += btn.Text;
        }

        // Запятая для дробных чисел
        private void btnComma_Click(object sender, EventArgs e)
        {
            txtDisplay.Text += ",";
        }

        // Очистка
        private void btnClear_Click(object sender, EventArgs e)
        {
            txtDisplay.Text = "";
        }

        // Вычисление
        private void btnEqual_Click(object sender, EventArgs e)
        {
            try
            {
                string expression = txtDisplay.Text;

                if (string.IsNullOrWhiteSpace(expression))
                {
                    MessageBox.Show("Введите выражение.");
                    return;
                }

                double result = Evaluate(expression);
                txtDisplay.Text = result.ToString();
            }
            catch (DivideByZeroException)
            {
                MessageBox.Show("Деление на ноль невозможно!", "Ошибка",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                txtDisplay.Text = "";
            }
            catch (Exception)
            {
                MessageBox.Show("Ошибка в выражении!", "Ошибка",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                txtDisplay.Text = "";
            }
        }

        // ====== ПАРСЕР ======

        private int pos;
        private string text;

        private double Evaluate(string expression)
        {
            text = expression.Replace(" ", "").Replace(',', '.');
            pos = 0;

            double result = ParseExpression();

            if (pos < text.Length)
                throw new Exception("Лишние символы");

            return result;
        }

        // + и -
        private double ParseExpression()
        {
            double value = ParseTerm();

            while (pos < text.Length)
            {
                if (text[pos] == '+')
                {
                    pos++;
                    value += ParseTerm();
                }
                else if (text[pos] == '-')
                {
                    pos++;
                    value -= ParseTerm();
                }
                else
                {
                    break;
                }
            }

            return value;
        }

        // * и /
        private double ParseTerm()
        {
            double value = ParseFactor();

            while (pos < text.Length)
            {
                if (text[pos] == '*')
                {
                    pos++;
                    value *= ParseFactor();
                }
                else if (text[pos] == '/')
                {
                    pos++;
                    double divisor = ParseFactor();

                    if (divisor == 0)
                        throw new DivideByZeroException();

                    value /= divisor;
                }
                else
                {
                    break;
                }
            }

            return value;
        }

        // число или выражение в скобках
        private double ParseFactor()
        {
            if (pos >= text.Length)
                throw new Exception("Неожиданный конец");

            // Скобки
            if (text[pos] == '(')
            {
                pos++;
                double value = ParseExpression();

                if (pos >= text.Length || text[pos] != ')')
                    throw new Exception("Нет закрывающей скобки");

                pos++;
                return value;
            }

            // Минус перед числом, например: -5
            if (text[pos] == '-')
            {
                pos++;
                return -ParseFactor();
            }

            return ParseNumber();
        }

        // Чтение числа
        private double ParseNumber()
        {
            int start = pos;

            while (pos < text.Length &&
                  (char.IsDigit(text[pos]) || text[pos] == '.'))
            {
                pos++;
            }

            string number = text.Substring(start, pos - start);

            if (string.IsNullOrEmpty(number))
                throw new Exception("Ожидалось число");

            return double.Parse(number, CultureInfo.InvariantCulture);
        }
    }
}