C++ Mathematical Expression Library (ExprTk) https://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
e0b0aa5130
commit
6c37419d62
12
.travis.yml
12
.travis.yml
|
@ -1,12 +0,0 @@
|
|||
language: cpp
|
||||
|
||||
sudo: required
|
||||
|
||||
dist: trusty
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
script:
|
||||
- make clean all
|
||||
- ./exprtk_test
|
121
exprtk.hpp
121
exprtk.hpp
|
@ -1111,13 +1111,21 @@ namespace exprtk
|
|||
return T(0);
|
||||
}
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
|
||||
#define exprtk_define_erf(TT,impl) \
|
||||
inline TT erf_impl(TT v) { return impl(v); } \
|
||||
|
||||
exprtk_define_erf( float,::erff)
|
||||
exprtk_define_erf( double,::erf )
|
||||
exprtk_define_erf(long double,::erfl)
|
||||
#undef exprtk_define_erf
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline T erf_impl(T v, real_type_tag)
|
||||
{
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
// Credits: Abramowitz & Stegun Equations 7.1.25-28
|
||||
const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
|
||||
|
||||
static const T c[] = {
|
||||
T( 1.26551223), T(1.00002368),
|
||||
T( 0.37409196), T(0.09678418),
|
||||
|
@ -1126,6 +1134,8 @@ namespace exprtk
|
|||
T(-0.82215223), T(0.17087277)
|
||||
};
|
||||
|
||||
const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
|
||||
|
||||
T result = T(1) - t * std::exp((-v * v) -
|
||||
c[0] + t * (c[1] + t *
|
||||
(c[2] + t * (c[3] + t *
|
||||
|
@ -1135,7 +1145,7 @@ namespace exprtk
|
|||
|
||||
return (v >= T(0)) ? result : -result;
|
||||
#else
|
||||
return ::erf(v);
|
||||
return erf_impl(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1145,13 +1155,23 @@ namespace exprtk
|
|||
return erf_impl(static_cast<double>(v),real_type_tag());
|
||||
}
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
|
||||
#define exprtk_define_erfc(TT,impl) \
|
||||
inline TT erfc_impl(TT v) { return impl(v); } \
|
||||
|
||||
exprtk_define_erfc( float,::erfcf)
|
||||
exprtk_define_erfc( double,::erfc )
|
||||
exprtk_define_erfc(long double,::erfcl)
|
||||
#undef exprtk_define_erfc
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline T erfc_impl(T v, real_type_tag)
|
||||
{
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
return T(1) - erf_impl(v,real_type_tag());
|
||||
#else
|
||||
return ::erfc(v);
|
||||
return erfc_impl(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1196,7 +1216,7 @@ namespace exprtk
|
|||
template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
|
||||
template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
|
||||
template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
|
||||
template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - log(T(1) - v)) / T(2); }
|
||||
template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); }
|
||||
template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
|
||||
template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
|
||||
template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
|
||||
|
@ -9223,7 +9243,7 @@ namespace exprtk
|
|||
};
|
||||
|
||||
template <typename T, typename Operation>
|
||||
class vecarith_vecvec_node : public binary_node <T>,
|
||||
class vec_binop_vecvec_node : public binary_node <T>,
|
||||
public vector_interface<T>
|
||||
{
|
||||
public:
|
||||
|
@ -9232,7 +9252,7 @@ namespace exprtk
|
|||
typedef vector_node<T>* vector_node_ptr;
|
||||
typedef vector_holder<T>* vector_holder_ptr;
|
||||
|
||||
vecarith_vecvec_node(const operator_type& opr,
|
||||
vec_binop_vecvec_node(const operator_type& opr,
|
||||
expression_ptr branch0,
|
||||
expression_ptr branch1)
|
||||
: binary_node<T>(opr,branch0,branch1),
|
||||
|
@ -9286,7 +9306,7 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
~vecarith_vecvec_node()
|
||||
~vec_binop_vecvec_node()
|
||||
{
|
||||
delete[] data_;
|
||||
delete temp_;
|
||||
|
@ -9388,7 +9408,7 @@ namespace exprtk
|
|||
};
|
||||
|
||||
template <typename T, typename Operation>
|
||||
class vecarith_vecval_node : public binary_node <T>,
|
||||
class vec_binop_vecval_node : public binary_node <T>,
|
||||
public vector_interface<T>
|
||||
{
|
||||
public:
|
||||
|
@ -9397,7 +9417,7 @@ namespace exprtk
|
|||
typedef vector_node<T>* vector_node_ptr;
|
||||
typedef vector_holder<T>* vector_holder_ptr;
|
||||
|
||||
vecarith_vecval_node(const operator_type& opr,
|
||||
vec_binop_vecval_node(const operator_type& opr,
|
||||
expression_ptr branch0,
|
||||
expression_ptr branch1)
|
||||
: binary_node<T>(opr,branch0,branch1),
|
||||
|
@ -9432,7 +9452,7 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
~vecarith_vecval_node()
|
||||
~vec_binop_vecval_node()
|
||||
{
|
||||
delete[] data_;
|
||||
delete temp_;
|
||||
|
@ -9530,7 +9550,7 @@ namespace exprtk
|
|||
};
|
||||
|
||||
template <typename T, typename Operation>
|
||||
class vecarith_valvec_node : public binary_node <T>,
|
||||
class vec_binop_valvec_node : public binary_node <T>,
|
||||
public vector_interface<T>
|
||||
{
|
||||
public:
|
||||
|
@ -9539,7 +9559,7 @@ namespace exprtk
|
|||
typedef vector_node<T>* vector_node_ptr;
|
||||
typedef vector_holder<T>* vector_holder_ptr;
|
||||
|
||||
vecarith_valvec_node(const operator_type& opr,
|
||||
vec_binop_valvec_node(const operator_type& opr,
|
||||
expression_ptr branch0,
|
||||
expression_ptr branch1)
|
||||
: binary_node<T>(opr,branch0,branch1),
|
||||
|
@ -9574,7 +9594,7 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
~vecarith_valvec_node()
|
||||
~vec_binop_valvec_node()
|
||||
{
|
||||
delete[] data_;
|
||||
delete temp_;
|
||||
|
@ -24282,7 +24302,7 @@ namespace exprtk
|
|||
);
|
||||
}
|
||||
|
||||
inline bool is_vector_eqineq_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
|
||||
inline bool is_vector_eqineq_logic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
|
||||
{
|
||||
if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
|
||||
return false;
|
||||
|
@ -24294,7 +24314,13 @@ namespace exprtk
|
|||
(details::e_gte == operation) ||
|
||||
(details::e_eq == operation) ||
|
||||
(details::e_ne == operation) ||
|
||||
(details::e_equal == operation)
|
||||
(details::e_equal == operation) ||
|
||||
(details::e_and == operation) ||
|
||||
(details::e_nand == operation) ||
|
||||
(details:: e_or == operation) ||
|
||||
(details:: e_nor == operation) ||
|
||||
(details:: e_xor == operation) ||
|
||||
(details::e_xnor == operation)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -24328,8 +24354,8 @@ namespace exprtk
|
|||
return synthesize_swap_expression(branch);
|
||||
else if (is_assignment_operation(operation))
|
||||
return synthesize_assignment_operation_expression(operation,branch);
|
||||
else if (is_vector_eqineq_operation(operation,branch))
|
||||
return synthesize_veceqineq_operation_expression(operation,branch);
|
||||
else if (is_vector_eqineq_logic_operation(operation,branch))
|
||||
return synthesize_veceqineqlogic_operation_expression(operation,branch);
|
||||
else if (is_vector_arithmetic_operation(operation,branch))
|
||||
return synthesize_vecarithmetic_operation_expression(operation,branch);
|
||||
else if (is_shortcircuit_expression(operation))
|
||||
|
@ -25778,28 +25804,37 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
inline expression_node_ptr synthesize_veceqineq_operation_expression(const details::operator_type& operation,
|
||||
inline expression_node_ptr synthesize_veceqineqlogic_operation_expression(const details::operator_type& operation,
|
||||
expression_node_ptr (&branch)[2])
|
||||
{
|
||||
const bool is_b0_ivec = details::is_ivector_node(branch[0]);
|
||||
const bool is_b1_ivec = details::is_ivector_node(branch[1]);
|
||||
|
||||
#define batch_eqineq_logic_case \
|
||||
case_stmt(details:: e_lt,details:: lt_op) \
|
||||
case_stmt(details:: e_lte,details:: lte_op) \
|
||||
case_stmt(details:: e_gt,details:: gt_op) \
|
||||
case_stmt(details:: e_gte,details:: gte_op) \
|
||||
case_stmt(details:: e_eq,details:: eq_op) \
|
||||
case_stmt(details:: e_ne,details:: ne_op) \
|
||||
case_stmt(details::e_equal,details::equal_op) \
|
||||
case_stmt(details:: e_and, details::and_op) \
|
||||
case_stmt(details:: e_nand, details::nand_op) \
|
||||
case_stmt(details:: e_or, details:: or_op) \
|
||||
case_stmt(details:: e_nor, details:: nor_op) \
|
||||
case_stmt(details:: e_xor, details:: xor_op) \
|
||||
case_stmt(details:: e_xnor, details::xnor_op) \
|
||||
|
||||
if (is_b0_ivec && is_b1_ivec)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
#define case_stmt(op0,op1) \
|
||||
case op0 : return node_allocator_-> \
|
||||
template allocate_rrr<typename details::vecarith_vecvec_node<Type,op1<Type> > > \
|
||||
template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
|
||||
(operation,branch[0],branch[1]); \
|
||||
|
||||
case_stmt(details:: e_lt,details:: lt_op)
|
||||
case_stmt(details:: e_lte,details:: lte_op)
|
||||
case_stmt(details:: e_gt,details:: gt_op)
|
||||
case_stmt(details:: e_gte,details:: gte_op)
|
||||
case_stmt(details:: e_eq,details:: eq_op)
|
||||
case_stmt(details:: e_ne,details:: ne_op)
|
||||
case_stmt(details::e_equal,details::equal_op)
|
||||
batch_eqineq_logic_case
|
||||
#undef case_stmt
|
||||
default : return error_node();
|
||||
}
|
||||
|
@ -25810,16 +25845,10 @@ namespace exprtk
|
|||
{
|
||||
#define case_stmt(op0,op1) \
|
||||
case op0 : return node_allocator_-> \
|
||||
template allocate_rrr<typename details::vecarith_vecval_node<Type,op1<Type> > > \
|
||||
template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
|
||||
(operation,branch[0],branch[1]); \
|
||||
|
||||
case_stmt(details:: e_lt,details:: lt_op)
|
||||
case_stmt(details:: e_lte,details:: lte_op)
|
||||
case_stmt(details:: e_gt,details:: gt_op)
|
||||
case_stmt(details:: e_gte,details:: gte_op)
|
||||
case_stmt(details:: e_eq,details:: eq_op)
|
||||
case_stmt(details:: e_ne,details:: ne_op)
|
||||
case_stmt(details::e_equal,details::equal_op)
|
||||
batch_eqineq_logic_case
|
||||
#undef case_stmt
|
||||
default : return error_node();
|
||||
}
|
||||
|
@ -25830,22 +25859,18 @@ namespace exprtk
|
|||
{
|
||||
#define case_stmt(op0,op1) \
|
||||
case op0 : return node_allocator_-> \
|
||||
template allocate_rrr<typename details::vecarith_valvec_node<Type,op1<Type> > > \
|
||||
template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
|
||||
(operation,branch[0],branch[1]); \
|
||||
|
||||
case_stmt(details:: e_lt,details:: lt_op)
|
||||
case_stmt(details:: e_lte,details:: lte_op)
|
||||
case_stmt(details:: e_gt,details:: gt_op)
|
||||
case_stmt(details:: e_gte,details:: gte_op)
|
||||
case_stmt(details:: e_eq,details:: eq_op)
|
||||
case_stmt(details:: e_ne,details:: ne_op)
|
||||
case_stmt(details::e_equal,details::equal_op)
|
||||
batch_eqineq_logic_case
|
||||
#undef case_stmt
|
||||
default : return error_node();
|
||||
}
|
||||
}
|
||||
else
|
||||
return error_node();
|
||||
|
||||
#undef batch_eqineq_logic_case
|
||||
}
|
||||
|
||||
inline expression_node_ptr synthesize_vecarithmetic_operation_expression(const details::operator_type& operation,
|
||||
|
@ -25867,7 +25892,7 @@ namespace exprtk
|
|||
{
|
||||
#define case_stmt(op0,op1) \
|
||||
case op0 : return node_allocator_-> \
|
||||
template allocate_rrr<typename details::vecarith_vecvec_node<Type,op1<Type> > > \
|
||||
template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
|
||||
(operation,branch[0],branch[1]); \
|
||||
|
||||
vector_ops
|
||||
|
@ -25882,7 +25907,7 @@ namespace exprtk
|
|||
{
|
||||
#define case_stmt(op0,op1) \
|
||||
case op0 : return node_allocator_-> \
|
||||
template allocate_rrr<typename details::vecarith_vecval_node<Type,op1<Type> > > \
|
||||
template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
|
||||
(operation,branch[0],branch[1]); \
|
||||
|
||||
vector_ops
|
||||
|
@ -25897,7 +25922,7 @@ namespace exprtk
|
|||
{
|
||||
#define case_stmt(op0,op1) \
|
||||
case op0 : return node_allocator_-> \
|
||||
template allocate_rrr<typename details::vecarith_valvec_node<Type,op1<Type> > > \
|
||||
template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
|
||||
(operation,branch[0],branch[1]); \
|
||||
|
||||
vector_ops
|
||||
|
|
|
@ -183,7 +183,7 @@ bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
|
|||
return true;
|
||||
}
|
||||
|
||||
const double pi = 3.14159265358979323846;
|
||||
const double pi = 3.141592653589793238462643383279502;
|
||||
|
||||
template <typename T>
|
||||
struct native
|
||||
|
|
|
@ -37,7 +37,7 @@ void square_wave()
|
|||
" (1/21)*sin(42*pi*f*t)+(1/23)*sin(46*pi*f*t)+"
|
||||
" (1/25)*sin(50*pi*f*t)+(1/27)*sin(54*pi*f*t))";
|
||||
|
||||
static const T pi = T(3.14159265358979323846);
|
||||
static const T pi = T(3.141592653589793238462643383279502);
|
||||
|
||||
T f = pi / T(10);
|
||||
T t = T(0);
|
||||
|
|
|
@ -36,7 +36,7 @@ void square_wave2()
|
|||
" }; "
|
||||
" r *= a * (4 / pi); ";
|
||||
|
||||
static const T pi = T(3.14159265358979323846);
|
||||
static const T pi = T(3.141592653589793238462643383279502);
|
||||
|
||||
T f = pi / T(10);
|
||||
T t = T(0);
|
||||
|
|
|
@ -61,7 +61,7 @@ void savitzky_golay_filter()
|
|||
std::vector<T> v_in;
|
||||
std::vector<T> v_out;
|
||||
|
||||
const T pi = T(3.141592653589793238462);
|
||||
const T pi = T(3.141592653589793238462643383279502);
|
||||
|
||||
srand(static_cast<unsigned int>(time(0)));
|
||||
|
||||
|
|
|
@ -33,7 +33,8 @@ struct rnd_01 : public exprtk::ifunction<T>
|
|||
inline T operator()()
|
||||
{
|
||||
// Note: Do not use this in production
|
||||
return T(::rand() / T(RAND_MAX + 1));
|
||||
// Result is in the interval [0,1)
|
||||
return T(::rand() / T(RAND_MAX + 1.0));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -61,7 +62,7 @@ void monte_carlo_pi()
|
|||
|
||||
const T approximate_pi = expression.value();
|
||||
|
||||
const T real_pi = T(3.141592653589793238462);
|
||||
const T real_pi = T(3.141592653589793238462643383279502); // or close enough...
|
||||
|
||||
printf("pi ~ %20.17f\terror: %20.17f\n",
|
||||
approximate_pi,
|
||||
|
|
|
@ -29,7 +29,12 @@
|
|||
#include "exprtk.hpp"
|
||||
|
||||
|
||||
#ifdef exprtk_test_float32_type
|
||||
typedef float numeric_type;
|
||||
#else
|
||||
typedef double numeric_type;
|
||||
#endif
|
||||
|
||||
typedef std::pair<std::string,numeric_type> test_t;
|
||||
|
||||
static const test_t global_test_list[] =
|
||||
|
@ -2750,7 +2755,7 @@ inline bool run_test04()
|
|||
}
|
||||
}
|
||||
|
||||
const T pi = T(3.14159265358979323846);
|
||||
const T pi = T(3.141592653589793238462643383279502);
|
||||
const T increment = T(0.0001);
|
||||
|
||||
while ((x <= T(+1000)) && (y <= T(+1000)))
|
||||
|
@ -2815,7 +2820,7 @@ inline bool run_test05()
|
|||
expression_list.push_back(e);
|
||||
}
|
||||
|
||||
const T pi = T(3.14159265358979323846);
|
||||
const T pi = T(3.141592653589793238462643383279502);
|
||||
const T increment = T(0.001);
|
||||
|
||||
while ((x <= T(+1000)) && (y <= T(+1000)))
|
||||
|
@ -2878,7 +2883,7 @@ inline bool run_test06()
|
|||
|
||||
T total_area1 = exprtk::integrate(expression,x,T(-1),T(1));
|
||||
T total_area2 = exprtk::integrate(expression,"x",T(-1),T(1));
|
||||
const T pi = T(3.14159265358979323846);
|
||||
const T pi = T(3.141592653589793238462643383279502);
|
||||
|
||||
if (not_equal(total_area1,total_area2,T(0.000001)))
|
||||
{
|
||||
|
@ -3196,12 +3201,16 @@ struct myfunc : public exprtk::ifunction<T>
|
|||
}
|
||||
};
|
||||
|
||||
double foo1(double v0) { return v0; }
|
||||
double foo2(double v0, double v1) { return v0 + v1; }
|
||||
double foo3(double v0, double v1, double v2) { return v0 + v1 + v2; }
|
||||
double foo4(double v0, double v1, double v2, double v3) { return v0 + v1 + v2 + v3; }
|
||||
double foo5(double v0, double v1, double v2, double v3, double v4) { return v0 + v1 + v2 + v3 + v4; }
|
||||
double foo6(double v0, double v1, double v2, double v3, double v4, double v5) { return v0 + v1 + v2 + v3 + v4 + v5; }
|
||||
#define define_free_functions(Type) \
|
||||
Type foo1(Type v0) { return v0; } \
|
||||
Type foo2(Type v0, Type v1) { return v0 + v1; } \
|
||||
Type foo3(Type v0, Type v1, Type v2) { return v0 + v1 + v2; } \
|
||||
Type foo4(Type v0, Type v1, Type v2, Type v3) { return v0 + v1 + v2 + v3; } \
|
||||
Type foo5(Type v0, Type v1, Type v2, Type v3, Type v4) { return v0 + v1 + v2 + v3 + v4; } \
|
||||
Type foo6(Type v0, Type v1, Type v2, Type v3, Type v4, Type v5) { return v0 + v1 + v2 + v3 + v4 + v5; } \
|
||||
|
||||
define_free_functions(numeric_type)
|
||||
#undef define_free_functions
|
||||
|
||||
template <typename T>
|
||||
inline bool run_test09()
|
||||
|
@ -3267,7 +3276,7 @@ inline bool run_test09()
|
|||
}
|
||||
}
|
||||
|
||||
const T pi = T(3.141592653589793238462);
|
||||
const T pi = T(3.141592653589793238462643383279502);
|
||||
|
||||
T result = expression.value();
|
||||
|
||||
|
|
47
readme.txt
47
readme.txt
|
@ -1269,12 +1269,13 @@ with vectors:
|
|||
(b) Exponentiation: vector ^ scalar
|
||||
(c) Assignment: :=, +=, -=, *=, /=, %=, <=>
|
||||
(d) Inequalities: <, <=, >, >=, ==, =, equal
|
||||
(e) Unary operations:
|
||||
(e) Boolean logic: and, nand, nor, or, xnor, xor
|
||||
(f) Unary operations:
|
||||
abs, acos, acosh, asin, asinh, atan, atanh, ceil, cos, cosh,
|
||||
cot, csc, deg2grad, deg2rad, erf, erfc, exp, expm1, floor,
|
||||
frac, grad2deg, log, log10, log1p, log2, rad2deg, round, sec,
|
||||
sgn, sin, sinc, sinh, sqrt, swap, tan, tanh, trunc
|
||||
(f) Aggregate and Reduce operations:
|
||||
(g) Aggregate and Reduce operations:
|
||||
avg, max, min, mul, sum
|
||||
|
||||
Note: When one of the above described operations is being performed
|
||||
|
@ -1315,6 +1316,7 @@ not a vector but rather a single value.
|
|||
avg(3x + 1) == 7
|
||||
min(1 / x) == (1 / 3)
|
||||
max(x / 2) == (3 / 2)
|
||||
sum(x > 0 and x < 5) == x[]
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -2487,6 +2489,16 @@ in the event of a failed compilation.
|
|||
}
|
||||
|
||||
|
||||
Assuming the following expression '2 + (3 / log(1 + x))' which uses a
|
||||
variable named 'x' that has not been registered with the appropriate
|
||||
symbol_table instance and is not a locally defined variable, once
|
||||
compiled the above denoted post compilation error handling code shall
|
||||
produce the following output:
|
||||
|
||||
Error: ERR184 - Undefined symbol: 'x'
|
||||
Err No.:00 Pos:17 Type:[Syntax] Msg: ERR184 - Undefined symbol: 'x'
|
||||
|
||||
|
||||
For expressions comprised of multiple lines, the error position
|
||||
provided in the parser_error object can be converted into a pair of
|
||||
line and column numbers by invoking the 'update_error' function as is
|
||||
|
@ -2730,9 +2742,40 @@ into account when using ExprTk:
|
|||
(x + y) / (x - y);
|
||||
}
|
||||
|
||||
(30) For performance considerations, one should assume the actions
|
||||
of expression, symbol table and parser instance instantiation
|
||||
and destruction, and the expression compilation process itself
|
||||
to be of high latency. Hence none of them should be part of any
|
||||
performance critical code paths, and should instead occur
|
||||
entirely either before or after such code paths.
|
||||
|
||||
(31) Before jumping in and using ExprTk, do take the time to peruse
|
||||
the documentation and all of the examples, both in the main and
|
||||
the extras distributions. Having an informed general view of
|
||||
what can and can't be done, and how something should be done
|
||||
with ExprTk, will likely result in a far more productive and
|
||||
enjoyable programming experience.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
[21 - SIMPLE EXPRTK EXAMPLE]
|
||||
The following is a simple yet complete example demonstrating typical
|
||||
usage of the ExprTk Library. The example instantiates a symbol table
|
||||
object, adding to it three variables named x, y and z, and a custom
|
||||
user defined function, that accepts only two parameters, named myfunc.
|
||||
The example then proceeds to instantiate an expression object and
|
||||
register to it the symbol table instance.
|
||||
|
||||
A parser is then instantiated, and the string representation of the
|
||||
expression and the expression object are passed to the parser's
|
||||
compile method for compilation. If an error occurred during
|
||||
compilation, the compile method will return false, leading to a series
|
||||
of error diagnostics being printed to stdout. Otherwise the newly
|
||||
compiled expression is evaluated by invoking the expression object's
|
||||
value method, and subsequently printing the result of the computation
|
||||
to stdout.
|
||||
|
||||
|
||||
--- snip ---
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
|
Loading…
Reference in New Issue