Recent

Author Topic: About TFPExpressionParser  (Read 23988 times)

wp

  • Hero Member
  • *****
  • Posts: 12772
Re: About TFPExpressionParser
« Reply #15 on: February 01, 2013, 12:44:08 am »
Nice. But an unlimited number or argument would be better. How about introducing a new symbol for the type of the input parameters? Maybe a lowercase f to indicate a variable number of floating point arguments, the number of f's indicates the minimum argument count. I don't know where to define that, but the comment in the Primitive method says that the parser is able to handle a variable number of arguments.

bigeno

  • Sr. Member
  • ****
  • Posts: 266
Re: About TFPExpressionParser
« Reply #16 on: February 01, 2013, 10:24:56 am »
indeed, when you have only one variable defined (v1) then it crash with
sum(1,2,3,4) + v1

this patch should fix problem with invalid argument count (it increases the number of arguments when it finds a comma).

so it is enough to apply only the second part of this patch and call
  FParser.Identifiers.AddFunction('sum', 'F', 'F', @ExprSum)
always only with 'F' as AParamTypes.

Code: [Select]
          Args[AI]:=Level1;
          Inc(AI);
          If (TokenType<>ttComma) then
            If (AI<Abs(ACount)) then begin
+              if (TokenType=ttRight) then begin              //if find end but argument count indicates more
+                 SetLength(Args,AI);
+                 break;
+              end else
                 ParserError(Format(SErrCommaExpected,[Scanner.Pos,CurrentToken]));
            end;
+          If (TokenType=ttComma) and (AI=ACount) then begin //if find other arg. but argument count indicates less
+            Inc(ACount);
+            SetLength(Args,ACount);
+            Args[ACount-1]:=Nil;
+            ID.ParameterTypes:=ID.ParameterTypes+ID.ParameterTypes[1];
+          end;

        Until (AI=ACount) or ((ACount<0) and (TokenType=ttRight));

limitation is to use the same type of all parameters.

What do you think about this?
« Last Edit: February 01, 2013, 10:27:07 am by bigeno »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12156
  • FPC developer.
Re: About TFPExpressionParser
« Reply #17 on: February 01, 2013, 07:19:19 pm »
Nice. But an unlimited number or argument would be better. 

See how Symbolic does it. One can get a list of unknown tokens after parsing. You need this for cases where the user inputs the equation.

But of course you are then stuck in a parse - fill parameters - evaluate step.

jmpessoa

  • Hero Member
  • *****
  • Posts: 2327
Re: About TFPExpressionParser
« Reply #18 on: February 05, 2013, 03:59:52 pm »
Hi Wp, in the implementation section of unit mpmath,

there are:

------------------
implementation

uses
  Math,
  typ, mpspe;  // numlib

-----------------------------

1. Why  numlib was commented?

2. Where is mpspe unit?

-----------------------

3. Danger!!!

In the absence (my lazarus 1.1 windows) of the mpspe unit
I  uncommented numlib.... ok work.

But, when I put mpmath in my component: IDE crashed!

