Ejemplo n.º 1
0
        // ОК
        private void ApplyButton_Click(object sender, EventArgs e)
        {
            // Контроль диапазона
            if ((StepValue.Value == 0) ||
                ((uint)(Math.Abs(EndValue.Value - StartValue.Value) / StepValue.Value) + 1 > DiagramData.MaxDataRows) ||
                (EndValue.Value == StartValue.Value))
            {
                MessageBox.Show(Localization.GetText("IncorrectRangeError", language), ProgramDescription.AssemblyTitle,
                                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            // Блокировка
            this.Enabled = false;

            // Заполнение
            for (int c = 0; c < CurvesList.Items.Count; c++)
            {
                // Получение цепочки вычисления
                LexemesExtractor         le  = new LexemesExtractor(CurvesList.Items[c].ToString());
                EvaluationChainAssembler eca = new EvaluationChainAssembler(le);
                ExpressionEvaluator      ee;

                // Подготовка
                y.Add(new List <double> ());

                // Генерация
                for (double i = (double)Math.Min(StartValue.Value, EndValue.Value); i <
                     (double)Math.Max(StartValue.Value, EndValue.Value); i += (double)StepValue.Value)
                {
                    if (c == 0)
                    {
                        x.Add(i);
                    }

                    ee = new ExpressionEvaluator(eca, i);
                    y[y.Count - 1].Add(ee.Result);
                }

                // Последнее значение
                if (c == 0)
                {
                    x.Add((double)Math.Max(StartValue.Value, EndValue.Value));
                }

                ee = new ExpressionEvaluator(eca, (double)Math.Max(StartValue.Value, EndValue.Value));
                y[y.Count - 1].Add(ee.Result);

                // Название столбца
                columnsNames.Add(CurvesList.Items[c].ToString());
            }

            // Завершение
            cancelled = false;
            this.Close();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Конструктор. Выполняет сборку цепочки вычислений
        /// </summary>
        public EvaluationChainAssembler(LexemesExtractor ExpressionLexemesExtractor)
        {
            // Контроль сборки
            if ((ExpressionLexemesExtractor.FollowingStatus != LexemesFollowingMatrix.LexemesFollowingStatuses.Ok) ||
                (ExpressionLexemesExtractor.ExpressionStatus != LexemesExtractor.ExpressionStatuses.Ok))
            {
                return;
            }

            // Формирование массива приоритетов
            List <int> links      = new List <int> ();
            int        multiplier = 10000;

            for (int i = 0; i < ExpressionLexemesExtractor.ExtractedLexemes.Count; i++)
            {
                switch (ExpressionLexemesExtractor.ExtractedLexemes[i].LexemeType)
                {
                // Установка уровня вложенности
                case Lexeme.LexemeTypes.LeftParenthesis:
                    multiplier += 10000;
                    break;

                case Lexeme.LexemeTypes.RightParenthesis:
                    multiplier -= 10000;
                    break;

                // Установка приоритетов для функций и операций
                case Lexeme.LexemeTypes.Sinus:
                case Lexeme.LexemeTypes.Cosinus:
                case Lexeme.LexemeTypes.Tangens:
                case Lexeme.LexemeTypes.Cotangens:
                case Lexeme.LexemeTypes.Arcsinus:
                case Lexeme.LexemeTypes.Arccosinus:
                case Lexeme.LexemeTypes.Arctangens:
                case Lexeme.LexemeTypes.Arccotangens:
                case Lexeme.LexemeTypes.NaturalLogarithm:
                case Lexeme.LexemeTypes.Abs:
                    links.Add(multiplier + 5000 + i);
                    break;

                case Lexeme.LexemeTypes.Exponentiation:
                    links.Add(multiplier + 4000 + i);
                    break;

                case Lexeme.LexemeTypes.Division:
                    links.Add(multiplier + 3000 + i);
                    break;

                case Lexeme.LexemeTypes.Multiplication:
                    links.Add(multiplier + 2000 + i);
                    break;

                case Lexeme.LexemeTypes.Minus:
                    links.Add(multiplier + 1000 + i);
                    break;

                case Lexeme.LexemeTypes.Plus:
                    links.Add(multiplier + 0 + i);
                    break;

                // Установка прямых ссылок на операнды
                case Lexeme.LexemeTypes.E:
                case Lexeme.LexemeTypes.Pi:
                case Lexeme.LexemeTypes.Number:
                case Lexeme.LexemeTypes.Variable:
                    links.Add(i);
                    break;

                // А такого быть не должно: класс LexemesExtractor должен это исключить
                case Lexeme.LexemeTypes.Unknown:
                    throw new Exception("Достигнуто предвиденное исключение. Для коррекции необходимо обратиться к автору программы");
                }
            }

            // Сборка цепочки
            int max, maxIndex;

            while (true)
            {
                // Поиск максимального приоритета
                max = maxIndex = 0;

                for (int i = 0; i < links.Count; i++)
                {
                    if (max < links[i])
                    {
                        max      = links[i];
                        maxIndex = i;
                    }
                }

                // Условие прерывания
                if (max < 1000)
                {
                    break;
                }

                // Обработка операций (любой сбой на этом шаге означает кривизну предыдущих обработок)
                switch (ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex] % 1000].LexemeType)
                {
                // Обработка функций
                case Lexeme.LexemeTypes.Sinus:
                case Lexeme.LexemeTypes.Cosinus:
                case Lexeme.LexemeTypes.Tangens:
                case Lexeme.LexemeTypes.Cotangens:
                case Lexeme.LexemeTypes.Arcsinus:
                case Lexeme.LexemeTypes.Arccosinus:
                case Lexeme.LexemeTypes.Arctangens:
                case Lexeme.LexemeTypes.Arccotangens:
                case Lexeme.LexemeTypes.NaturalLogarithm:
                case Lexeme.LexemeTypes.Abs:
                    if (links[maxIndex + 1] >= 0)
                    {
                        // По факту
                        chain.Add(new EvaluationChainElement(ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex] % 1000],
                                                             ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex + 1] % 1000]));
                    }
                    else
                    {
                        // По ссылке (ссылки хранятся в отрицательных числах со смещением
                        chain.Add(new EvaluationChainElement(ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex] % 1000],
                                                             (uint)(-links[maxIndex + 1] - 1)));
                    }

                    // То же самое
                    if (!chain[chain.Count - 1].IsInited)
                    {
                        throw new Exception("Достигнуто предвиденное исключение. Для коррекции необходимо обратиться к автору программы");
                    }

                    // Замещение операции и операнда ссылкой на результат операции
                    links.RemoveAt(maxIndex);
                    links.RemoveAt(maxIndex);
                    links.Insert(maxIndex, -chain.Count);
                    break;

                // Обработка бинарных операций
                case Lexeme.LexemeTypes.Plus:
                case Lexeme.LexemeTypes.Minus:
                case Lexeme.LexemeTypes.Multiplication:
                case Lexeme.LexemeTypes.Division:
                case Lexeme.LexemeTypes.Exponentiation:
                    if (links[maxIndex - 1] >= 0)
                    {
                        // По факту
                        if (links[maxIndex + 1] >= 0)
                        {
                            chain.Add(new EvaluationChainElement(ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex - 1] % 1000],
                                                                 ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex] % 1000],
                                                                 ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex + 1] % 1000]));
                        }
                        // Со вторым операндом-ссылкой
                        else
                        {
                            chain.Add(new EvaluationChainElement(ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex - 1] % 1000],
                                                                 ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex] % 1000],
                                                                 (uint)(-links[maxIndex + 1] - 1)));
                        }
                    }
                    else
                    {
                        // С первым операндом-ссылкой
                        if (links[maxIndex + 1] >= 0)
                        {
                            chain.Add(new EvaluationChainElement((uint)(-links[maxIndex - 1] - 1),
                                                                 ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex] % 1000],
                                                                 ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex + 1] % 1000]));
                        }
                        // С обоими операндами-ссылками
                        else
                        {
                            chain.Add(new EvaluationChainElement((uint)(-links[maxIndex - 1] - 1),
                                                                 ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex] % 1000],
                                                                 (uint)(-links[maxIndex + 1] - 1)));
                        }
                    }

                    // То же самое
                    if (!chain[chain.Count - 1].IsInited)
                    {
                        throw new Exception("Достигнуто предвиденное исключение. Для коррекции необходимо обратиться к автору программы");
                    }

                    // Замещение операции и операнда ссылкой на результат операции
                    links.RemoveAt(maxIndex - 1);
                    links.RemoveAt(maxIndex - 1);
                    links.RemoveAt(maxIndex - 1);
                    links.Insert(maxIndex - 1, -chain.Count);
                    break;

                // Остальных лексем здесь быть не должно
                default:
                    throw new Exception("Достигнуто предвиденное исключение. Для коррекции необходимо обратиться к автору программы");
                }
            }

            // Если массив шагов пуст, то операций в выражении не было
            if (chain.Count == 0)
            {
                // Необходимо для фильтрации скобок
                chain.Add(new EvaluationChainElement(ExpressionLexemesExtractor.ExtractedLexemes[links[maxIndex] % 1000]));

                if (!chain[chain.Count - 1].IsInited)
                {
                    throw new Exception("Достигнуто предвиденное исключение. Для коррекции необходимо обратиться к автору программы");
                }
            }

            // Завершено
            isInited = true;
        }
