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

This commit is contained in:
Arash Partow 2013-04-04 20:45:19 +11:00
parent e9c3e2e79d
commit cfa2f97e72
2 changed files with 152 additions and 120 deletions

View File

@ -236,11 +236,11 @@ namespace exprtk
"abs", "acos", "and", "asin", "atan", "atan2", "avg", "ceil", "clamp", "abs", "acos", "and", "asin", "atan", "atan2", "avg", "ceil", "clamp",
"cos", "cosh", "cot", "csc", "deg2grad", "deg2rad", "equal", "erf", "erfc", "cos", "cosh", "cot", "csc", "deg2grad", "deg2rad", "equal", "erf", "erfc",
"exp", "false", "floor", "for", "frac", "grad2deg", "hypot", "if", "ilike", "exp", "false", "floor", "for", "frac", "grad2deg", "hypot", "if", "ilike",
"in", "inrange", "like", "log", "log10", "logn", "log1p", "mand", "max", "in", "inrange", "like", "log", "log10", "log2", "logn", "log1p", "mand",
"min", "mod", "mor", "mul", "nand", "nor", "not", "not_equal", "null", "or", "max", "min", "mod", "mor", "mul", "nand", "nor", "not", "not_equal", "null",
"pow", "rad2deg", "root", "round", "roundn", "sec", "sgn", "shl", "shr", "sin", "or", "pow", "rad2deg", "root", "round", "roundn", "sec", "sgn", "shl", "shr",
"sinh", "sqrt", "sum", "tan", "tanh", "true", "trunc", "while", "xnor", "xor", "sin", "sinh", "sqrt", "sum", "tan", "tanh", "true", "trunc", "while", "xnor",
"&", "|" "xor", "&", "|"
}; };
static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string); static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
@ -376,6 +376,7 @@ namespace exprtk
static const double _1_pi = 0.318309886183790671538; static const double _1_pi = 0.318309886183790671538;
static const double _2_pi = 0.636619772367581343076; static const double _2_pi = 0.636619772367581343076;
static const double _180_pi = 57.295779513082320876798; static const double _180_pi = 57.295779513082320876798;
static const double log2 = 0.693147180559945309417;
} }
namespace details namespace details
@ -708,6 +709,7 @@ namespace exprtk
template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); } template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); }
template <typename T> inline T log_impl(const T v, real_type_tag) { return std::log (v); } template <typename T> inline T log_impl(const T v, real_type_tag) { return std::log (v); }
template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); } template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); }
template <typename T> inline T log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); }
template <typename T> inline T neg_impl(const T v, real_type_tag) { return -v; } template <typename T> inline T neg_impl(const T v, real_type_tag) { return -v; }
template <typename T> inline T pos_impl(const T v, real_type_tag) { return +v; } template <typename T> inline T pos_impl(const T v, real_type_tag) { return +v; }
template <typename T> inline T sin_impl(const T v, real_type_tag) { return std::sin (v); } template <typename T> inline T sin_impl(const T v, real_type_tag) { return std::sin (v); }
@ -730,6 +732,7 @@ namespace exprtk
template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); } template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); }
template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); } template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); }
template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); } template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); }
template <typename T> inline T log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); }
template <typename T> inline T neg_impl(const T v, int_type_tag) { return -v; } template <typename T> inline T neg_impl(const T v, int_type_tag) { return -v; }
template <typename T> inline T pos_impl(const T v, int_type_tag) { return +v; } template <typename T> inline T pos_impl(const T v, int_type_tag) { return +v; }
template <typename T> inline T ceil_impl(const T v, int_type_tag) { return v; } template <typename T> inline T ceil_impl(const T v, int_type_tag) { return v; }
@ -924,6 +927,7 @@ namespace exprtk
exprtk_define_unary_function(floor) exprtk_define_unary_function(floor)
exprtk_define_unary_function(log ) exprtk_define_unary_function(log )
exprtk_define_unary_function(log10) exprtk_define_unary_function(log10)
exprtk_define_unary_function(log2 )
exprtk_define_unary_function(log1p) exprtk_define_unary_function(log1p)
exprtk_define_unary_function(neg ) exprtk_define_unary_function(neg )
exprtk_define_unary_function(pos ) exprtk_define_unary_function(pos )
@ -1508,7 +1512,9 @@ namespace exprtk
while (!is_end(s_itr_)) while (!is_end(s_itr_))
{ {
scan_token(); scan_token();
if (token_list_.back().is_error()) if (token_list_.empty())
return true;
else if (token_list_.back().is_error())
{ {
return false; return false;
} }
@ -1516,6 +1522,11 @@ namespace exprtk
return true; return true;
} }
inline bool empty() const
{
return token_list_.empty();
}
inline std::size_t size() const inline std::size_t size() const
{ {
return token_list_.size(); return token_list_.size();
@ -2747,15 +2758,15 @@ namespace exprtk
e_shr , e_shl , e_abs , e_acos , e_shr , e_shl , e_abs , e_acos ,
e_asin , e_atan , e_ceil , e_cos , e_asin , e_atan , e_ceil , e_cos ,
e_cosh , e_exp , e_floor , e_log , e_cosh , e_exp , e_floor , e_log ,
e_log10 , e_log1p , e_logn , e_neg , e_log10 , e_log2 , e_log1p , e_logn ,
e_pos , e_round , e_roundn , e_root , e_neg , e_pos , e_round , e_roundn ,
e_sqrt , e_sin , e_sinh , e_sec , e_root , e_sqrt , e_sin , e_sinh ,
e_csc , e_tan , e_tanh , e_cot , e_sec , e_csc , e_tan , e_tanh ,
e_clamp , e_inrange , e_sgn , e_r2d , e_cot , e_clamp , e_inrange , e_sgn ,
e_d2r , e_d2g , e_g2d , e_hypot , e_r2d , e_d2r , e_d2g , e_g2d ,
e_notl , e_erf , e_erfc , e_frac , e_hypot , e_notl , e_erf , e_erfc ,
e_trunc , e_assign , e_in , e_like , e_frac , e_trunc , e_assign , e_in ,
e_ilike , e_like , e_ilike ,
// Do not add new functions/operators after this point. // Do not add new functions/operators after this point.
e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003, e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
@ -2828,6 +2839,7 @@ namespace exprtk
case e_floor : return numeric::floor(arg); case e_floor : return numeric::floor(arg);
case e_log : return numeric::log (arg); case e_log : return numeric::log (arg);
case e_log10 : return numeric::log10(arg); case e_log10 : return numeric::log10(arg);
case e_log2 : return numeric::log2 (arg);
case e_log1p : return numeric::log1p(arg); case e_log1p : return numeric::log1p(arg);
case e_neg : return numeric::neg (arg); case e_neg : return numeric::neg (arg);
case e_pos : return numeric::pos (arg); case e_pos : return numeric::pos (arg);
@ -2863,6 +2875,7 @@ namespace exprtk
case e_exp : return numeric::exp (arg); case e_exp : return numeric::exp (arg);
case e_log : return numeric::log (arg); case e_log : return numeric::log (arg);
case e_log10 : return numeric::log10(arg); case e_log10 : return numeric::log10(arg);
case e_log2 : return numeric::log2 (arg);
case e_log1p : return numeric::log1p(arg); case e_log1p : return numeric::log1p(arg);
case e_neg : return numeric::neg (arg); case e_neg : return numeric::neg (arg);
case e_pos : return numeric::pos (arg); case e_pos : return numeric::pos (arg);
@ -2983,18 +2996,18 @@ namespace exprtk
e_ipow , e_ipowinv , e_abs , e_acos , e_ipow , e_ipowinv , e_abs , e_acos ,
e_asin , e_atan , e_ceil , e_cos , e_asin , e_atan , e_ceil , e_cos ,
e_cosh , e_exp , e_floor , e_log , e_cosh , e_exp , e_floor , e_log ,
e_log10 , e_log1p , e_neg , e_pos , e_log10 , e_log2 , e_log1p , e_neg ,
e_round , e_sin , e_sinh , e_sqrt , e_pos , e_round , e_sin , e_sinh ,
e_tan , e_tanh , e_cot , e_sec , e_sqrt , e_tan , e_tanh , e_cot ,
e_csc , e_r2d , e_d2r , e_d2g , e_sec , e_csc , e_r2d , e_d2r ,
e_g2d , e_notl , e_sgn , e_erf , e_d2g , e_g2d , e_notl , e_sgn ,
e_erfc , e_frac , e_trunc , e_uvouv , e_erf , e_erfc , e_frac , e_trunc ,
e_vov , e_cov , e_voc , e_vob , e_uvouv , e_vov , e_cov , e_voc ,
e_bov , e_cob , e_boc , e_vovov , e_vob , e_bov , e_cob , e_boc ,
e_vovoc , e_vocov , e_covov , e_covoc , e_vovov , e_vovoc , e_vocov , e_covov ,
e_vovovov , e_vovovoc , e_vovocov , e_vocovov , e_covoc , e_vovovov , e_vovovoc , e_vovocov ,
e_covovov , e_covocov , e_vocovoc , e_covovoc , e_vocovov , e_covovov , e_covocov , e_vocovoc ,
e_vococov , e_sf3ext , e_sf4ext e_covovoc , e_vococov , e_sf3ext , e_sf4ext
}; };
typedef T value_type; typedef T value_type;
@ -4747,6 +4760,7 @@ namespace exprtk
exprtk_def_unary_op(g2d ) exprtk_def_unary_op(g2d )
exprtk_def_unary_op(log ) exprtk_def_unary_op(log )
exprtk_def_unary_op(log10) exprtk_def_unary_op(log10)
exprtk_def_unary_op(log2 )
exprtk_def_unary_op(log1p) exprtk_def_unary_op(log1p)
exprtk_def_unary_op(neg ) exprtk_def_unary_op(neg )
exprtk_def_unary_op(notl ) exprtk_def_unary_op(notl )
@ -7554,6 +7568,7 @@ namespace exprtk
register_op( "floor",e_floor , 1) register_op( "floor",e_floor , 1)
register_op( "log",e_log , 1) register_op( "log",e_log , 1)
register_op( "log10",e_log10 , 1) register_op( "log10",e_log10 , 1)
register_op( "log2",e_log2 , 1)
register_op( "log1p",e_log1p , 1) register_op( "log1p",e_log1p , 1)
register_op( "round",e_round , 1) register_op( "round",e_round , 1)
register_op( "sin",e_sin , 1) register_op( "sin",e_sin , 1)
@ -9255,6 +9270,9 @@ namespace exprtk
inline bool compile(const std::string& expression_string, expression<T>& expr) inline bool compile(const std::string& expression_string, expression<T>& expr)
{ {
error_list_.clear();
expression_generator_.set_allocator(node_allocator_);
if (expression_string.empty()) if (expression_string.empty())
{ {
set_error( set_error(
@ -9263,15 +9281,20 @@ namespace exprtk
return false; return false;
} }
error_list_.clear();
expression_generator_.set_allocator(node_allocator_);
if (!lexer_.process(expression_string)) if (!lexer_.process(expression_string))
{ {
process_lexer_errors(); process_lexer_errors();
return false; return false;
} }
if (lexer_.empty())
{
set_error(
make_error(parser_error::e_syntax,
"ERR01 - Empty expression!"));
return false;
}
if (!run_assemblies()) if (!run_assemblies())
{ {
return false; return false;
@ -9294,7 +9317,7 @@ namespace exprtk
{ {
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
"ERR01 - Incomplete expression!")); "ERR02 - Incomplete expression!"));
symbol_name_cache_.clear(); symbol_name_cache_.clear();
if (0 != e) if (0 != e)
{ {
@ -9310,7 +9333,7 @@ namespace exprtk
{ {
if (lexer_[i].is_error()) if (lexer_[i].is_error())
{ {
std::string diagnostic = "ERR02 - "; std::string diagnostic = "ERR03 - ";
switch (lexer_[i].type) switch (lexer_[i].type)
{ {
case lexer::token::e_error : diagnostic + "General token error"; case lexer::token::e_error : diagnostic + "General token error";
@ -9400,7 +9423,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_token, make_error(parser_error::e_token,
bracket_checker_ptr->error_token(), bracket_checker_ptr->error_token(),
"ERR03 - Mismatched brackets: " + bracket_checker_ptr->error_token().value)); "ERR04 - Mismatched brackets: " + bracket_checker_ptr->error_token().value));
} }
else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker*>(helper_assembly_.error_token_scanner))) else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker*>(helper_assembly_.error_token_scanner)))
{ {
@ -9410,7 +9433,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_token, make_error(parser_error::e_token,
error_token, error_token,
"ERR04 - Invalid numeric token: " + error_token.value)); "ERR05 - Invalid numeric token: " + error_token.value));
} }
} }
else if (0 != (sequence_validator_ptr = dynamic_cast<lexer::helper::sequence_validator*>(helper_assembly_.error_token_scanner))) else if (0 != (sequence_validator_ptr = dynamic_cast<lexer::helper::sequence_validator*>(helper_assembly_.error_token_scanner)))
@ -9421,7 +9444,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_token, make_error(parser_error::e_token,
error_token.first, error_token.first,
"ERR05 - Invalid token sequence: " + "ERR06 - Invalid token sequence: " +
error_token.first.value + " " + error_token.first.value + " " +
error_token.second.value)); error_token.second.value));
} }
@ -9860,7 +9883,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR06 - Expecting argument list for function: '" + function_name + "'")); "ERR07 - Expecting argument list for function: '" + function_name + "'"));
return error_node(); return error_node();
} }
@ -9872,7 +9895,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR07 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'")); "ERR08 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'"));
return error_node(); return error_node();
} }
else if (i < static_cast<int>(NumberofParameters - 1)) else if (i < static_cast<int>(NumberofParameters - 1))
@ -9882,7 +9905,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR08 - Invalid number of arguments for function: '" + function_name + "'")); "ERR09 - Invalid number of arguments for function: '" + function_name + "'"));
return error_node(); return error_node();
} }
} }
@ -9893,7 +9916,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR09 - Invalid number of arguments for function: '" + function_name + "'")); "ERR10 - Invalid number of arguments for function: '" + function_name + "'"));
return error_node(); return error_node();
} }
else else
@ -9912,7 +9935,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR10 - Expecting '()' to proceed: '" + function_name + "'")); "ERR11 - Expecting '()' to proceed: '" + function_name + "'"));
return error_node(); return error_node();
} }
else else
@ -9929,7 +9952,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR11 - No entries found for base operation: " + operation_name)); "ERR12 - No entries found for base operation: " + operation_name));
return error_node(); return error_node();
} }
@ -9952,7 +9975,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR12 - Impossible argument count for base function: " + operation_name)); "ERR13 - Impossible argument count for base function: " + operation_name));
return error_node(); return error_node();
} }
@ -9973,7 +9996,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR13 - Invalid parameter count for function: " + operation_name)); "ERR14 - Invalid parameter count for function: " + operation_name));
return error_node(); return error_node();
} }
@ -9993,7 +10016,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR14 - Failed to parse condition for if-statement")); "ERR15 - Failed to parse condition for if-statement"));
return error_node(); return error_node();
} }
else if (!token_is(token_t::e_comma)) else if (!token_is(token_t::e_comma))
@ -10003,7 +10026,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR15 - Failed to parse consequent for if-statement")); "ERR16 - Failed to parse consequent for if-statement"));
return error_node(); return error_node();
} }
else if (!token_is(token_t::e_comma)) else if (!token_is(token_t::e_comma))
@ -10013,7 +10036,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR16 - Failed to parse alternative for if-statement")); "ERR17 - Failed to parse alternative for if-statement"));
return error_node(); return error_node();
} }
else if (!token_is(token_t::e_rbracket)) else if (!token_is(token_t::e_rbracket))
@ -10035,7 +10058,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR17 - Failed to parse condition for while-loop")); "ERR18 - Failed to parse condition for while-loop"));
return error_node(); return error_node();
} }
else if (!token_is(token_t::e_rbracket)) else if (!token_is(token_t::e_rbracket))
@ -10047,7 +10070,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR18 - Failed to parse branch for while-loop")); "ERR19 - Failed to parse branch for while-loop"));
return error_node(); return error_node();
} }
else if (!token_is(token_t::e_rcrlbracket)) else if (!token_is(token_t::e_rcrlbracket))
@ -10059,7 +10082,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR19 - Failed to parse branch for while-loop")); "ERR20 - Failed to parse branch for while-loop"));
return error_node(); return error_node();
} }
else else
@ -10086,7 +10109,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR20 - Unsupported vararg function: " + symbol)); "ERR21 - Unsupported vararg function: " + symbol));
return error_node(); return error_node();
} }
@ -10098,7 +10121,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR21 - Expected '(' for call to vararg function: " + symbol)); "ERR22 - Expected '(' for call to vararg function: " + symbol));
return error_node(); return error_node();
} }
@ -10116,7 +10139,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR22 - Expected ',' for call to vararg function: " + symbol)); "ERR23 - Expected ',' for call to vararg function: " + symbol));
return error_node(); return error_node();
} }
} }
@ -10142,7 +10165,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR21 - Expected '(' for call to vararg function: " + vararg_function_name)); "ERR24 - Expected '(' for call to vararg function: " + vararg_function_name));
return error_node(); return error_node();
} }
@ -10160,7 +10183,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR22 - Expected ',' for call to vararg function: " + vararg_function_name)); "ERR25 - Expected ',' for call to vararg function: " + vararg_function_name));
return error_node(); return error_node();
} }
} }
@ -10221,7 +10244,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_token, make_error(parser_error::e_token,
current_token_, current_token_,
"ERR23 - Invalid special function[1]: " + current_token_.value)); "ERR26 - Invalid special function[1]: " + current_token_.value));
return error_node(); return error_node();
} }
@ -10232,7 +10255,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_token, make_error(parser_error::e_token,
current_token_, current_token_,
"ERR24 - Invalid special function[2]: " + current_token_.value)); "ERR27 - Invalid special function[2]: " + current_token_.value));
return error_node(); return error_node();
} }
@ -10324,7 +10347,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR25 - Invalid number of parameters for function: " + symbol)); "ERR28 - Invalid number of parameters for function: " + symbol));
return error_node(); return error_node();
} }
} }
@ -10336,7 +10359,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR26 - Failed to generate node for function: '" + symbol + "'")); "ERR29 - Failed to generate node for function: '" + symbol + "'"));
return error_node(); return error_node();
} }
} }
@ -10356,7 +10379,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR27 - Failed to generate node for vararg function: '" + symbol + "'")); "ERR30 - Failed to generate node for vararg function: '" + symbol + "'"));
return error_node(); return error_node();
} }
} }
@ -10365,7 +10388,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR28 - Undefined variable or function: '" + symbol + "'")); "ERR31 - Undefined variable or function: '" + symbol + "'"));
return error_node(); return error_node();
} }
} }
@ -10409,7 +10432,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_symtab, make_error(parser_error::e_symtab,
current_token_, current_token_,
"ERR29 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token_.value)); "ERR32 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token_.value));
return error_node(); return error_node();
} }
} }
@ -10484,7 +10507,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR30 - Premature end of expression.[1]")); "ERR33 - Premature end of expression.[1]"));
return error_node(); return error_node();
} }
else else
@ -10492,7 +10515,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR31 - Premature end of expression.[2]")); "ERR34 - Premature end of expression.[2]"));
return error_node(); return error_node();
} }
} }
@ -10659,18 +10682,18 @@ namespace exprtk
(details::e_ceil == operation) || (details::e_cos == operation) || (details::e_ceil == operation) || (details::e_cos == operation) ||
(details::e_cosh == operation) || (details::e_exp == operation) || (details::e_cosh == operation) || (details::e_exp == operation) ||
(details::e_floor == operation) || (details::e_log == operation) || (details::e_floor == operation) || (details::e_log == operation) ||
(details::e_log10 == operation) || (details::e_log1p == operation) || (details::e_log10 == operation) || (details::e_log2 == operation) ||
(details::e_neg == operation) || (details::e_pos == operation) || (details::e_log1p == operation) || (details::e_neg == operation) ||
(details::e_round == operation) || (details::e_sin == operation) || (details::e_pos == operation) || (details::e_round == operation) ||
(details::e_sinh == operation) || (details::e_sqrt == operation) || (details::e_sin == operation) || (details::e_sinh == operation) ||
(details::e_tan == operation) || (details::e_tanh == operation) || (details::e_sqrt == operation) || (details::e_tan == operation) ||
(details::e_cot == operation) || (details::e_sec == operation) || (details::e_tanh == operation) || (details::e_cot == operation) ||
(details::e_csc == operation) || (details::e_r2d == operation) || (details::e_sec == operation) || (details::e_csc == operation) ||
(details::e_d2r == operation) || (details::e_d2g == operation) || (details::e_r2d == operation) || (details::e_d2r == operation) ||
(details::e_g2d == operation) || (details::e_notl == operation) || (details::e_d2g == operation) || (details::e_g2d == operation) ||
(details::e_sgn == operation) || (details::e_erf == operation) || (details::e_notl == operation) || (details::e_sgn == operation) ||
(details::e_erfc == operation) || (details::e_frac == operation) || (details::e_erf == operation) || (details::e_erfc == operation) ||
(details::e_trunc == operation); (details::e_frac == operation) || (details::e_trunc == operation);
} }
inline bool sf3_optimizable(const std::string sf3id, trinary_functor_t& tfunc) inline bool sf3_optimizable(const std::string sf3id, trinary_functor_t& tfunc)
@ -11125,6 +11148,7 @@ namespace exprtk
case_stmt(details::e_floor,details::floor_op) \ case_stmt(details::e_floor,details::floor_op) \
case_stmt(details:: e_log,details:: log_op) \ case_stmt(details:: e_log,details:: log_op) \
case_stmt(details::e_log10,details::log10_op) \ case_stmt(details::e_log10,details::log10_op) \
case_stmt(details:: e_log2,details:: log2_op) \
case_stmt(details::e_log1p,details::log1p_op) \ case_stmt(details::e_log1p,details::log1p_op) \
case_stmt(details:: e_neg,details:: neg_op) \ case_stmt(details:: e_neg,details:: neg_op) \
case_stmt(details:: e_pos,details:: pos_op) \ case_stmt(details:: e_pos,details:: pos_op) \
@ -14896,6 +14920,7 @@ namespace exprtk
register_unary_op(details::e_floor,details::floor_op) register_unary_op(details::e_floor,details::floor_op)
register_unary_op(details:: e_log,details:: log_op) register_unary_op(details:: e_log,details:: log_op)
register_unary_op(details::e_log10,details::log10_op) register_unary_op(details::e_log10,details::log10_op)
register_unary_op(details:: e_log2,details:: log2_op)
register_unary_op(details::e_log1p,details::log1p_op) register_unary_op(details::e_log1p,details::log1p_op)
register_unary_op(details:: e_neg,details:: neg_op) register_unary_op(details:: e_neg,details:: neg_op)
register_unary_op(details:: e_pos,details:: pos_op) register_unary_op(details:: e_pos,details:: pos_op)

