скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

TMathExpression - компонент для синтаксического анализа



Автор: Виталий Бабичев

Уважаемые жители, для тестирования предлагается TMathExpression — компонент, предназначенный для синтаксического анализа и расчета математических выражений.

Компонент тестировался под Delphi5.

Для тестирования предлагается Demo-версия, в которой есть ограничения на количество обрабатываемых формул (не более 10).

ВСЕМ, кто примет активное участие в тестировании и даст конкретные предложения по качественному улучшению работы компонента, хелпа к нему или демонстрационной программы, проект будет предоставлен БЕЗ ОГРАНИЧЕНИЙ.

Основные возможности

Компонент предназначен для синтаксического анализа и расчета математических выражений. Выражение - арифметическое выражение, состоящее из имен формул, констант и пользовательских функций.

Математические выражения могут быть взяты из любого источника данных (таблица, текстовый файл, лист MSExcel и т.д.).

Проще всего если источником данных является таблица, потому что метод FillExpression формирует список формул из указанной таблицы. Если источником данных является не таблица, то для формирования списка формул надо воспользоваться методом AddExpression.

Формула - поименованное выражение, т.е. любому выражению может быть присвоено имя, и это имя может быть вставлено в другое выражение.

Это сделано для исключения повторного вычисления. Допустим, у Вас есть несколько одинаковых кусочков выражения.

Вы выделяете этот кусочек в отдельное выражение и именуете его. А в другие выражения вставляете наименование этой формулы. При вычислениях формула будет посчитана один раз. А там, где в выражениях встречается это наименование формулы, будет проставлен результат.

Это экономит время расчета.

Функции это тот механизм, ради которого и создавался компонент TMathExpression. У компонента TMathExpression есть свойство-коллекция TFunctions, она и содержит список пользовательских функций с их реализацией. В связи с тем, что функции участвуют в выражениях, они обязательно должны возвращать число. В принципе функции могут делать что угодно (что-то вычислить, обнулить какие-то параметры или даже закрыть какое-нибудь приложение и т.д.), но как результат - возвратить число.

Функции могут быть четырех типов (т.е. их параметры могут быть четырех типов):

1. ПАРАМЕТР - СЧЕТ ИЛИ ИДЕНТИФИКАТОР;
Счет может быть представлен в двух вариантах:
  • 1. Счет 2-го порядка (5 символов); Функции, у которых параметр счет второго порядка, возвращают остаток или оборот по счету.
  • 2. Счет 1-го порядка (3 символа); В его состав входит группа счетов в диапазоне от ХХХ00 до ХХХ99 (где ХХХ - номер счета).
Функции, у которых параметр счет первого порядка, возвращают сумму остатков или оборотов по группе счетов, входящих в состав счета первого порядка.
Первый и второй порядок - это бухгалтерские понятия, в которые я вдаваться не буду.
Иногда возникает необходимость расчета параметра, в состав которого входят счета из разных групп.
Это, конечно, можно сделать, если составить выражение из функций, параметрами которой являются нужные счета. Но тогда выражение может быть слишком большим, что затрудняет его читаемость и как следствие, возникают трудности с модификацией такого выражения.
Для такого случая введено понятие - идентификатор списка счетов. Списку счетов присваивается имя. Далее в выражение вставляется вызов одной функции, параметром которой является имя списка счетов. Это существенно сокращает длину выражения, да и редактировать список счетов гораздо легче.
2. ПАРАМЕТР - НАИМЕНОВАНИЕ ФОРМУЛЫ;
Функции, параметрами которых могут быть имена формул.
В каких ситуациях это может понадобиться? Допустим у Вас есть ряд однотипных объектов, по которым необходимо сделать сводный отчет. Это могут быть, например, филиалы предприятия в различных регионах, склады и т.д. Вы определяете функцию, которая считает сводный показатель.
В данном случае результатом будет сумма значений формулы по всем однотипным объектам.
3. ПАРАМЕТР - ЛЮБОЙ, НО ОДИН;
Этот тип функций введен для случаев, которые не попадают под описание первых двух.
Например, функция должна возвратить значение по определенному критерию, который не является ни счетом, ни идентификатором списков счетов, ни формулой. Для такого параметра устанавливаются свои правила проверки синтаксиса (для всех остальных правила проверки синтаксиса известны).
Но условия при вычислении остаются прежними - функция должна возвратить число.
У каждой пользовательской функции есть свойство OnCheckParam, но актуально оно только для этого типа функций (в остальных случаях событие игнорируется, даже если определен обработчик). В обработчике для этого события можно проверять правильность заполнения параметра. Этот обработчик должен быть обязательно определен, в противном случае при синтаксическом разборе будет ошибка.
Допустим, у Вас есть справочник с критериями, накопительная база с данными по этим критериям за разные периоды времени и Вы хотите иметь функцию для возврата этих значений. Вы добавляете функцию, присваиваете ей нужный тип и имя. В обработчике для события OnCheckParam, Вы определяете правила проверки синтаксиса, а в обработчике события OnExecFunction ее реализацию. Вот, собственно, и все.
4. УСЛОВНАЯ ФУНКЦИЯ;
Аналогом таких функций является условный оператор IF в языках программирования.
В такую функцию передается три параметра: условие, выражение если условие истинно, выражение если условие ложно. Условие разделено на две части, между которыми должен стоять один из знаков сравнения ("=","<>","<",">","<=",">="). Все выражения могут содержать в себе любое количество формул, констант и функций.

ОБРАБОТКА ОШИБОК

В связи с тем, что в выражения могут быть вставлены наименования формул, синтаксический анализатор проверяет дополнительно ситуацию зацикливания.
Что же это такое зацикливание?
Допустим, у Вас есть три формулы:
Formula1=Formula2+1
Formula2=Formula3-1
Formula3=Formula1
Обратите внимание, что Formula1 ссылается на Formula2, Formula2 ссылается на Formula3, а Formula3 в свою очередь ссылается на Formula1.
Образуется замкнутая цепочка, из которой не понятно как производить вычисления, хотя синтаксически все написано правильно. Вот это и называется зацикливанием. При ее возникновении, синтаксический анализатор выдает сообщение об ошибке и выводит всю замкнутую цепочку.

Все примеры использования приведены в демонстрационной программе.

Буду рад выслушать все замечания и предложения.

Скачать проект: MathExpr.zip (98 K)






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook