The components are intended for
Delphi developers and perform high-speed (about 10 million evaluations per
second) mathematics and boolean calculations. All components are available for Delphi
6, Delphi 7, Delphi 2005, Delphi 2006, Delphi 2007,
Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi
XE4, Delphi XE5, Delphi XE6, Delphi XE7, Delphi XE8, Delphi 10 Seattle, Delphi 10.1 Berlin.
Please note that the samples do not require components installation (however installation is
possible and in case when installed you find the components on "Samples" page of the pallete).
You may open the Delphi project file (*.dpr) in the sample folder and simply run it.
Introduction
The
best way to understand how parse components work is looking through the demo
program source code. Hence the material below contains the basic information.
Also, there are a number of samples to download with comprehensive information
on parse components. Each sample contains minimum source code and only that one
which covers the sample question. All the components are user-friendly and easy
for understanding and using them.
First
of all, we take a look at CalcUtils unit. This unit contains some simplest
methods for making calculations of any type. Then we pay attention to the
TCalculator component, which has many features - not only making calculations
of any type, but also expression optimization, making new variables,
multi-threaded mode and so on. After that we look through the TParser component
- the heart of calculation mechanism. TParser has many low-level methods and
properties and needed if you are going to extend its existing functionality.
However, TParser component is simple in use, according to its philosophy - for
example, it implements methods like AsByte, AsInteger, AsDouble, etc., having
the singular parameter of string type, which represents the mathematics
expression, and returning the number.
Brief
The components are intended for
programmers of all levels. It makes possible using the parse components at any
time without unnecessary understanding the internal parse mechanisms.
Some features of the parse
components:
- It
is possible compiling the expression into the script and further using
that script in calculations;
- It
is possible decompiling the expression into the string;
- It
is possible making user-defined functions. User-defined functions can be
of five types:
- A
function requiring no parameters. Such function simply returns some
result;
- A
function requiring parameter before itself;
- A
function requiring parameter after itself;
- A
function requiring both parameters - before and after itself;
- A
function requiring a number of parameters, following right after the
function and enclosed in round brackets. These parameters can be of string type;
- Each
function has a priority (meaningful only when function requires expression
before or after itself) determining its execution order within the
formula;
- It
is possible making variables;
- It
is possible making a direct reference to the simple variable of type like
Byte, Integer, etc.;
- It
is possible making constants;
- It
is possible making types;
- It
is possible optimizing the expression. Optimization is simplifying of
mathematic expression (if possible) at binary level; the result is an
increase in evaluation speed;
- It
is possible working in multi-threaded mode. Multi-threaded mode provides
the best performance due to simultaneous evaluation the elements in array
of expressions;
- It
is possible using the internal automatic thread - to use it we only need
to fill the expression array, start the execution and wait until all
threads are done. You are able to set up a number of parameters for
managing the threads, for example, define the amount of automatic
threads, adjust the priority of each automatic thread and more;
- It
is possible using user-defined (Classes.TThread inheritor) threads;
- It
is possible making variables and building a dependency chain of any depth,
where each variable depends on the previous one;
- It
is possible making your own variable lists (each element of the list looks
like NAME=VALUE) and connecting them to the parser.
CalcUtils
unit
This unit is for the quick
calculation of any expression. You just use the CalcUtils unit and apply its
methods. The methods below work at high speed:
- function
AsValue(const
Text: string): TValue;
- function
AsByte(const
Text: string): Byte;
- function
AsShortint(const
Text: string): Shortint;
- function
AsWord(const
Text: string): Word;
- function
AsSmallint(const
Text: string): Smallint;
- function
AsLongword(const
Text: string): Longword;
- function
AsInteger(const
Text: string): Integer;
- function
AsInt64(const
Text: string): Int64;
- function
AsSingle(const
Text: string): Single;
- function
AsDouble(const
Text: string): Double;
- function
AsExtended(const
Text: string): Extended;
- function
AsBoolean(const
Text: string): Boolean;
- function
AsPointer(const
Text: string): Pointer;
- function
AsString(const
Text: string): string;
- function
TryTextToValue(const
Text: string; out Value: TValue): Boolean;
- function
TryTextToByte(const
Text: string; out Value: Byte): Boolean;
- function
TryTextToShortint(const
Text: string; out Value: Shortint): Boolean;
- function
TryTextToWord(const
Text: string; out Value: Word): Boolean;
- function
TryTextToSmallint(const
Text: string; out Value: Smallint): Boolean;
- function
TryTextToLongword(const
Text: string; out Value: Longword): Boolean;
- function
TryTextToInteger(const
Text: string; out Value: Integer): Boolean;
- function
TryTextToInt64(const
Text: string; out Value: Int64): Boolean;
- function
TryTextToSingle(const
Text: string; out Value: Single): Boolean;
- function
TryTextToDouble(const
Text: string; out Value: Double): Boolean;
- function
TryTextToExtended(const
Text: string; out Value: Extended): Boolean;
- function
TryTextToBoolean(const
Text: string; out Value: Boolean): Boolean;
- function
TryTextToPointer(const
Text: string; out Value: Pointer): Boolean;
- function
TryTextToString(const
Text: string; out Value: string): Boolean;
- function
TextToValueDef(const
Text: string; const Default: TValue): TValue;
- function
TextToByteDef(const
Text: string; const Default: Byte): Byte;
- function
TextToShortintDef(const
Text: string; const Default: Shortint): Shortint;
- function
TextToWordDef(const
Text: string; const Default: Word): Word;
- function
TextToSmallintDef(const
Text: string; const Default: Smallint): Smallint;
- function
TextToLongwordDef(const
Text: string; const Default: Longword): Longword;
- function
TextToIntegerDef(const
Text: string; const Default: Integer): Integer;
- function
TextToInt64Def(const
Text: string; const Default: Int64): Int64;
- function
TextToSingleDef(const
Text: string; const Default: Single): Single;
- function
TextToDoubleDef(const
Text: string; const Default: Double): Double;
- function
TextToExtendedDef(const
Text: string; const Default: Extended): Extended;
- function
TextToBooleanDef(const
Text: string; const Default: Boolean): Boolean;
- function
TextToPointerDef(const
Text: string; const Default: Pointer): Pointer;
- function
TextToStringDef(const
Text: string; const Default: string): Pointer;
The methods calculate mathematics
expression (for example: "2 * 2"), which is in Text parameter.
TCalculator
component
The
component is intended for mathematics and boolean calculations. TCalculator is
fully-functional, stand-alone mathematics and multi-threaded shell for the
parser. It allows declaring your own variables, managing calculation process by
setting up the internal properties and accessing to the internal components. The
component philosophy is being easy in use and the primary aim is being fast in
calculations - even when parsing a big amount of different expressions.
All
calculations are performed by two ways:
- Compiling the expression into
the byte-code and then using it. This method is the fastest and makes
possible reaching the maximum calculation speed - about 10 million
iterations per second for the simplest formulas. For the formula like X *
2 + Y * 2 speed is about 2 million operations per second.
- Direct execution the expression.
It means passing the new string expression into the method each time when
it is necessary to get its result. It is not necessary for the new
expression to be the same all time. This method is slower than the first
one, but it is still very fast due to many tools in TCalculator, intended
for reaching the maximum performance.
TCalculator
has such an important thing as optimization mechanism. All expressions are
being optimized during the calculation process. Optimization is simplifying the
mathematic expression (if possible) at binary level; the result is increase of
evaluation speed when calculating by byte-code. TCalculator automatically
optimizes all expressions by default.
TCalculator
works in multi-threaded mode. Multi-threaded mode provides the best performance
due to simultaneous evaluation the elements in an array of expressions. Of
course to use the multi-threaded mode we first need to fill the expression
array. After that we start the execution in multi-thread mode and wait until all
threads are done. TCalculator has properties for managing the amount of
threads, adjusting the priority of each thread and much more. It also supports
using user-defined (Classes.TThread inheritor) threads.
TCalculator in use
Please
take a look at the following samples to see how TCalculator is simple in use:
1)
Evaluation of mathematic expression:

