fpexprpars.txt 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. The fpexprpars unit contains an expression parser.
  2. The parser compiles the expression into a node tree, which is
  3. type checked after it was compiled.
  4. The expression parser handles the following types:
  5. String
  6. Integer (64-bit)
  7. Float (TExprFloat, normally Double)
  8. TDateTime
  9. Boolean
  10. The following operations are allowed:
  11. + - / *
  12. not and or xor
  13. ( )
  14. The binary operations can also be done on integer values, in which
  15. case they act on the bits of the integer.
  16. In the case of strings addition results in concatenation of the strings.
  17. Operator precedence is observed. In case of equal precedence, evaluation
  18. order is left-to-right.
  19. Normally, both operands of binary operations must have the same type.
  20. There are 2 exceptions: The engine will convert integers to float or
  21. TDateTime if it detects that one of the nodes is a float or datetime.
  22. The engine can be extended with variables and functions. There are over
  23. 60 built-in functions, which can be enabled by setting the Builtins property
  24. of the expression parser to a set of the following values:
  25. bcStrings: Various string routines
  26. length copy delete pos lowercase uppercase stringreplace comparetext
  27. bcDateTime: Various datetime routines
  28. date time now dayofweek extractyear extractmonth extractday extracthour
  29. extractmin extractsec extractmsec encodedate encodetime encodedatetime
  30. shortdayname shortmonthname longdayname longmonthname formatdatetime
  31. bcMath: Various mathematical routines
  32. pi cos sin arctan abs sqr sqrt exp ln log frac int round trunc
  33. bcBoolean: Various boolean routines
  34. shl shr IFS IFF IFD IFI
  35. bcConversion : Conversion routines
  36. inttostr strtoint strtointdef floattostr strtofloat strtofloatdef
  37. booltostr strtobool strtobooldef datetostr timetostr strtodate strtodatedef
  38. strtotime strtotimedef strtodatetime strtodatetimedef
  39. Additional functions/variables can be added to the Identifiers collection:
  40. FP : TFPexpressionParser;
  41. The following will define a TODAY variable which has value equal to the date
  42. at the moment is is defined:
  43. FP.Identifiers.AddDateTimeVariable('TODAY',Date);
  44. The following will define a function echodate:
  45. Procedure EchoDate(Var Result : TFPExpressionResult; Const Args : TExprParameterArray);
  46. begin
  47. Result.resDateTime:=Args[0].resDateTime;
  48. end;
  49. FP.Identifiers.AddFunction('EchoDate','D','D',@EchoDate);
  50. The arguments are:
  51. Name : Name of the function
  52. Result type : Character with result type:
  53. I : integer
  54. S : String
  55. F : FLoat
  56. D : TDateTime
  57. B : Boolean
  58. Argument types : A string with each character the type of argument at that position.
  59. Callback : executed when the function is called. This can be a procedural
  60. variable or an event (procedure of object).
  61. Result and arguments are type-checked.
  62. The engine knows 2 built-in functions which are handled specially:
  63. IF(Expr,Res1,Res1)
  64. Will return Res1 if expr evaluates to True, or Res2 if expr evaluates to False.
  65. The types of Res1 and Res2 must be the same, and expr must be a boolean
  66. expression.
  67. CASE(Tag,Def,Label1,Value1,Label2,Value2,...)
  68. Case will examine the value of Tag and compare it with Label1, Label2 etc.
  69. till a match is found. It will return Value1, Value2 etc. depending on the
  70. match. If no match is found, Def will be returned. From this it follows that
  71. 1) The number of arguments is always even and is at least 4.
  72. 2) The types of Tag, label1, label2 must be the same;
  73. 3) The types of Def, Value1, Value2 must be the same;
  74. As soon as the expression is set, it is compiled and checked. Thus
  75. FP.Expression:='1*2';
  76. will work.
  77. On the other hand
  78. FP.Expression:=' 1 * ''a string''';
  79. will result in an exception because 1 and ''a string'' do not have the same
  80. type.
  81. Getting the result is quite simple
  82. FP.Expression:='1*2';
  83. Writeln(FP.AsInteger);
  84. This will raise an exception if the type of the result is not integer.
  85. In case the expression result type is unknown, it can be examined using
  86. the ResultType function, as in :
  87. FP.Expression:='Some user-provided expression';
  88. Case FP.ResultType of
  89. rtString : Writeln(FP.Evaluate.ResString);
  90. rtInteger : Writeln(FP.Evaluate.ResInteger);
  91. rtFloat : Writeln(FP.Evaluate.ResFloat);
  92. rtBoolean : Writeln(FP.Evaluate.ResBoolean);
  93. rtDateTime : Writeln(FormatDateTime('cccc',FP.Evaluate.ResDateTime));
  94. end;
  95. Which is equivalent to
  96. FP.Expression:='Some user-provided expression';
  97. Case FP.ResultType of
  98. rtString : Writeln(FP.AsString);
  99. rtInteger : Writeln(FP.AsInteger);
  100. rtFloat : Writeln(FP.AsFloat);
  101. rtBoolean : Writeln(FP.AsBoolean);
  102. rtDateTime : Writeln(FormatDateTime('cccc',FP.AsDateTime));
  103. end;