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

This commit is contained in:
Arash Partow 2016-10-09 16:31:52 +11:00
parent 5e3733ad8a
commit a3becad0e0
3 changed files with 194 additions and 43 deletions

View File

@ -66,7 +66,10 @@ namespace exprtk
namespace details
{
inline bool is_whitespace(const char c)
typedef unsigned char uchar_t;
typedef char char_t;
inline bool is_whitespace(const char_t c)
{
return (' ' == c) || ('\n' == c) ||
('\r' == c) || ('\t' == c) ||
@ -74,7 +77,7 @@ namespace exprtk
('\f' == c) ;
}
inline bool is_operator_char(const char c)
inline bool is_operator_char(const char_t c)
{
return ('+' == c) || ('-' == c) ||
('*' == c) || ('/' == c) ||
@ -89,43 +92,43 @@ namespace exprtk
('|' == c) || (';' == c) ;
}
inline bool is_letter(const char c)
inline bool is_letter(const char_t c)
{
return (('a' <= c) && (c <= 'z')) ||
(('A' <= c) && (c <= 'Z')) ;
}
inline bool is_digit(const char c)
inline bool is_digit(const char_t c)
{
return ('0' <= c) && (c <= '9');
}
inline bool is_letter_or_digit(const char c)
inline bool is_letter_or_digit(const char_t c)
{
return is_letter(c) || is_digit(c);
}
inline bool is_left_bracket(const char c)
inline bool is_left_bracket(const char_t c)
{
return ('(' == c) || ('[' == c) || ('{' == c);
}
inline bool is_right_bracket(const char c)
inline bool is_right_bracket(const char_t c)
{
return (')' == c) || (']' == c) || ('}' == c);
}
inline bool is_bracket(const char c)
inline bool is_bracket(const char_t c)
{
return is_left_bracket(c) || is_right_bracket(c);
}
inline bool is_sign(const char c)
inline bool is_sign(const char_t c)
{
return ('+' == c) || ('-' == c);
}
inline bool is_invalid(const char c)
inline bool is_invalid(const char_t c)
{
return !is_whitespace (c) &&
!is_operator_char(c) &&
@ -138,7 +141,7 @@ namespace exprtk
('\'' != c);
}
inline bool imatch(const char c1, const char c2)
inline bool imatch(const char_t c1, const char_t c2)
{
return std::tolower(c1) == std::tolower(c2);
}
@ -217,7 +220,7 @@ namespace exprtk
(('a' <= digit) && (digit <= 'f')) ;
}
inline unsigned char hex_to_bin(unsigned char h)
inline uchar_t hex_to_bin(uchar_t h)
{
if (('0' <= h) && (h <= '9'))
return (h - '0');
@ -339,8 +342,8 @@ namespace exprtk
for (std::size_t i = 0; i < length; ++i)
{
const char c1 = static_cast<char>(std::tolower(s1[i]));
const char c2 = static_cast<char>(std::tolower(s2[i]));
const char_t c1 = static_cast<char>(std::tolower(s1[i]));
const char_t c2 = static_cast<char>(std::tolower(s2[i]));
if (c1 > c2)
return false;
@ -502,7 +505,7 @@ namespace exprtk
struct cs_match
{
static inline bool cmp(const char c0, const char c1)
static inline bool cmp(const char_t c0, const char_t c1)
{
return (c0 == c1);
}
@ -510,7 +513,7 @@ namespace exprtk
struct cis_match
{
static inline bool cmp(const char c0, const char c1)
static inline bool cmp(const char_t c0, const char_t c1)
{
return (std::tolower(c0) == std::tolower(c1));
}
@ -621,7 +624,7 @@ namespace exprtk
{
if ('*' == (*p_itr))
{
const char target = static_cast<char>(std::toupper(*(p_itr - 1)));
const char_t target = static_cast<char>(std::toupper(*(p_itr - 1)));
if ('*' == target)
{
@ -1697,8 +1700,8 @@ namespace exprtk
template <typename Iterator, typename T>
static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
{
static const char inf_uc[] = "INFINITY";
static const char inf_lc[] = "infinity";
static const char_t inf_uc[] = "INFINITY";
static const char_t inf_lc[] = "infinity";
static const std::size_t inf_length = 8;
const std::size_t length = std::distance(itr,end);
@ -2091,6 +2094,7 @@ namespace exprtk
typedef token token_t;
typedef std::vector<token_t> token_list_t;
typedef std::vector<token_t>::iterator token_list_itr_t;
typedef details::char_t char_t;
generator()
: base_itr_(0),
@ -2255,7 +2259,7 @@ namespace exprtk
// 3. /* .... */
struct test
{
static inline bool comment_start(const char c0, const char c1, int& mode, int& incr)
static inline bool comment_start(const char_t c0, const char_t c1, int& mode, int& incr)
{
mode = 0;
if ('#' == c0) { mode = 1; incr = 1; }
@ -2267,7 +2271,7 @@ namespace exprtk
return (0 != mode);
}
static inline bool comment_end(const char c0, const char c1, const int mode)
static inline bool comment_end(const char_t c0, const char_t c1, const int mode)
{
return (
((1 == mode) && ('\n' == c0)) ||
@ -2358,15 +2362,15 @@ namespace exprtk
{
token_t t;
const char c0 = s_itr_[0];
const char_t c0 = s_itr_[0];
if (!is_end(s_itr_ + 1))
{
const char c1 = s_itr_[1];
const char_t c1 = s_itr_[1];
if (!is_end(s_itr_ + 2))
{
const char c2 = s_itr_[2];
const char_t c2 = s_itr_[2];
if ((c0 == '<') && (c1 == '=') && (c2 == '>'))
{
@ -3283,7 +3287,7 @@ namespace exprtk
exprtk::details::is_bracket(t.value[0])
)
{
char c = t.value[0];
details::char_t c = t.value[0];
if (t.type == lexer::token::e_lbracket) stack_.push(std::make_pair(')',t.position));
else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position));
@ -4142,16 +4146,40 @@ namespace exprtk
: v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
{}
value_t& operator()()
inline value_t& operator()()
{
return v_;
}
const value_t& operator()() const
inline const value_t& operator()() const
{
return v_;
}
template <typename IntType>
inline bool to_int(IntType& i) const
{
if (!exprtk::details::numeric::is_integer(v_))
return false;
i = static_cast<IntType>(v_);
return true;
}
template <typename UIntType>
inline bool to_uint(UIntType& u) const
{
if (v_ < T(0))
return false;
else if (!exprtk::details::numeric::is_integer(v_))
return false;
u = static_cast<UIntType>(v_);
return true;
}
T& v_;
};
};
@ -5252,7 +5280,7 @@ namespace exprtk
private:
mutable vector_holder_base* vector_holder_base_;
unsigned char buffer[64];
uchar_t buffer[64];
};
template <typename T>
@ -17557,7 +17585,7 @@ namespace exprtk
for (std::size_t i = error.token.position; i > 0; --i)
{
const char c = expression[i];
const details::char_t c = expression[i];
if (('\n' == c) || ('\r' == c))
{
@ -18455,12 +18483,9 @@ namespace exprtk
struct parser_state
{
parser_state()
: parsing_return_stmt(false),
parsing_break_stmt (false),
return_stmt_present(false),
side_effect_present(false),
scope_depth(0)
{}
{
reset();
}
void reset()
{
@ -21225,7 +21250,7 @@ namespace exprtk
nse.type = scope_element::e_variable;
nse.depth = state_.scope_depth;
nse.data = new T(T(0));
nse.var_node = new variable_node_t(*(T*)(nse.data));
nse.var_node = node_allocator_.allocate<variable_node_t>(*(T*)(nse.data));
if (!sem_.add_element(nse))
{
@ -22429,8 +22454,8 @@ namespace exprtk
for (std::size_t i = 0; i < param_seq_list_.size(); ++i)
{
std::size_t diff_index = 0;
char diff_value = 0;
details::char_t diff_value = 0;
std::size_t diff_index = 0;
bool result = details::sequence_match(param_seq_list_[i],
param_seq,
@ -23519,7 +23544,7 @@ namespace exprtk
nse.type = scope_element::e_variable;
nse.depth = state_.scope_depth;
nse.data = new T(T(0));
nse.var_node = new variable_node_t(*(T*)(nse.data));
nse.var_node = node_allocator_.allocate<variable_node_t>(*(T*)(nse.data));
if (!sem_.add_element(nse))
{
@ -23609,7 +23634,7 @@ namespace exprtk
nse.depth = state_.scope_depth;
nse.ip_index = sem_.next_ip_index();
nse.data = new T(T(0));
nse.var_node = new variable_node_t(*(T*)(nse.data));
nse.var_node = node_allocator_.allocate<variable_node_t>(*(T*)(nse.data));
if (!sem_.add_element(nse))
{
@ -26535,7 +26560,7 @@ namespace exprtk
}
break;
case e_st_vecelem : {
case e_st_vecelem : {
typedef details::vector_holder<T> vector_holder_t;
vector_holder_t& vh = static_cast<vector_elem_node_t*>(node)->vec_holder();

View File

@ -56,12 +56,12 @@ void file_io()
" return [false]; "
" } ";
exprtk::rtl::io::file::package<T> fileio_package;
exprtk::rtl::io::println<T> println;
exprtk::rtl::io::file::package<T> package;
symbol_table_t symbol_table;
symbol_table.add_function("println",println);
symbol_table.add_package (package);
symbol_table.add_package (fileio_package );
expression_t expression;
expression.register_symbol_table(symbol_table);

View File

@ -6336,6 +6336,132 @@ inline bool run_test18()
return false;
}
{
bool failure = false;
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::vector<T> v0;
std::vector<T> s;
#define pb(v,N) \
v.push_back(T(N)); \
pb(v0,0) pb(v0,1) pb(v0,2) pb(v0,3) pb(v0,4)
pb(v0,5) pb(v0,6) pb(v0,7) pb(v0,8) pb(v0,9)
pb(s, 3) pb(s, 6) pb(s, 9) pb(s,12)
pb(s,15) pb(s,18) pb(s,21)
#undef pb
const std::string expr_string = "var i := 0; var j := 1; var k := 2; v[i] + v[j] + v[k]";
exprtk::vector_view<T> v = exprtk::make_vector_view(v0,4);
symbol_table_t symbol_table;
symbol_table.add_vector("v",v);
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
if (!parser.compile(expr_string,expression))
{
printf("run_test18() - Error: %s\tExpression: %s\n",
parser.error().c_str(),
expr_string.c_str());
failure = true;
}
for (std::size_t i = 0; i < v0.size() - 4; ++i)
{
v.rebase(v0.data() + i);
T sum = expression.value();
if (not_equal(sum,s[i]))
{
printf("run_test18() - Error in evaluation! (8) Expression: %s Expected: %5.3f Computed: %5.3f\n",
expr_string.c_str(),
s[i],
sum);
failure = true;
}
}
if (failure)
return false;
}
{
bool failure = false;
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
std::vector<T> v0;
std::vector<T> s;
#define pb(v,N) \
v.push_back(T(N)); \
pb(v0,0) pb(v0,1) pb(v0,2) pb(v0,3) pb(v0,4)
pb(v0,5) pb(v0,6) pb(v0,7) pb(v0,8) pb(v0,9)
pb(s, 3) pb(s, 6) pb(s, 9) pb(s,12)
pb(s,15) pb(s,18) pb(s,21)
#undef pb
const std::string expr_string = "var i := 0; v[i + 0] + v[i + 1] + v[i + 2]";
exprtk::vector_view<T> v = exprtk::make_vector_view(v0,4);
symbol_table_t symbol_table;
symbol_table.add_vector("v",v);
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
if (!parser.compile(expr_string,expression))
{
printf("run_test18() - Error: %s\tExpression: %s\n",
parser.error().c_str(),
expr_string.c_str());
failure = true;
}
for (std::size_t i = 0; i < v0.size() - 4; ++i)
{
v.rebase(v0.data() + i);
T sum = expression.value();
if (not_equal(sum,s[i]))
{
printf("run_test18() - Error in evaluation! (9) Expression: %s Expected: %5.3f Computed: %5.3f\n",
expr_string.c_str(),
s[i],
sum);
failure = true;
}
}
if (failure)
return false;
}
return true;
}