2)
Evaluation of Boolean expression:

3) Creation of "MyVar"
variable, initializing and using it in mathematic expression:

4) Running TCalculator in
multi-threaded mode:

It is necessary to say that there is
a difference between calling TParser.AsByte and TCalculator.AsByte or other
like-named methods, in spite of these methods do the same (from the user's
point of view). For example, TCalculator uses internal component TParseManager
- one more optimization mechanism, intended for the additional speedup.
TParser
component
TParser
is intended for mathematics and Boolean calculations and contains many of
standard functions, such as Sin (returns the sine of the angle in radians) or
Sqrt (returns the square root of the parameter), etc. It also contains standard
set of types, such as Byte or Word, which are used for specifying the
functions, variables and numbers. It is possible to create your own functions,
variables and types (AddFunction, AddVariable, AddType methods). It creates
binary representation of formula - script (StringToScript method, TScript =
Types.TByteDynArray) and makes the following calculations using the script
(Execute method). There are no limitations for the formula; it may have any
length and any amount of embedded formulas. The parser implements many
features, including methods for simplifying the formula (Optimize method). It
supports variables and functions with unlimited number of parameters. It also
supports script decompiling (ScriptToString method).
Expressions
can be constructed from operands, functions, variables and numbers.
- Operand makes some operation on
the expression:
- +: operand, executes adding
operation.
- –: operand, executes subtraction
operation.
- Function makes some calculation
on its parameters and returns the result. There are five types of function:
- A function which requires no
parameters. Such function simply returns some result. For example, True
(returns True value) function does not require any expression. It behaves itself like
variable.
- A function which require
parameter before itself. For example, ! function (returns factorial of an
expression) require expression before itself.
- A function which require
parameter after itself. For example, Int function (returns the integer
part of a number) requires expression after itself.
- A function which requires both
parameters - before and after itself. For example, ^ function (raises
expression to any power) requires both expressions - before and after
itself.
- A function which requires a
number of parameters, following right after the function and enclosed in
round brackets. For example, Sum function (returns the sum of all input
parameters) requires one or more parameters.
- Variable refers to a number and
behaves itself like function with no parameters. A number which variable
refers to is defined by the following structure:

