Recent

Author Topic: Update fpexprpars  (Read 1778 times)

ASerge

  • Hero Member
  • *****
  • Posts: 2411
Update fpexprpars
« on: April 05, 2025, 10:44:46 am »
I decided to post here the changes I made in the standard fpexprpars.pp unit.
Why here, and not in gitlab? Because admins really don't like units, that have changed so much that it haven't .diff file.

Include:
fpexprpars2.pp - modified version of fpexprpars.pp.
testexprpars2.pp - modified version of testexprpars.pp (unit test).
fpexprpars.pp - last version from gitlab. For compare.
testexprpars.pp - last version from gitlab. For compare.
changes.txt - description of what has changed.
GuiTest.lpr - simple project for unit testing.

The number two is added to the name to avoid conflict with the existing name, and to be able to try different versions of the module in the same project.

In order not to annoy the admins, I left the testexprpars2.pp as similar as possible to the original version. That it 's easy for it to do .the diff file.
I rolled back some changes, for example, I returned the comparison of double values as it was - through the implicit conversion of double to currency.
And left "uninitialized variables", etc., which do not affect the result.
The unit testexprpars2.pp is compatible with the previous fpexprpars.pp version, except that new bugs are fixed in it. New features added via conditional compilation.
Some obvious bugs with memory leaks, etc. eliminated.

I decided to roll back some features from the fpexprpars2.pp unit as well:
Generating an error on numbers like ".E-1", which are considered valid zero by the System.Str function.
Advanced type conversion that allows you to perform such operations: sum(1, 2,  '3', True). But added the ability to easily implement it.

I ask those who have used this unit in real projects to test it.
And also the admins should take a closer look, maybe it's include it in the source code.
« Last Edit: April 05, 2025, 10:47:07 am by ASerge »

wp

  • Hero Member
  • *****
  • Posts: 12799
Re: Update fpexprpars
« Reply #1 on: April 05, 2025, 10:50:25 am »
I am afraid that when you don't describe what you changed and why nobody will look at it. And you attachment does not contain all the other files that you mention.

d2010

  • Full Member
  • ***
  • Posts: 161