"TpNumLib.dll is missing........."  :-[

Help!

Thank you!



 



Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

wp

  • Hero Member
  • *****
  • Posts: 12772
Re: About TFPExpressionParser
« Reply #19 on: February 05, 2013, 05:30:20 pm »
I guess that something is wrong with your installation, I don't use any DLL. The units "typ" and "mpspe" belong to FreePascal's numlib (that is indicated by the comment at the end of that line); in my default installation (Win32) they are in "C:\lazarus\fpc\2.6.0\source\packages\numlib".

You can remove these units, then you won't be able to use error function and the bessel functions in the parser. Maybe you can live with that. But at first, you should check out what's wrong with your Lazarus installation.

jmpessoa

  • Hero Member
  • *****
  • Posts: 2327
Re: About TFPExpressionParser
« Reply #20 on: February 05, 2013, 05:35:59 pm »

Thank You Wp!

Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

jmpessoa

  • Hero Member
  • *****
  • Posts: 2327
Re: About TFPExpressionParser
« Reply #21 on: February 05, 2013, 08:35:57 pm »

Newsworthy,

1. In my path (lazarus 1.1 - fpc\2.61- win7)

"C:\lazarus\fpc\2.6.1\source\packages\numlib"

I  dont have "mpspe" just only "numlib" and "typ"

2. I noticed that in \component\tachart

have \numlib_fix with units: "ipf" , "mdt" ,  "sle" , "spe" ...

 This is a replacement for "mpspe"?

Thanks!
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

wp

  • Hero Member
  • *****
  • Posts: 12772
Re: About TFPExpressionParser
« Reply #22 on: February 05, 2013, 09:37:29 pm »
O no - I am stupid: As I see now mpspe is not an official unit of the fpc numlib, it is a special version which I had adapted to return NaN in case of illegal arguments - see my description of the parser a few postings above. You may use the original unit called spe, but mine integrates better into the modified parser. It is in the attachment. Sorry for the confusion.

jmpessoa

  • Hero Member
  • *****
  • Posts: 2327
Re: About TFPExpressionParser
« Reply #23 on: February 05, 2013, 10:19:45 pm »
 
Your help has been essential!

Thank you again!
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

jmpessoa

  • Hero Member
  • *****
  • Posts: 2327
Re: About TFPExpressionParser
« Reply #24 on: February 13, 2013, 09:57:03 pm »
Hi There!

The new component TFPMathExpressionBridge is a warapper for the math subset
of TFPExpressionParse (fpexprpars.pas) attempting to establish a intuitive semantics
for construction of function graph and expression evaluete.
More specifically the underline code used here is a WP revision and addOns. (Thank you WP!)

Attached content:

1. tfpmathexpressionbridge_lazarus_package  -  Component install
2. tfpmathexpressionbridge_demo1            -  TAChart FuncSeries example
3. tfpmathexpressionbridge_demo2            -  TAChart ParametricCurveSeries example (need r40137)

About TFPExpressionParser and Wp addOns follow there  ;D

App Demo 2 use "TParametricCurveSeries" added to unit "tafuncseries.pas" on TAChart revision 40137
http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/components/tachart/tafuncseries.pas?annotate=40137&root=lazarus&pathrev=40137

about TAChart TParametricCurveSeries follow this:
http://www.lazarus.freepascal.org/index.php/topic,19627.msg111853.html#msg111853

The TFPMathExpressionBridge "readme.txt":

TFPMathExpressionBridge - Version 0.1 - 02/2013

Author: Jose Marques Pessoa : jmpessoa__hotmail_com

Acknowledgment: Thank you WP!

TFPMathExpressionBridge is a warapper for [math]* subset
of TFPExpressionParse** attempting to establish a easy semantics
for construction of function graph and expression evaluete.

0. Warning: at the moment this code is just a "proof-of-concept".

1.Data

1.1 Add Data
 
  Add Constants
  Add Variables
  Add Expressions
 
  use:
 
  AddConstant('k')
  AddVariable('x')
  AddExpression('kx+1')
 
  Obs.: Data are Case Insensitive!

1.2 Set Data

  Set Expression            //triggers OnConstantParse...
  use: Expression:= 'k*x+1'

  or by Helpers:
   procedure SetExpressionByIndex(Index: integer);
   function GetExpressionByIndex(Index: integer): string;
   function GetExpressionIndexByName(AName: string): integer;

  Set VariableOfFunc     //variable of "functions of one variable"
  use: VariableOfFunc:= 'x'

2.Evaluete
2.1 Function Evaluete

  function EvalFunc(AValue: real)                //eval function for one variable....
  use: EvalFunc(AValue)

  function EvalFunc(AValues: array of real)      //eval function for many variables...
  use:EvalFunc([AValue1, AValue2, AValue3])

2.2 Expression Evaluete //event driver

  function EvalExpr(Expr: string; ANamesVar: array of string)
  use:  EvalExpr('A*x**x+ B*x + C', ['x','A','B','C']) //triggers OnVariableParse

  function EvalExpr
  use:
  AddConstant('A')
  AddConstant('B')
  AddConstant('C')
  AddVariable('x')
  Expression:= 'A*x**x+ B*x + k*C'
  EvalExpr; //triggers OnVariableParse

3. Events
3.1 OnConstantParse  //triggers every time Expression is Set.....

    use: handle to set constant value

3.2 OnVariableParse  //triggers every time EvalExpr is called.....

    use: handle to set variable value

4.Add "building" function

  //signature:
  type
    TExprFunc = procedure(Var Result: TFPExpressionResult; Const Args: TExprParameterArray);

  //"building" funtion code example:
  Procedure ExprDelta(Var Result: TFPExpressionResult; Const Args: TExprParameterArray);
  var
    a,b,c: Double;
  begin
   a := ArgToFloat(Args[0]);
   b := ArgToFloat(Args[1]);
   c := ArgToFloat(Args[2]);

   if IsNumber(a) and IsNumber(b) and IsNumber(c) then
      Result.resFloat := b*b - 4*a*c
   else
      result.resFloat := NaN;
  end;   
   
4.1 AddFunction(AName: string; paramCount: integer; callFunc: TExprFunc)
 
  Use:
   AddFunction('Delta', 3, @ExprDelta);
 
  Use:
   Expression:='Delta(2,4,1)';
   EvalExpr;

5. Have Fun!
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

wp

  • Hero Member
  • *****
  • Posts: 12772
Re: About TFPExpressionParser
« Reply #25 on: February 13, 2013, 11:12:27 pm »
Thank you for sharing.

One comment:
If you add the units fpexprpars_wp.pp, mpmath_wp.pas, mpspe_wp.pas to the package you would not need them explicitely again in the demo projects.

jmpessoa

  • Hero Member
  • *****
  • Posts: 2327
Re: About TFPExpressionParser
« Reply #26 on: February 14, 2013, 12:13:24 am »
Ok.

I'll do it for an upcoming release.

Thanks for the suggestion!

Greetings!
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

CM630

  • Hero Member
  • *****
  • Posts: 1315
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: About TFPExpressionParser
« Reply #27 on: November 27, 2019, 06:59:41 am »
I tried TFPExpressionParser yesterday, I have some issues:

1. mod does not work.

2. min does not like its params and also does not work.


Code: Pascal  [Select][+][-]
  1. uses
  2.  
  3.   ...fpexprpars,math;
  4. ...
  5.  
  6.  
  7. procedure TForm1.Button1Click(Sender: TObject);
  8. var
  9.   FParser: TFPExpressionParser;
  10.   parserResult : TFPExpressionResult;
  11. begin
  12.   FParser := TFPExpressionParser.Create(nil);
  13.   FParser.Builtins := FParser.Builtins + [bcMath] + [bcAggregate] ;
  14.   try
  15.     ShowMessage (IntToStr (min(3,5)));
  16.     FParser.Expression := 'min(1,2)';
  17.     parserResult := FParser.Evaluate;
  18.   except
  19.     ShowMessage ('Error');
  20.   end;
  21.  
  22.  
  23.   try
  24.     ShowMessage (IntToStr (8 mod 3));
  25.     FParser.Expression := '8 mod 3';
  26.     parserResult := FParser.Evaluate;
  27.   except
  28.     ShowMessage ('Error');
  29.   end;
  30.   FParser.Free;
  31. end;  

Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

Thaddy

  • Hero Member
  • *****
  • Posts: 16813
  • Ceterum censeo Trump esse delendam
Re: About TFPExpressionParser
« Reply #28 on: November 27, 2019, 08:09:23 am »
1. mod works!
2. you're right.
I reworked your code a bit:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. uses
  3.  sysutils, fpexprpars,math;
  4. var
  5.   FParser: TFPExpressionParser;
  6. begin
  7.   FParser := TFPExpressionParser.Create(nil);
  8.   FParser.Builtins :=[bcStrings,bcDateTime,bcMath,bcBoolean,bcConversion,bcData,bcVaria,bcUser,bcAggregate];
  9.   try
  10.     writeln(8 mod 3);
  11.     FParser.Expression := '8 mod 3';
  12.     FParser.Evaluate;
  13.     writeln(FParser.AsInteger);
  14.   except
  15.      On E:EExprParser do
  16.        writeln(E.Message)
  17.      else Raise;
  18.   end;
  19.  
  20.   try
  21.     writeln(min(3,5));
  22.     FParser.Expression := 'min(3,5)';
  23.     FParser.Evaluate;
  24.     writeln(FParser.AsInteger);
  25.   except
  26.     on E:EExprParser do
  27.       writeln(E.Message)
  28.     else Raise;
  29.   end;
  30.   FParser.Free;
  31. end.

Tested with trunk. 

Output:
Code: Bash  [Select][+][-]
  1. 2
  2. 2
  3. 3
  4. Expected ) bracket at position 7, but got ,
« Last Edit: November 27, 2019, 08:14:05 am by Thaddy »
Changing servers. thaddy.com may be temporary unreachable but restored when the domain name transfer is done.

CM630

  • Hero Member
  • *****
  • Posts: 1315
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: About TFPExpressionParser
« Reply #29 on: November 27, 2019, 09:19:39 am »
Still does not work for me, using your modifications. I get "Badly terminated expression. Found token at position 6 : mod".
Version@: 2.0.4; Date 2019-11-07; FPC Version: 3.0.4; Svn Revision: 61665; i386-win32-win32/win64.
Maybe my Lazarus version is too old  :-\
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

 

TinyPortal © 2005-2018