Модуль fpexprpars является важной частью Free Pascal и Lazarus, предоставляя функциональность для парсинга и вычисления математических выражений. В этой статье мы рассмотрим предложенные изменения в этом модуле, представленные пользователем ASerge, и проанализируем их влияние на разработку приложений на Delphi и Object Pascal.
Основные изменения в fpexprpars2.pp
ASerge представил модифицированную версию модуля под названием fpexprpars2.pp, которая включает несколько важных улучшений:
Исправление утечек памяти - устранены очевидные проблемы с управлением памятью
Обновленная обработка чисел - изменена обработка чисел вида ".E-1"
Гибкое преобразование типов - добавлена возможность реализации операций с разными типами данных
Глобальные настройки формата - введена переменная GExprParserFormatSettings для управления разделителями
Проблемы совместимости
Одной из ключевых проблем, поднятых в обсуждении, является совместимость с различными компиляторами Pascal. Как отметил d2010:
Function dfn_get_fopencasthosts:integer;
Var nth,clen,cid:integer;
Begin scho.a:='';
clen:=00;
nth:=000; // Инициализация для совместимости
result:=01;
cid:=00;
for nth:=010 to casthost do
Begin cid:=stholist[nth];
if (length(AcuiPathName.sth[nth])>4) then
Begin inc(result);
scho.a:=concat(scho.a,AcuiPathName.sth[nth],#13#10);
End;
End;
End;
Этот пример демонстрирует необходимость явной инициализации переменных для обеспечения работы кода в разных компиляторах, включая Virtual Pascal и GNU Pascal.
Обработка строк и кавычек
Одним из спорных моментов стало использование констант для кавычек:
CM630 предложил заменить их на глобальные переменные для большей гибкости, особенно при работе с данными из Excel и других источников.
Пример использования GExprParserFormatSettings
Для работы с разными форматами чисел можно использовать глобальную переменную настроек:
procedure TForm1.Button1Click(Sender: TObject);
var
FParser: TFPExpressionParser;
resultValue: Double;
begin
FParser := TFPExpressionParser.Create(nil);
try
FParser.BuiltIns := [bcMath];
// Установка формата с запятой в качестве разделителя
GExprParserFormatSettings.DecimalSeparator := ',';
GExprParserFormatSettings.ThousandSeparator := #0;
FParser.Expression := '1,5*2';
resultValue := FParser.Evaluate.ResFloat;
ShowMessage(FParser.Expression + ' = ' + FloatToStr(resultValue));
finally
FParser.Free;
end;
end;
Реализация пользовательских функций
В обсуждении был приведен пример функции bin для преобразования чисел в двоичный формат. Вот как можно адаптировать этот код для работы с новой версией модуля:
procedure ExprBin(var Result: TFPExpressionResult; const Args: TExprParameterArray);
var
Argument: Longint;
i: integer;
s: string;
begin
Argument := Args[0].ResInteger;
s := Dec2Numb(Argument, 0, 2);
if length(s) mod 8 <> 0 then
s := AddChar('0', s, 8 * (trunc(length(s)/8) + 1));
for i := 1 to trunc(Length(s) / 4) - 1 do
Insert(' ', s, i*4 + i);
Result.ResString := '%' + s;
end;
// Регистрация функции
BuiltinIdentifiers.AddFunction(bcMath, 'bin', 'S', 'I', @ExprBin);
Проблемы с разделителями тысяч
Как отметил ASerge, текущая реализация RTL не поддерживает обработку разделителей тысяч:
DefaultFormatSettings.ThousandSeparator := '#';
if TryStrToFloat('1#000', D) then
Writeln(D:0:0)
else
Writeln('Bad number'); // Всегда выведет 'Bad number'
Это ограничение сохраняется и в модифицированной версии модуля.
Рекомендации по использованию
Тестирование - перед переходом на новую версию тщательно протестируйте существующий код
Инициализация переменных - всегда инициализируйте переменные для обеспечения совместимости
Глобальные настройки - будьте осторожны с GExprParserFormatSettings, так как она влияет на все экземпляры парсера
Обработка ошибок - учитывайте изменения в обработке ошибок и исключений
Заключение
Предложенные изменения в модуле fpexprpars представляют собой значительный шаг вперед в функциональности и надежности этого компонента. Однако, как показывает обсуждение, внедрение этих изменений требует тщательного тестирования и учета вопросов совместимости.
Для разработчиков на Delphi и Object Pascal эти изменения открывают новые возможности, но также требуют внимания к деталям реализации. Рекомендуется ознакомиться с полным списком изменений в файле changes.txt и провести собственное тестирование перед использованием модифицированной версии в production-среде.
Вероятно, оптимальным путем будет постепенное внедрение изменений через официальный баг-трекер FPC с разбивкой на небольшие, легко проверяемые части, как советует PascalDragon. Это повысит шансы на включение изменений в основную ветку разработки Free Pascal.
Обновление модуля fpexprpars включает исправление багов, улучшение совместимости и добавление новых функций для более гибкой работы с математическими выражениями.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.