7 Usage
Data Types
The following data types and constants are used throughout TinyExpr++:
te_parser
: The main class for defining an evaluation engine and solving expressions.
te_type
: The data type for variables, function parameters, and results. By default this is double
, but can be float
(when TE_FLOAT
is defined) or long double
(when TE_LONG_DOUBLE
is defined).
If long double
is in use, then various bitwise functions (BITNOT()
, BITRROTATE()
) may be able to support 64-bit integers. This will depend on the compiler used to build the library and can be verified by calling te_parser::supports_64bit()
in your code or SUPPORTS64BIT()
in an expression at runtime.
te_variable
: A user-defined variable or function that can be embedded into a te_parser
. (Refer to custom variables.)
te_expr
: The base class for a compiled expression. Classes that derive from this can be bound to custom functions. In turn, this allows for connecting more complex, class-based objects to the parser. (Refer to custom classes.)
te_parser::te_nan
: An invalid numeric value. This should be returned from user-defined functions to signal a failed calculation.
te_parser::npos
: An invalid position. This is returned from te_parser::get_last_error_position()
when no error occurred.
te_usr_noop
: A no-op function. When passed to te_parser::set_unknown_symbol_resolver()
, will disable unknown symbol resolution. (Refer to ch. 9.)
Functions
The primary interface to TinyExpr++ is the class te_parser
. A te_parser
is a self-contained parser, which stores its own user-defined variables & functions, separators, and state information.
te_parser
provides these functions:
1te_type evaluate(const std::string_view expression);
2te_type get_result();
bool success();
int64_t get_last_error_position();
std::string get_last_error_message();
3(const std::set<te_variable>& vars);
set_variables_and_functionsstd::set<te_variable>& get_variables_and_functions();
(const te_variable& var);
add_variable_or_function4(te_usr_variant_type usr);
set_unknown_symbol_resolver5();
get_decimal_separator();
set_decimal_separator();
get_list_separator(); set_list_separator
- 1
-
evaluate()
takes an expression and immediately returns the result. If there is a parse error, then it returns NaN (which can be verified by usingstd::isnan()
). (success()
will also return false.) - 2
-
get_result()
can be called anytime afterwards to retrieve the result fromevaluate()
. - 3
-
set_variables_and_functions()
,get_variables_and_functions()
, andadd_variable_or_function()
are used to add custom variables and functions to the parser. - 4
-
set_unknown_symbol_resolver()
is used to provide a custom function to resolve unknown symbols in an expression. (Refer to ch. 9 for further details.) - 5
-
get_decimal_separator()
/set_decimal_separator()
andget_list_separator()
/set_list_separator()
can be used to parse non-US formatted formulas.
Example:
;
te_parser tep
// Returns 10, error position is set to te_parser::npos (i.e., no error).
auto result = tep.evaluate("(5+5)");
// Returns NaN, error position is set to 3.
auto result2 = tep.evaluate("(5+5");
You can also provide set_variables_and_functions()
a list of constants, bound variables, and function pointers/lambdas. evaluate()
will then evaluate expressions using these variables and functions.
Error Handling
TinyExpr++ will throw exceptions when:
- An illegal character is specified in a custom function or variable name.
- An illegal character is provided as a list or decimal separator.
- The same character is provided as both the list and decimal separator.
It is recommended to wrap the following functions in try
/catch
blocks to handle these exceptions:
compile()
evaluate()
set_variables_and_functions()
add_variable_or_function()
set_decimal_separator()
set_list_separator()
Syntax and calculation errors are trapped within calls to compile()
and evaluate()
. Error information can be retrieved afterwards by calling the following:
success()
: returns whether the last parse was successful or not.get_last_error_position()
: returns the 0-based index of where in the expression the parse failed (useful for syntax errors). If there was no parse error, then this will returnte_parser::npos
.get_last_error_message()
: returns a more detailed message for some calculation errors (e.g., division by zero).
Example:
#include "tinyexpr.h"
#include <iostream>
te_type x{ 0 }, y{ 0 };
// Store variable names and pointers.
;
te_parser tep.set_variables_and_functions({{"x", &x}, {"y", &y}});
tep
// Compile the expression with variables.
auto result = tep.evaluate("sqrt(x^2+y^2)");
if (tep.success())
{
= 3; y = 4;
x // Will use the previously used expression, returns 5.
const auto h1 = tep.evaluate();
= 5; y = 12;
x // Returns 13.
const auto h2 = tep.evaluate();
}
else
{
std::cout << "Parse error at " <<
std::to_string(tep.get_last_error_position()) << "\n";
}
Along with positional and message information, the return value of a parse can also indicate failure. When an evaluation fails, the parser will return NaN (i.e., std::numeric_limits<te_type>::quiet_NaN()
) as the result. NaN values can be verified using the standard function std::isnan()
.
Example
The following is a short example demonstrating how to use TinyExpr++.
#include "tinyexpr.h"
#include <iostream>
int main(int argc, char *argv[])
{
;
te_parser tepconst char* expression = "sqrt(5^2+7^2+11^2+(8-2)^2)";
const auto res = tep.evaluate(expression);
std::cout << "The expression:\n\t" <<
<< "\nevaluates to:\n\t" << res << "\n";
expression return EXIT_SUCCESS;
}