Re: Update fpexprpars
« Reply #2 on: April 05, 2025, 11:27:04 am »
And left "uninitialized variables", etc., which do not affect the result.
And also the admins should take a closer look, maybe it's include it in the source code.
Okai You repair Lazarus or fpc, but you forget exists others compilators,
(some are weak, the VirtualPascaL or GnuPascal is less FPC.exe)
 :(That reason, you cannot RE-fix the LazarusParser.

Always I initialize the variabiles at top of function/s, even inside "Lazarus".
Some others (Virtual Pascal.exe, DelphiXe Or Gnu Pascal) , report the "nth" is not initialized , so they cannot complier before "FOR nth:="
, I put  "    nth:=000;" at ???
Code: [Select]
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;
« Last Edit: April 05, 2025, 11:34:10 am by d2010 »

cdbc

  • Hero Member
  • *****
  • Posts: 2138
    • http://www.cdbc.dk
Re: Update fpexprpars
« Reply #3 on: April 05, 2025, 11:29:30 am »
Hi
Hmmm, @wp: I've got all the files he described...  %)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

wp

  • Hero Member
  • *****
  • Posts: 12799
Re: Update fpexprpars
« Reply #4 on: April 05, 2025, 12:00:18 pm »
Yes, the attachment has been replaced now. I ran a diff between fpexprpars and fpexprpars2, and it is full of differences. So, I stick to my opinion that this submission is useless without any description of the changes.

ASerge

  • Hero Member
  • *****
  • Posts: 2411
Re: Update fpexprpars
« Reply #5 on: April 05, 2025, 12:05:10 pm »
Yes, the attachment has been replaced now. I ran a diff between fpexprpars and fpexprpars2, and it is full of differences. So, I stick to my opinion that this submission is useless without any description of the changes.
See changes.txt.

ASerge

  • Hero Member
  • *****
  • Posts: 2411
Re: Update fpexprpars
« Reply #6 on: April 05, 2025, 12:07:14 pm »
Okai You repair Lazarus or fpc, but you forget exists others compilators,
(some are weak, the VirtualPascaL or GnuPascal is less FPC.exe)
 :(That reason, you cannot RE-fix the LazarusParser.
These are not my mistakes, I left them in the code to make it more similar to the previous version. Did you see how outraged @wp was that there were a lot of changes?

wp

  • Hero Member
  • *****
  • Posts: 12799
Re: Update fpexprpars
« Reply #7 on: April 05, 2025, 12:31:12 pm »
Sorry, if I gave the impression that I am "outraged" - I am not. I just did not notice "changes.txt". It lists a lot of important changes which should be added from my point of view. But I am sure that unless you split that entire topic into small pieces you will have a hard time in the bug tracker to convince MvC... (BTW: I already had proposed including the formatsettings some time ago, and he rejected it).

CM630

  • Hero Member
  • *****
  • Posts: 1340
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Update fpexprpars
« Reply #8 on: April 07, 2025, 09:13:09 am »
From the changes.txt file, I get the impression that it partially solves https://gitlab.com/freepascal.org/fpc/source/-/issues/39351.
But still in fpexprpars2.pp there is:
Code: Pascal  [Select][+][-]
  1. const
  2.   CNull = #0;
  3.   CSingleQuote = '''';
  4.   CDoubleQuote = '"';
It would be better if CSingleQuote was not a constant, so strings from Excel and other languages could be handled ditrectly.
And maybe, some handling of thousands separators (#20; #194#160 etc.) might be useful.

EDIT: I tried an app using fpexprpars.
The following code compiles and works with fpexprpars, but does not compile with fpexprpars2.

Code: Pascal  [Select][+][-]
  1. //Converts a number to binary. Example bin(45) returns %0010 1101; bin($45) returns %0010 1101;
  2. ...
  3.   BuiltinIdentifiers.AddFunction(bcMath, 'bin',     'S', 'I',  @ExprBin);
  4. ...
  5.  
  6. procedure ExprBin(var Result: TFPExpressionResult; Const Args: TExprParameterArray);
  7. var
  8.   Argument: Longint;
  9.   i: integer;
  10. begin
  11.   Argument:= Args[0].ResInteger;
  12.   Result.ResString := Dec2Numb (Argument,0,2);
  13.   if length(Result.ResString) mod 8 <> 0
  14.     then Result.ResString := addchar('0',Result.ResString,8*(trunc(length(Result.ResString)/8)+1));
  15.  
  16.   for i:= 1 to trunc(Length(Result.ResString) / 4)-1 do
  17.     Insert (' ',Result.ResString,i*4+i);
  18.  
  19.   Result.ResString := '%' + Result.ResString;
  20. end;  

(...Error: Can't take the address of constant expressions on line 17)
« Last Edit: April 07, 2025, 09:32:46 am by CM630 »
Лазар 4,0 32 bit (sometimes 64 bit); FPC3,2,2

ASerge

  • Hero Member
  • *****
  • Posts: 2411
Re: Update fpexprpars
« Reply #9 on: April 08, 2025, 03:28:52 am »
(...Error: Can't take the address of constant expressions on line 17)
For safety ResString now a property, not a field.

As for the thousands separator, RTL does not process it yet either:
Code: Pascal  [Select][+][-]
  1. DefaultFormatSettings.ThousandSeparator := '#';
  2. if TryStrToFloat('1#000', D) then
  3.   Writeln(D:0:0)
  4. else
  5.   Writeln('Bad number');
  6.  
print "Bad number".

You're right about the quotation marks. It's not difficult to make global variables instead of constants. The same applies to other separators. Just have to add code that checks when parsing expressions that they don't match each other.

CM630

  • Hero Member
  • *****
  • Posts: 1340
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Update fpexprpars
« Reply #10 on: April 08, 2025, 08:30:44 am »
For safety ResString now a property, not a field.
Definitely a good intention, but how many projects might be broken (I have updated the quoted code, now it works both with fpexprpars and fpexprpars2)?
A couple of weeks ago, I was surprised to find out that it was me who reported a bug that fpexprpars does not handle division on zero, which maybe means that the component is not widely used, so no big harm could happen with that change.

As for the thousands separator, RTL does not process it yet either:
Code: Pascal  [Select][+][-]
  1. DefaultFormatSettings.ThousandSeparator := '#';
  2. if TryStrToFloat('1#000', D) then
  3.   Writeln(D:0:0)
  4. else
  5.   Writeln('Bad number');
  6.  
print "Bad number".
Maybe this is not handleable. SI strictly prohibits separators different than a space (which I believe does not exclude #194#160 and other spaces), but it occurs that even outside USA unbelievable characters are used for thousand separators.

You're right about the quotation marks. It's not difficult to make global variables instead of constants. The same applies to other separators. Just have to add code that checks when parsing expressions that they don't match each other.

Recently, I tried to fix the fixed separator issue. I got stuck when I came to Single and Double quoutation marks.
Double quotes are not documented; maybe their handling could be disabled if they are set to an empty string? Otherwise the user shall set it to character, that will never occur, maybe something < 0x20.

EDIT: I do not understand how GExprParserFormatSettings is to be used. It is not a property but a variable %)
« Last Edit: April 08, 2025, 01:46:10 pm by CM630 »
Лазар 4,0 32 bit (sometimes 64 bit); FPC3,2,2

ASerge

  • Hero Member
  • *****
  • Posts: 2411
Re: Update fpexprpars
« Reply #11 on: April 08, 2025, 09:18:43 pm »
I do not understand how GExprParserFormatSettings is to be used. It is not a property but a variable %)
Did you read changes.txt?

CM630

  • Hero Member
  • *****
  • Posts: 1340
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Update fpexprpars
« Reply #12 on: April 09, 2025, 10:16:34 am »
Did you read changes.txt?
That is the first thing I  did.
Still I do not get the idea:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, fpexprpars2;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.   private
  18.  
  19.   public
  20.  
  21.   end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. { TForm1 }
  31.  
  32. procedure TForm1.Button1Click(Sender: TObject);
  33.   var
  34.   FParser1: TFPExpressionParser;
  35.   FParser2: TFPExpressionParser;
  36.   resultValue: Double;
  37. begin
  38.   FParser1 := TFPExpressionParser.Create(nil);
  39.   try
  40.     FParser1.BuiltIns := [bcMath];
  41.     GExprParserFormatSettings.ListSeparator := ';';
  42.     GExprParserFormatSettings.DecimalSeparator := ',';
  43.     FParser1.Expression := '1,5*2';
  44.     resultValue := FParser1.Evaluate.ResFloat;
  45.     ShowMessage(FParser1.Expression + ' = ' + FloatToStr(resultValue));
  46.   finally
  47.     FParser1.Free;
  48.   end;
  49.  
  50.   FParser2 := TFPExpressionParser.Create(nil);
  51.   try
  52.     FParser2.BuiltIns := [bcMath];
  53.     FParser2.Expression := '1.5*2'; //This is not accepted, the parser still expects 1,5
  54.     resultValue := FParser2.Evaluate.ResFloat;
  55.     ShowMessage(FParser2.Expression + ' = ' + FloatToStr(resultValue));
  56.   finally
  57.     FParser2.Free;
  58.   end;
  59. end;
  60.  
  61.  
  62. end.
  63.  
  64.  
  65.  

GExprParserFormatSettings is global, if I have 5 instances of TFPExpressionParser, I have to set GExprParserFormatSettings before each FParser.Expression := xxx and still I am not sure that things will not get messed up. Am I missing something?
« Last Edit: April 09, 2025, 10:20:26 am by CM630 »
Лазар 4,0 32 bit (sometimes 64 bit); FPC3,2,2

ASerge

  • Hero Member
  • *****
  • Posts: 2411
Re: Update fpexprpars
« Reply #13 on: April 09, 2025, 06:07:12 pm »
Am I missing something?
Yes, that's right. This is done to simplify things. All intermediate classes, built-in functions, etc. use a single variable. If link between instances of classes to get to the parent one containing such a variable, many functions will be overgrown with parameters or additional functions.
Even now, in a simplified form, admins do not want to use innovations, because there are a lot of them. And if all classes are overgrown with additional parameters, then compatibility will disappear. Then it will definitely be buried.
New changes can be made after the accepting of the simplified version.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5967
  • Compiler Developer
Re: Update fpexprpars
« Reply #14 on: April 10, 2025, 09:05:31 pm »
New changes can be made after the accepting of the simplified version.

Unless you can split this up into smaller, incremental changes that can be reviewed there will be no “accepting”.

 

TinyPortal © 2005-2018