Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Обновление и модификация модуля fpexprpars: исправления багов, улучшения совместимости и добавление новых функций

Delphi , Компоненты и Классы , Процедуры и функции

 

Введение

Модуль fpexprpars является важной частью Free Pascal и Lazarus, предоставляя функциональность для парсинга и вычисления математических выражений. В этой статье мы рассмотрим предложенные изменения в этом модуле, представленные пользователем ASerge, и проанализируем их влияние на разработку приложений на Delphi и Object Pascal.

Основные изменения в fpexprpars2.pp

ASerge представил модифицированную версию модуля под названием fpexprpars2.pp, которая включает несколько важных улучшений:

  1. Исправление утечек памяти - устранены очевидные проблемы с управлением памятью
  2. Обновленная обработка чисел - изменена обработка чисел вида ".E-1"
  3. Гибкое преобразование типов - добавлена возможность реализации операций с разными типами данных
  4. Глобальные настройки формата - введена переменная 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.

Обработка строк и кавычек

Одним из спорных моментов стало использование констант для кавычек:

const
  CNull = #0;
  CSingleQuote = '''';
  CDoubleQuote = '"';

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'

Это ограничение сохраняется и в модифицированной версии модуля.

Рекомендации по использованию

  1. Тестирование - перед переходом на новую версию тщательно протестируйте существующий код
  2. Инициализация переменных - всегда инициализируйте переменные для обеспечения совместимости
  3. Глобальные настройки - будьте осторожны с GExprParserFormatSettings, так как она влияет на все экземпляры парсера
  4. Обработка ошибок - учитывайте изменения в обработке ошибок и исключений

Заключение

Предложенные изменения в модуле fpexprpars представляют собой значительный шаг вперед в функциональности и надежности этого компонента. Однако, как показывает обсуждение, внедрение этих изменений требует тщательного тестирования и учета вопросов совместимости.

Для разработчиков на Delphi и Object Pascal эти изменения открывают новые возможности, но также требуют внимания к деталям реализации. Рекомендуется ознакомиться с полным списком изменений в файле changes.txt и провести собственное тестирование перед использованием модифицированной версии в production-среде.

Вероятно, оптимальным путем будет постепенное внедрение изменений через официальный баг-трекер FPC с разбивкой на небольшие, легко проверяемые части, как советует PascalDragon. Это повысит шансы на включение изменений в основную ветку разработки Free Pascal.

Создано по материалам из источника по ссылке.

Обновление модуля fpexprpars включает исправление багов, улучшение совместимости и добавление новых функций для более гибкой работы с математическими выражениями.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Процедуры и функции ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-04 06:32:46/0.0059318542480469/0