C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html

This commit is contained in:
Arash Partow 2014-12-18 03:43:27 +11:00
parent 3dee9efa49
commit dd7ebec65a
2 changed files with 148 additions and 8 deletions

View File

@ -29538,6 +29538,12 @@ namespace exprtk
{ {
namespace details namespace details
{ {
template <typename T>
inline void print_type(const std::string& fmt, const T v, exprtk::details::numeric::details::real_type_tag)
{
printf(fmt.c_str(),v);
}
template <typename T> template <typename T>
struct print_impl struct print_impl
{ {
@ -29553,9 +29559,11 @@ namespace exprtk
{ {
generic_type& gt = parameters[i]; generic_type& gt = parameters[i];
typename exprtk::details::numeric::details::number_type<T>::type num_type;
switch (gt.type) switch (gt.type)
{ {
case generic_type::e_scalar : printf(scalar_format.c_str(),scalar_t(gt)()); case generic_type::e_scalar : print_type(scalar_format.c_str(),scalar_t(gt)(),num_type);
break; break;
case generic_type::e_vector : { case generic_type::e_vector : {
@ -29563,7 +29571,8 @@ namespace exprtk
for (std::size_t x = 0; x < vector.size(); ++x) for (std::size_t x = 0; x < vector.size(); ++x)
{ {
printf(scalar_format.c_str(),vector[x]); print_type(scalar_format.c_str(),vector[x],num_type);
if ((x + 1) < vector.size()) if ((x + 1) < vector.size())
printf(" "); printf(" ");
} }

View File

@ -825,6 +825,7 @@ such transformations:
(e) 5foo(x,y) ---> 5 * foo(x,y) (e) 5foo(x,y) ---> 5 * foo(x,y)
(f) foo(x,y)6 + 1 ---> foo(x,y) * 6 + 1 (f) foo(x,y)6 + 1 ---> foo(x,y) * 6 + 1
(g) (4((2x)3)) ---> 4 * ((2 * x) * 3) (g) (4((2x)3)) ---> 4 * ((2 * x) * 3)
(h) w(x) + (y)z ---> w * x + y * z
(7) Strength Reduction Check (e_strength_reduction) (7) Strength Reduction Check (e_strength_reduction)
@ -1577,8 +1578,138 @@ zero input parameters the calling styles are as follows:
(2) x + sin(foo - 2) / y (2) x + sin(foo - 2) / y
[16 - EXPRESSION DEPENDENTS]
Any expression that is not a literal (aka constant) will have
dependencies. The types of 'dependencies' an expression can have are
as follows:
[16 - COMPILATION ERRORS] (a) Variables
(b) Vectors
(c) Strings
(d) Functions
(e) Assignments
In the following example the denoted expression has its various
dependencies listed:
z := abs(x + sin(2 * pi / y))
(a) Variables: x, y, z and pi
(b) Functions: abs, sin
(c) Assignments: z
ExprTk allows for the derivation of expression dependencies via the
'dependent_entity_collector' (DEC). When activated either through
'compile_options' at the construction of the parser or through calls
to enabler methods just prior to compilation, the DEC will proceed to
collect any of the relevant types that are encountered during the
parsing phase. Once the compilation process has successfully
completed, the caller can then obtain a list of symbols and their
associated types from the DEC.
The following example demonstrates usage of the DEC in determining the
dependents of the given expression:
typedef typename parser_t::
dependent_entity_collector::symbol_t symbol_t;
std::string expression_string =
"z := abs(x + sin(2 * pi / y))";
parser_t parser;
symbol_table_t symbol_table;
expression_t expression;
expression.register_symbol_table(symbol_table);
//Collect only variable and function symbols
parser.dec().collect_variables() = true;
parser.dec().collect_functions() = true;
if (!parser.compile(expression_string,expression))
{
// error....
}
std::deque<symbol_t> symbol_list;
parser.dec().symbols(symbol_list);
for (std::size_t i = 0; i < symbol_list.size(); ++i)
{
symbol_t& symbol = symbol_list[i];
switch (symbol.second)
{
case parser_t::e_st_variable: ... break;
case parser_t::e_st_vector : ... break;
case parser_t::e_st_string : ... break;
case parser_t::e_st_function: ... break;
}
}
Note: The 'symbol_t' type is a pair comprising of the symbol name
(std::string) and the associated type of the symbol as denoted by the
cases in the switch statement.
Having particular symbols (variable or function) present in an
expression is one form of dependency. Another and just as interesting
and important type of dependency is that of assignments. Assignments
are the set of dependent symbols that 'may' have their values modified
within an expression. The following are example expressions and their
associated assignments:
Assignments Expression
1. x x := y + z
2. x, y x += y += z
3. x, y, z x := y += sin(z := w + 2)
4. z, w if (x > y, z := x + 2, w := 'A String')
5. None x + y + z
Note: In expression 4, both variables 'z' and 'w' are denoted as being
assignments even though only one of them can be modified at the time
of evaluation. Furthermore the determination of which of the two
variables the modification will occur upon can only be known with
certainty at evaluation time and not beforehand.
The following builds upon the previous example demonstrating the usage
of the DEC in determining the 'assignments' of the given expression:
//Collect assignments
parser.dec().collect_assignments() = true;
if (!parser.compile(expression_string,expression))
{
// error....
}
std::deque<symbol_t> symbol_list;
parser.dec().assignment_symbols(symbol_list);
for (std::size_t i = 0; i < symbol_list.size(); ++i)
{
symbol_t& symbol = symbol_list[i];
switch (symbol.second)
{
case parser_t::e_st_variable: ... break;
case parser_t::e_st_vector : ... break;
case parser_t::e_st_string : ... break;
}
}
Note: The assignments will only consist of variable types and as such
will not contain symbols denoting functions.
[17 - COMPILATION ERRORS]
When attempting to compile a malformed or otherwise erroneous ExprTk When attempting to compile a malformed or otherwise erroneous ExprTk
expression, the compilation process will result in an error, as is expression, the compilation process will result in an error, as is
indicated by the 'compile' method returning a false value. A indicated by the 'compile' method returning a false value. A
@ -1687,7 +1818,7 @@ via the 'unknown symbol resolver' mechanism.
[17 - EXPRTK NOTES] [18 - EXPRTK NOTES]
The following is a list of facts and suggestions one may want to take The following is a list of facts and suggestions one may want to take
into account when using Exprtk: into account when using Exprtk:
@ -1852,7 +1983,7 @@ into account when using Exprtk:
[18 - SIMPLE EXPRTK EXAMPLE] [19 - SIMPLE EXPRTK EXAMPLE]
--- snip --- --- snip ---
#include <cstdio> #include <cstdio>
#include <string> #include <string>
@ -1940,7 +2071,7 @@ int main()
[19 - BUILD OPTIONS] [20 - BUILD OPTIONS]
When building ExprTk there are a number of defines that will enable or When building ExprTk there are a number of defines that will enable or
disable certain features and capabilities. The defines can either be disable certain features and capabilities. The defines can either be
part of a compiler command line switch or scoped around the include to part of a compiler command line switch or scoped around the include to
@ -1978,7 +2109,7 @@ in a compilation failure.
[20 - FILES] [21 - FILES]
The source distribution of ExprTk is comprised of the following set of The source distribution of ExprTk is comprised of the following set of
files: files:
@ -2006,7 +2137,7 @@ files:
[20 - LANGUAGE STRUCTURE] [22 - LANGUAGE STRUCTURE]
+-------------------------------------------------------------+ +-------------------------------------------------------------+
|00 - If Statement | |00 - If Statement |
| | | |