View File

@ -1,11 +1,11 @@
C++ Mathematical Expression Toolkit Library C++ Mathematical Expression Toolkit Library
[INTRODUCTION] [INTRODUCTION]
The C++ Mathematical Expression Library (ExprTk) is a simple to use, The C++ Mathematical Expression Toolkit Library (ExprTk) is a simple
easy to integrate and extremely efficient mathematical expression to use, easy to integrate and extremely efficient mathematical
parsing and evaluation engine. The parsing engine supports various expression parsing and evaluation engine. The parsing engine supports
kinds of functional and logic processing semantics and is very easily numerous forms of functional and logic processing semantics and is
extendible. very easily extendible.
@ -15,20 +15,19 @@ operations, functions and processes:
(0) Basic operators: +, -, *, /, %, ^ (0) Basic operators: +, -, *, /, %, ^
(1) Functions: min, max, avg, sum, abs, ceil, floor, round, (1) Functions: abs, avg, ceil, clamp, erf, erfc, exp, floor,
roundn, exp, log, log10, logn, log1p, root, frac, inrange, log, log10, log1p, log2, logn,
sqrt, clamp, inrange, sgn, erf, erfc, frac, max, min, root, round, roundn, sgn, sqrt, sum,
trunc trunc
(2) Trigonometry: sin, cos, tan, acos, asin, atan, atan2, cosh, (2) Trigonometry: acos, asin, atan, atan2, cos, cosh, cot, csc,
cot, csc, sec, sinh, tanh, rad2deg, deg2rad, deg2grad, deg2rad, grad2deg, hypot, rad2deg,
deg2grad, grad2deg, hypot sec, sin, sinh, tan, tanh
(3) Equalities & (3) Equalities &
Inequalities: =, ==, <>, !=, <, <=, >, >= Inequalities: =, ==, <>, !=, <, <=, >, >=
(4) Boolean logic: and, or, xor, xnor, not, nand, nor, shr, shl, (4) Boolean logic: and, mand, mor, nand, nor, not, or, shl, shr,
true, false xnor, xor, true, false
(5) Conditional & (5) Conditional &
Loop statement: if-then-else, while Loop statement: if-then-else, while
@ -70,25 +69,27 @@ expressions that can be parsed and evaluated using the ExprTk library.
[COPYRIGHT NOTICE] [COPYRIGHT NOTICE]
Free use of the Mathematical Expression Toolkit Library is permitted Free use of the C++ Mathematical Expression Toolkit Library is
under the guidelines and in accordance with the most current version permitted under the guidelines and in accordance with the most current
of the Common Public License. version of the Common Public License.
http://www.opensource.org/licenses/cpl1.0.php http://www.opensource.org/licenses/cpl1.0.php
[DOWNLOADS & UPDATES] [DOWNLOADS & UPDATES]
All updates and the most recent version of the C++ Mathematical The most recent version of the C++ Mathematical Expression Toolkit
Expression Library can be found at: Library including all updates and tests can be found at the following
(1) http://www.partow.net/programming/exprtk/index.html locations:
(2) svn checkout http://exprtk.googlecode.com/svn/ exprtk
(1) http://www.partow.net/programming/exprtk/index.html
(2) svn checkout http://exprtk.googlecode.com/svn/ exprtk
[INSTALLATION] [INSTALLATION]
(1) exprtk.hpp should be placed in a project or system include path The header file exprtk.hpp should be placed in a project or system
(e.g: /usr/include/). include path (e.g: /usr/include/).
@ -230,6 +231,8 @@ Expression Library can be found at:
| log1p | Natural logarithm of 1 + x, where x is very small. | | log1p | Natural logarithm of 1 + x, where x is very small. |
| | (eg: log1p(x)) | | | (eg: log1p(x)) |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
| log2 | Base 2 logarithm of x |
+-----------+--------------------------------------------------------+
| logn | Base N logarithm of x (eg: logn(1235,8)) | | logn | Base N logarithm of x (eg: logn(1235,8)) |
| | where n > 0 and is an integer. | | | where n > 0 and is an integer. |
+-----------+--------------------------------------------------------+ +-----------+--------------------------------------------------------+
@ -392,55 +395,59 @@ correctly optimize such expressions for a given architecture.
[EXPRTK NOTES] [EXPRTK NOTES]
(00) Supported types are float, double and long double. (00) Precision and performance of expression evaluations are the
dominant principles of the ExprTk library.
(01) Standard mathematical operator precedence is applied (BEDMAS). (01) Supported types are float, double and long double.
(02) Supported user defined types are numeric and string variables (02) Standard mathematical operator precedence is applied (BEDMAS).
(03) Supported user defined types are numeric and string variables
and functions. and functions.
(03) All variable and function names are case-insensitive (04) All variable and function names are case-insensitive
(04) Variable and function names must begin with a letter (05) Variable and function names must begin with a letter
(A-Z or a-z), then can be comprised of any combination of (A-Z or a-z), then can be comprised of any combination of
letters, digits and underscores. (eg: x, var1 or power_func99) letters, digits and underscores. (eg: x, var1 or power_func99)
(05) Expression lengths are limited only by storage capacity. (06) Expression lengths are limited only by storage capacity.
(06) The life-time of objects registered with a symbol-table must (07) The life-time of objects registered with or created from a
span at least the life-time of expressions generated using specific symbol-table must span at least the life-time of
that symbol-table, otherwise the result will be undefined expressions generated using that symbol-table, otherwise
behavior. the result will be undefined behavior.
(07) Equal/Nequal routines use epsilons of 0.0000000001 and 0.000001 (08) Equal/Nequal are normalized equality routines, which use
for double and float types respectively. epsilons of 0.0000000001 and 0.000001 for double and float
types respectively.
(08) All trigonometric functions assume radian input unless (09) All trigonometric functions assume radian input unless
stated otherwise. stated otherwise.
(09) Expressions may contain white-space characters such as (10) Expressions may contain white-space characters such as
space, tabs, new-lines, control-feed et al. space, tabs, new-lines, control-feed et al.
('\n', '\r', '\t', '\b', '\v', '\f') ('\n', '\r', '\t', '\b', '\v', '\f')
(10) Strings may be constructed from any letters, digits or special (11) Strings may be constructed from any letters, digits or special
characters such as (~!@#$%^&*()[]|=+ ,./?<>;:"`~_), and must characters such as (~!@#$%^&*()[]|=+ ,./?<>;:"`~_), and must
be enclosed with single-quotes. be enclosed with single-quotes.
eg: 'Frankly, my dear, I don't give a damn!' eg: 'Frankly, my dear, I don't give a damn!'
(11) User defined normal functions can have up to 20 parameters, (12) User defined normal functions can have up to 20 parameters,
where as user defined vararg-functions can have an unlimited where as user defined vararg-functions can have an unlimited
number of parameters. number of parameters.
(12) The inbuilt polynomial functions can be at most of degree 12. (13) The inbuilt polynomial functions can be at most of degree 12.
(13) Where appropriate constant folding optimisations will be (14) Where appropriate constant folding optimisations will be
applied. (eg: The expression '2+(3-(x/y))' becomes '5-(x/y)') applied. (eg: The expression '2+(3-(x/y))' becomes '5-(x/y)')
(14) String processing capabilities are available by default. (15) String processing capabilities are available by default.
To turn them off, the following needs to be defined at To turn them off, the following needs to be defined at
compile time: exprtk_disable_string_capabilities compile time: exprtk_disable_string_capabilities
(15) Expressions may contain any of the following comment styles: (16) Expressions may contain any of the following comment styles:
1. // .... \n 1. // .... \n
2. # .... \n 2. # .... \n
3. /* .... */ 3. /* .... */