Ejemplo n.º 3
0
        // Обновление статуса проверки формулы и добавление кривой
        private void AddButton_Click(object sender, EventArgs e)
        {
            // Блокировка контролов
            FormulaBox.ReadOnly = true;
            AddButton.Enabled   = DeleteButton.Enabled = false;
            ApplyButton.Enabled = AbortButton.Enabled = false;

            // Контроль порядка лексем в выражении
            LexemesExtractor le = new LexemesExtractor(FormulaBox.Text);

            switch (le.FollowingStatus)
            {
            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedConstant:
                InfoLabel.Text = string.Format(Localization.GetText("MisplacedConstantError", language), le.LastLexeme);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedDivisionOperator:
                InfoLabel.Text = Localization.GetText("MisplacedDivisionOperatorError", language);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedExponentiationOperator:
                InfoLabel.Text = Localization.GetText("MisplacedExponentiationOperatorError", language);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedFunctionCall:
                InfoLabel.Text = string.Format(Localization.GetText("MisplacedFunctionCallError", language), le.LastLexeme);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedLeftParenthesis:
                InfoLabel.Text = Localization.GetText("MisplacedLeftParenthesisError", language);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedMinusOperator:
                InfoLabel.Text = Localization.GetText("MisplacedMinusOperatorError", language);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedMultiplicationOperator:
                InfoLabel.Text = Localization.GetText("MisplacedMultiplicationOperatorError", language);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedNumber:
                InfoLabel.Text = string.Format(Localization.GetText("MisplacedNumberError", language), le.LastLexeme);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedPlusOperator:
                InfoLabel.Text = Localization.GetText("MisplacedPlusOperatorError", language);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedRightParenthesis:
                InfoLabel.Text = Localization.GetText("MisplacedRightParenthesisError", language);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.MisplacedVariable:
                InfoLabel.Text = Localization.GetText("MisplacedVariableError", language);
                break;

            case LexemesFollowingMatrix.LexemesFollowingStatuses.UnknownLexeme:
                InfoLabel.Text = string.Format(Localization.GetText("UnknownLexemeError", language), le.LastLexeme);
                break;
            }

            if (le.FollowingStatus != LexemesFollowingMatrix.LexemesFollowingStatuses.Ok)
            {
                InfoLabel.ForeColor = Color.FromArgb(128, 32, 0);

                FormulaBox.ReadOnly  = false;
                AddButton.Enabled    = (CurvesList.Items.Count < DiagramData.MaxLines);
                DeleteButton.Enabled = ApplyButton.Enabled = (CurvesList.Items.Count > 0);
                AbortButton.Enabled  = true;

                return;
            }

            // Первичная обработка выражения
            switch (le.ExpressionStatus)
            {
            case LexemesExtractor.ExpressionStatuses.ExpressionIsEmpty:
                InfoLabel.Text = Localization.GetText("ExpressionIsEmptyError", language);
                break;

            case LexemesExtractor.ExpressionStatuses.IncorrectExpressionEnd:
                InfoLabel.Text = string.Format(Localization.GetText("IncorrectExpressionEndError", language), le.LastLexeme);
                break;

            case LexemesExtractor.ExpressionStatuses.IncorrectExpressionStart:
                InfoLabel.Text = string.Format(Localization.GetText("IncorrectExpressionStartError", language), le.LastLexeme);
                break;

            case LexemesExtractor.ExpressionStatuses.LeftParenthesisWasNotClosed:
                InfoLabel.Text = Localization.GetText("LeftParenthesisWasNotClosedError", language);
                break;

            case LexemesExtractor.ExpressionStatuses.MisplacedRightParenthesis:
                InfoLabel.Text = Localization.GetText("UnexpectedRightParenthesisError", language);
                break;
            }

            if (le.ExpressionStatus != LexemesExtractor.ExpressionStatuses.Ok)
            {
                InfoLabel.ForeColor = Color.FromArgb(128, 0, 0);

                FormulaBox.ReadOnly  = false;
                AddButton.Enabled    = (CurvesList.Items.Count < DiagramData.MaxLines);
                DeleteButton.Enabled = ApplyButton.Enabled = (CurvesList.Items.Count > 0);
                AbortButton.Enabled  = true;

                return;
            }

            // Проверка успешно завершена
            InfoLabel.ForeColor = Color.FromArgb(0, 128, 0);
            InfoLabel.Text      = Localization.GetText("NoErrors", language) + "\nf(x) = ";
            string formula = "";

            for (int i = 0; i < le.ExtractedLexemes.Count; i++)
            {
                formula        += le.ExtractedLexemes[i].LexemeValue;
                InfoLabel.Text += le.ExtractedLexemes[i].LexemeValue;
            }

            // Добавление кривой в список
            CurvesList.Items.Add(formula);

            // Разблокировка контролов
            FormulaBox.ReadOnly  = false;
            AddButton.Enabled    = (CurvesList.Items.Count < DiagramData.MaxLines);
            DeleteButton.Enabled = ApplyButton.Enabled = true;
            AbortButton.Enabled  = true;
        }