-
Notifications
You must be signed in to change notification settings - Fork 0
Evaluating an expression
The Parser
class have a property Expr
which holds the expression to be evaluated.
parser.Expr = "1 + 1";
Expression evaluation is done by calling the Eval()
member function of a parser object. When evaluating an expression for the first time the parser evaluates the expression string directly and creates a bytecode during this first time evaluation. Every sucessive call to Eval()
will evaluate the bytecode directly unless you call a function that will silently reset the parser to string parse mode. Some functions invalidate the bytecode due to possible changes in callback function pointers or variable addresses. By doing so they effectively cause a recreation of the bytecode during the next call to Eval()
.
Internally there are different evaluation functions. One for parsing from a string, the other for parsing from bytecode (and a third one used only if the expression can be simplified to a constant). Initially, Eval()
will call the string parsing function which is slow due to all the necessary syntax checking, variable lookup, and bytecode creation. Once this function succeeds, Eval()
will change its internal parse function pointer to either the bytecode parsing function or the const result function which are significantly (approx. 1000 times) faster. You don't have to worry about this, it's done automatically, just keep in mind that the first time evaluation of an expression is significantly slower than any successive call to Eval()
.
try
{
double val = parser.Eval();
}
catch (ParserError e)
{
Console.WriteLine(e.Message);
}
If the expression contains multiple separated subexpressions the return value of Eval()
is the result of the last subexpression. If you need all of the results use the functions described in the next sections.
muParser
and, consequently, muParserNET
accepts expressions that are made up of several subexpressions delimited by the function argument separator. For instance take a look at the following expression:
sin(x),y+x,x*x
It is made up of three expression separated by commas hence it will create three return values. (Assuming the comma is defined as the argument separator). Their value can be queried with the call of the EvalMulti
function. This returns an array of double
holding the actual values with the first value at the botton of the array and the last at the top.
double[] vals = p.EvalMulti();
for (int i = 0; i < vals.Length; i++)
{
Console.WriteLine(vals[i]);
}
The basic idea behind the bulkmode is to minimize the overhead of function calls and loops when using muParser
inside of large loops. Each loop turn requires a distinct set of variables and setting these variables followed by calling the evaluation function can by slow if the loop is implemented in a managed language. This overhead can be minimized by precalculating the variable values and calling just a single evaluation function. In reality the bulkmode doesn't make much of a difference when used in C++ but it brings a significant increase in performance when used in .NET applications. If muParser
was compiled with OpenMP support the calculation load will be spread among all available CPU cores. When using the bulk mode variables created with DefineVar
function must be initializated with arrays instead of single variables. All variable arrays must have the same size and each array index represents a distinct set of variables to be used in the expression.
try
{
Parser p = new Parser();
p.DefineVar("a", new double[]{ 1, 2, 3, 4, 5});
p.DefineVar("b", new double[]{ 6, 7, 8, 9, 10});
p.Expr = "a + b";
double[] results = p.EvalBulk(5);
for (int i = 0; i < results.Length; i++)
{
Console.WriteLine(results[i]);
}
}
catch (ParserError e)
{
Console.WriteLine(e.Message);
}
- Getting started
- Setting and evaluating an expression
- Setting the expression
- Single return expression evaluation
- Multiple return expression evaluation
- Bulk mode evaluations
- Error handling
- Defining identifier charsets
- Defining parser variables
- Explicitely defining variables
- Implicit creation of new variables
- Querying parser variables
- Removing variables
- Defining constants
- Defining parser constants
- Querying parser constants
- Removing constants
- Setting custom value recognition callbacks
- Defining functions
- Defining parser functions
- Bulk mode functions
- Defining parser operators
- Unary operators
- Binary operators
- Disable built-in operators
- Localization