- Number plays the role of
parameter for the function or takes part in operand operations.
The
list below contains all standard functions and its description:
- *:
function, executes multiplying operation;
- /:
function, executes division operation;
- Succ: function, returns
the successor of the parameter;
- Pred: function, returns
the predecessor of the parameter;
- not: function, performs
a bitwise NOT (negation) on the parameter;
- and: function, performs
a logical conjunction on two parameters;
- or: function, performs
a logical disjunction on two parameters;
- xor: function, performs
a logical exclusion on two parameters;
- shl: function, performs
a bitwise shift left on two parameters;
- shr: function, performs
a bitwise shift right on two parameters;
- SameValue (A: Double; B:Double;
Epsilon: Double = 0): function, returns True if two parameters are
(approximately) equal. Epsilon is the maximum amount by which A and B can
differ and still be considered the same value;
- IsZero (A: Double; Epsilon:
Double = 0):
function, returns True if parameter A is (approximately) zero or differs
from zero by at most Epsilon;
- If (AValue: Boolean; ATrue:
Expression; AFalse: Expression): function, checks the
expression passed as AValue and returns ATrue parameter if it evaluates to
true, or AFalse parameter if it evaluates to false. When using If
function, only one expression is being calculated - if AValue is True,
ATrue expression is being calculated, but AFalse is not; otherwise if
AValue is False, AFalse expression is being calculated, but ATrue is not;
- IfThen (AValue: Boolean; ATrue:
Expression; AFalse: Expression): function, checks the
expression passed as AValue and returns ATrue parameter if it evaluates to
true, or AFalse parameter if it evaluates to false. When using IfThen
function, both expressions - ATrue and AFalse are being calculated;
- EnsureRange (AValue, AMin, AMax:
Double):
function, returns the closest value to a specified value within a
specified range;
- StrToInt (S: string): function, converts
a string representing a decimal value to an integer;
- StrToIntDef (S: string; Default:
Integer):
function, converts the string S, which represents an integer-type number
in either decimal or hexadecimal notation, into a number. If S does not
represent a valid number, StrToIntDef returns Default;
- StrToFloat (S: string): function, converts
a given string to a floating-point value;
- StrToFloatDef (S: string;
Default: Double):
function, converts a given string into a floating-point value with error
Default;
- False:
function, returns 0;
- True:
function, returns 1;
- =: function, returns
True if two parameters are equal;
- <>: function, returns
True if two parameters are not equal;
- >: function, returns
True if first parameter is greater than second one;
- <: function, returns
True if first parameter is less than second one;
- >=: function, returns
True if first parameter is greater or equal to the second one;
- <=: function, returns
True if first parameter is less or equal to the second one;
- GetEpsilon: function, returns
the maximum amount by which A and B can differ and still be considered the
same value. Epsilon value required by compare functions, like SameValue,
IsZero, etc.;
- SetEpsilon (Value: Double): function, sets the
maximum amount by which A and B can differ and still be considered the
same value. Epsilon value required by compare functions, like SameValue,
IsZero, etc.;
- SetDecimalSeparat (S: string): function, sets the
character used to separate the integer part from the fractional part of a
number;
- div: functions, executes
integer division operation;
- mod: functions, executes
remainder operation;
- ^: function, raises
expression to any power;
- !: function, returns
factorial of an expression;
- Sqrt: functions, square
root of a number;
- Int: function, returns
the integer part of a number;
- Round: function, returns
the value rounded to the nearest whole number;
- RoundTo (Value: Extended; Digit:
Shortint):
function, rounds a floating-point value to a specified digit or power of
ten using "Banker's rounding";
- Trunc: function, truncates
a number to an integer;
- Abs: function, returns
an absolute value;
- Frac: function, returns
the fractional part of a number;
- Ln: function, returns
the natural log of an expression;
- Lg: function, returns
log base 10;
- Log: function, returns
the log of expression for a specified base;
- Exp: function, returns
the exponential of an expression;
- Random: function, returns
random number within the range 0 <= value < 1;
- Sin: function, returns
the sine of the angle in radians;
- ArcSin: function, returns
the inverse sine of a number;
- Sinh: function, returns
the hyperbolic sine of an angle;
- ArcSinh: function, returns
the inverse hyperbolic sine of a number;
- Cos: function, returns
the cosine of the angle in radians;
- ArcCos: function, returns
the inverse cosine of a number;
- Cosh: function, returns
the hyperbolic cosine of an angle;
- ArcCosh: function, returns
the inverse hyperbolic cosine of a number;
- Tan: function, returns
the tangent of the angle;
- ArcTan: function, returns
the arctangent of a number;
- Tanh: function, returns the
hyperbolic tangent of an angle;
- ArcTanh: function, the
inverse hyperbolic tangent of a number;
- Cotan: function, returns
the cotangent of the angle;
- ArcCotan: function, returns
the inverse cotangent of a number;
- Cotanh: function, returns
the hyperbolic cotangent of an angle;
- ArcCotanh: function, the
inverse hyperbolic cotangent of a number;
- Sec: function, returns
the secant of an angle;
- ArcSec: function, returns
the inverse secant of a number;
- Sech: function, returns
the hyperbolic secant of an angle;
- SrcSech: function, the
inverse hyperbolic secant of a number;
- Csc: function, returns
the cosecant of an angle;
- ArcCsc: function, returns
the inverse cosecant of a number;
- Csch: function, returns
the hyperbolic cosecant of an angle;
- ArcCsch: function, returns
the inverse hyperbolic secant of a number;
- ArcTan2 (Y, X: Double): function,
calculates ArcTan(Y/X), and returns an angle in the correct quadrant. The
values of X and Y must be between -2^64 and 2^64. In addition, the value
of X can't be 0. The return value will fall in the range from -Pi to Pi
radians;
- Hypot (X, Y: Double): function, returns
the length of the hypotenuse of a right triangle. Specify the lengths of
the sides adjacent to the right angle in X and Y. Hypot uses the formula
Sqrt(X*2 + Y*2) ;
- RadToDeg: function, converts
radians to degrees;
- RadToGrad: function, converts
radians to grads;
- RadToCycle: function, converts
radians to cycles;
- DegToRad: function, returns
the value of a degree measurement expressed in radians;
- DegToGrad: function, returns
the value of a degree measurement expressed in grads;
- DegToCycle: function, returns
the value of a degree measurement expressed in cycles;
- GradToRad: function, converts
grad measurements to radians;
- GradToDeg: function, converts
grad measurements to degrees;
- GradToCycle: function, converts
grad measurements to cycles;
- CycleToRad: function, converts
an angle measurement from cycles to radians;
- CycleToDeg: function, converts
an angle measurement from cycles to degrees;
- CycleToGrad: function, converts
an angle measurement from cycles to grads;
- LnXP1: function, returns
the natural log of (X+1);
- Log10: function,
calculates log base 10;
- Log2: function,
calculates log base 2;
- IntPower (Base: Double;
Exponent: Integer): function, calculates the integral power of a base
value;
- Power (Base: Double; Exponent:
Double):
function, Raises Base to any power;
- Ldexp (X: Double; P: Double): function,
calculates X times (2 to the power of P);
- Ceil: function, rounds
variables up toward positive infinity;
- Floor: function, rounds
variables toward negative infinity;
- Poly (X: Double;
Coefficients(1)..Coefficients(N): Double): function, evaluates a uniform
polynomial of one variable at the value X;
- Mean (Data(1)..Data(N): Double): function, returns
the average of all values in an array;
- Sum (Data(1)..Data(N): Double): function, returns
the sum of the elements in an array;
- SumInt (Data(1)..Data(N):
Integer):
function, returns the sum of the elements in an integer array;
- SumOfSquares (Data(1)..Data(N):
Double):
function, returns the sum of the squared values from a data array;
- MinValue (Data(1)..Data(N):
Double):
function, returns smallest signed value in an array;
- MinIntValue (Data(1)..Data(N):
Integer):
function, returns the smallest signed value in an integer array;
- MinValue (Data(1)..Data(N):
Double):
function, returns smallest signed value in an array;
- MaxValue (Data(1)..Data(N):
Double):
function, returns the largest signed value in an array;
- MaxIntValue (Data(1)..Data(N):
Integer):
function, returns the largest signed value in an integer array;
- MaxValue (Data(1)..Data(N):
Double):
function, returns the largest signed value in an array;
- StdDev (Data(1)..Data(N):
Double):
function, returns the sample standard deviation for elements in an array;
- PopnStdDev (Data(1)..Data(N):
Double):
function, calculates the population standard deviation;
- Variance (Data(1)..Data(N):
Double):
function, calculates statistical sample variance from an array of data;
- PopnVariance (Data(1)..Data(N):
Double):
function, calculates the population variance;
- TotalVariance (Data(1)..Data(N):
Double):
function, returns the statistical variance from an array of values;
- Norm (Data(1)..Data(N): Double): function, returns
the Euclidean 'L-2' norm;
- RandG (Mean, StdDev: Double): function, generates
random numbers with Gaussian distribution;
- RandomRange (AFrom, ATo:
Integer):
function, returns a random integer from a specified range;
- RandomFrom (Value(1)..Value(N):
Double):
function, returns a randomly selected element from an array;
- Pi:
variable, returns 3.1415926535897932385;
- New (VariableName: string;
Value: Double; Optimizable: Boolean = False): function, returns
True if new variable with name, defined by parameter VariableName
successfully created and its value set to parameter Value; otherwise
returns False; Parameter Optimizable determine whether or not the new
variable is optimizable. The
default value of parameter Optimizable is False;
- Delete (VariableName: string;
RaiseError: Boolean = True): function, returns True if
variable with name, defined by parameter VariableName successfully
deleted; otherwise raises exception if RaiseError is True or returns False
if RaiseError is False. The
default value of RaiseError parameter is True;
- Get (VariableName: string;
RaiseError: Boolean = True): function, returns variable
value, which defined by parameter VariableName; Function raises the
exception if RaiseError is True and variable with name VariableName not
found. The default
value of RaiseError parameter is True.
- Set (Name: string, Value:
Double; RaiseError: Boolean = True): function, returns True if
variable with name, defined by parameter Name, found and its value set to
parameter Value; otherwise raises exception if RaiseError is True or
returns False if RaiseError is False. The default value of RaiseError parameter is True;
- For (VariableName: string;
VariableValue: Integer; LoopCondition: Boolean; LoopExpression:
Expression):
function, loops the expression. For example: For ("A", 1,
Get("A") < 10, Set("A", Get("A") + 1)).
If variable with name, defined by parameter VariableName, does not exist,
it is created automatically and live until loop is done. Function sums the
results of expression, defined by parameter LoopExpression;
- Repeat (LoopExpression:
Expression; LoopCondition: Boolean): function, loops the
expression. For example: Repeat (Set("A", Get("A") +
1), Get("A") > 10) - in this case variable with name
"A" needs to be created beforehand. Function sums the results of
expression, defined by parameter LoopExpression;
- While (LoopCondition: Boolean;
LoopExpression: Expression): function, loops the
expression. For example: While (Get("A") < 10,
Set("A", Get("A") + 1)) in this case variable with
name "A" needs to be created beforehand. Function sums the
results of expression, defined by parameter LoopExpression.
TGraph component
TGraph component is intended for building the graph in rectangular and polar coodrinate systems.
Please take a look at some samples showing colorful graphs:



