C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
d95db43aa9
commit
ce23204895
765
exprtk.hpp
765
exprtk.hpp
File diff suppressed because it is too large
Load Diff
|
@ -63,19 +63,24 @@ bool load_expression(exprtk::symbol_table<T>& symbol_table,
|
||||||
Sequence<exprtk::expression<T>,Allocator>& expr_seq)
|
Sequence<exprtk::expression<T>,Allocator>& expr_seq)
|
||||||
{
|
{
|
||||||
exprtk::parser<double> parser;
|
exprtk::parser<double> parser;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < expression_list_size; ++i)
|
for (std::size_t i = 0; i < expression_list_size; ++i)
|
||||||
{
|
{
|
||||||
exprtk::expression<double> expression;
|
exprtk::expression<double> expression;
|
||||||
expression.register_symbol_table(symbol_table);
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
if (!parser.compile(expression_list[i],expression))
|
if (!parser.compile(expression_list[i],expression))
|
||||||
{
|
{
|
||||||
printf("[load_expression] - Parser Error: %s\tExpression: %s\n",
|
printf("[load_expression] - Parser Error: %s\tExpression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_list[i].c_str());
|
expression_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_seq.push_back(expression);
|
expr_seq.push_back(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,8 +91,10 @@ void run_exprtk_benchmark(T& x, T& y,
|
||||||
{
|
{
|
||||||
T total = T(0);
|
T total = T(0);
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
exprtk::timer timer;
|
exprtk::timer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
for (x = lower_bound_x; x <= upper_bound_x; x += delta)
|
for (x = lower_bound_x; x <= upper_bound_x; x += delta)
|
||||||
{
|
{
|
||||||
for (y = lower_bound_y; y <= upper_bound_y; y += delta)
|
for (y = lower_bound_y; y <= upper_bound_y; y += delta)
|
||||||
|
@ -96,7 +103,9 @@ void run_exprtk_benchmark(T& x, T& y,
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
if (T(0) != total)
|
if (T(0) != total)
|
||||||
printf("[exprtk] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n",
|
printf("[exprtk] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n",
|
||||||
timer.time(),
|
timer.time(),
|
||||||
|
@ -113,8 +122,10 @@ void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_
|
||||||
{
|
{
|
||||||
T total = T(0);
|
T total = T(0);
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
exprtk::timer timer;
|
exprtk::timer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
for (x = lower_bound_x; x <= upper_bound_x; x += delta)
|
for (x = lower_bound_x; x <= upper_bound_x; x += delta)
|
||||||
{
|
{
|
||||||
for (y = lower_bound_y; y <= upper_bound_y; y += delta)
|
for (y = lower_bound_y; y <= upper_bound_y; y += delta)
|
||||||
|
@ -123,7 +134,9 @@ void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
if (T(0) != total)
|
if (T(0) != total)
|
||||||
printf("[native] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n",
|
printf("[native] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n",
|
||||||
timer.time(),
|
timer.time(),
|
||||||
|
@ -146,6 +159,7 @@ bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
|
||||||
{
|
{
|
||||||
exprtk::timer timer;
|
exprtk::timer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
{
|
{
|
||||||
if (!parser.compile(expression_list[i],expression))
|
if (!parser.compile(expression_list[i],expression))
|
||||||
|
@ -153,15 +167,19 @@ bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
|
||||||
printf("[run_parse_benchmark] - Parser Error: %s\tExpression: %s\n",
|
printf("[run_parse_benchmark] - Parser Error: %s\tExpression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_list[i].c_str());
|
expression_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
printf("[parse] Total Time:%12.8f Rate:%14.3fparse/sec Expression: %s\n",
|
printf("[parse] Total Time:%12.8f Rate:%14.3fparse/sec Expression: %s\n",
|
||||||
timer.time(),
|
timer.time(),
|
||||||
rounds / timer.time(),
|
rounds / timer.time(),
|
||||||
expression_list[i].c_str());
|
expression_list[i].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,10 +296,12 @@ int main(int argc, char* argv[])
|
||||||
if (argc >= 2)
|
if (argc >= 2)
|
||||||
{
|
{
|
||||||
const std::string file_name = argv[1];
|
const std::string file_name = argv[1];
|
||||||
|
|
||||||
if (argc == 2)
|
if (argc == 2)
|
||||||
perform_file_based_benchmark(file_name);
|
perform_file_based_benchmark(file_name);
|
||||||
else
|
else
|
||||||
perform_file_based_benchmark(file_name,atoi(argv[2]));
|
perform_file_based_benchmark(file_name,atoi(argv[2]));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,16 +399,20 @@ void pgo_primer()
|
||||||
std::size_t load_expression_file(const std::string& file_name, std::deque<std::string>& expression_list)
|
std::size_t load_expression_file(const std::string& file_name, std::deque<std::string>& expression_list)
|
||||||
{
|
{
|
||||||
std::ifstream stream(file_name.c_str());
|
std::ifstream stream(file_name.c_str());
|
||||||
|
|
||||||
if (!stream) return 0;
|
if (!stream) return 0;
|
||||||
|
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
buffer.reserve(1024);
|
buffer.reserve(1024);
|
||||||
std::size_t line_count = 0;
|
std::size_t line_count = 0;
|
||||||
|
|
||||||
while (std::getline(stream,buffer))
|
while (std::getline(stream,buffer))
|
||||||
{
|
{
|
||||||
if (buffer.empty())
|
if (buffer.empty())
|
||||||
continue;
|
continue;
|
||||||
else if ('#' == buffer[0])
|
else if ('#' == buffer[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
++line_count;
|
++line_count;
|
||||||
expression_list.push_back(buffer);
|
expression_list.push_back(buffer);
|
||||||
}
|
}
|
||||||
|
@ -399,6 +423,7 @@ std::size_t load_expression_file(const std::string& file_name, std::deque<std::s
|
||||||
void perform_file_based_benchmark(const std::string& file_name, const std::size_t& rounds)
|
void perform_file_based_benchmark(const std::string& file_name, const std::size_t& rounds)
|
||||||
{
|
{
|
||||||
std::deque<std::string> expr_str_list;
|
std::deque<std::string> expr_str_list;
|
||||||
|
|
||||||
if (0 == load_expression_file(file_name,expr_str_list))
|
if (0 == load_expression_file(file_name,expr_str_list))
|
||||||
{
|
{
|
||||||
std::cout << "Failed to load any expressions from: " << file_name << "\n";
|
std::cout << "Failed to load any expressions from: " << file_name << "\n";
|
||||||
|
@ -463,17 +488,21 @@ void perform_file_based_benchmark(const std::string& file_name, const std::size_
|
||||||
|
|
||||||
{
|
{
|
||||||
parser_t parser;
|
parser_t parser;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < expr_str_list.size(); ++i)
|
for (std::size_t i = 0; i < expr_str_list.size(); ++i)
|
||||||
{
|
{
|
||||||
expression_t expression;
|
expression_t expression;
|
||||||
expression.register_symbol_table(symbol_table);
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
if (!parser.compile(expr_str_list[i],expression))
|
if (!parser.compile(expr_str_list[i],expression))
|
||||||
{
|
{
|
||||||
printf("[perform_file_based_benchmark] - Parser Error: %s\tExpression: %s\n",
|
printf("[perform_file_based_benchmark] - Parser Error: %s\tExpression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
expression_list.push_back(expression);
|
expression_list.push_back(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -483,6 +512,7 @@ void perform_file_based_benchmark(const std::string& file_name, const std::size_
|
||||||
double single_eval_total_time = 0.0;
|
double single_eval_total_time = 0.0;
|
||||||
|
|
||||||
total_timer.start();
|
total_timer.start();
|
||||||
|
|
||||||
for (std::size_t i = 0; i < expression_list.size(); ++i)
|
for (std::size_t i = 0; i < expression_list.size(); ++i)
|
||||||
{
|
{
|
||||||
expression_t& e = expression_list[i];
|
expression_t& e = expression_list[i];
|
||||||
|
@ -499,12 +529,14 @@ void perform_file_based_benchmark(const std::string& file_name, const std::size_
|
||||||
|
|
||||||
timer.start();
|
timer.start();
|
||||||
double sum = 0.0;
|
double sum = 0.0;
|
||||||
|
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
{
|
{
|
||||||
sum += e.value();
|
sum += e.value();
|
||||||
std::swap(a,b);
|
std::swap(a,b);
|
||||||
std::swap(x,y);
|
std::swap(x,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
printf("Expression %3d of %3d %9.3f ns\t%10d ns\t(%30.10f) '%s'\n",
|
printf("Expression %3d of %3d %9.3f ns\t%10d ns\t(%30.10f) '%s'\n",
|
||||||
|
@ -519,6 +551,7 @@ void perform_file_based_benchmark(const std::string& file_name, const std::size_
|
||||||
|
|
||||||
single_eval_total_time += (timer.time() * 1000000000.0) / (1.0 * rounds);
|
single_eval_total_time += (timer.time() * 1000000000.0) / (1.0 * rounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
total_timer.stop();
|
total_timer.stop();
|
||||||
|
|
||||||
printf("[*] Number Of Evals: %15.0f\n",
|
printf("[*] Number Of Evals: %15.0f\n",
|
||||||
|
|
|
@ -1129,6 +1129,7 @@ inline bool test_expression(const std::string& expression_string, const T& expec
|
||||||
printf("test_expression() - Error: %s Expression: %s\n",
|
printf("test_expression() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1137,6 +1138,7 @@ inline bool test_expression(const std::string& expression_string, const T& expec
|
||||||
{
|
{
|
||||||
printf("test_expression() - Error: Expression did not compile to a constant! Expression: %s\n",
|
printf("test_expression() - Error: Expression did not compile to a constant! Expression: %s\n",
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1148,6 +1150,7 @@ inline bool test_expression(const std::string& expression_string, const T& expec
|
||||||
expression_string.c_str(),
|
expression_string.c_str(),
|
||||||
(double)expected_result,
|
(double)expected_result,
|
||||||
(double)result);
|
(double)result);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,8 +1173,10 @@ inline bool run_test00()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1538,6 +1543,7 @@ inline bool run_test01()
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
{
|
{
|
||||||
bool loop_result = true;
|
bool loop_result = true;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < test_list_size; ++i)
|
for (std::size_t i = 0; i < test_list_size; ++i)
|
||||||
{
|
{
|
||||||
test_xy<T>& test = const_cast<test_xy<T>&>(test_list[i]);
|
test_xy<T>& test = const_cast<test_xy<T>&>(test_list[i]);
|
||||||
|
@ -1554,12 +1560,15 @@ inline bool run_test01()
|
||||||
|
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
if (!parser.compile(test.expr,expression))
|
if (!parser.compile(test.expr,expression))
|
||||||
{
|
{
|
||||||
printf("run_test01() - Error: %s Expression: %s\n",
|
printf("run_test01() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
test.expr.c_str());
|
test.expr.c_str());
|
||||||
|
|
||||||
loop_result = false;
|
loop_result = false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1572,6 +1581,7 @@ inline bool run_test01()
|
||||||
test.expr.c_str(),
|
test.expr.c_str(),
|
||||||
(double)test.result,
|
(double)test.result,
|
||||||
(double)result);
|
(double)result);
|
||||||
|
|
||||||
loop_result = false;
|
loop_result = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1662,12 +1672,15 @@ inline bool run_test01()
|
||||||
|
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
if (!parser.compile(test.expr,expression))
|
if (!parser.compile(test.expr,expression))
|
||||||
{
|
{
|
||||||
printf("run_test01() - Error: %s Expression: %s\n",
|
printf("run_test01() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
test.expr.c_str());
|
test.expr.c_str());
|
||||||
|
|
||||||
loop_result = false;
|
loop_result = false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1741,12 +1754,15 @@ inline bool run_test01()
|
||||||
|
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
if (!parser.compile(expr_list[i],expression))
|
if (!parser.compile(expr_list[i],expression))
|
||||||
{
|
{
|
||||||
printf("run_test01() - Error: %s Expression: %s\n",
|
printf("run_test01() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_list[i].c_str());
|
expr_list[i].c_str());
|
||||||
|
|
||||||
loop_result = false;
|
loop_result = false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2077,6 +2093,7 @@ inline bool run_test02()
|
||||||
printf("run_test02() - Error: %s Expression: %s\n",
|
printf("run_test02() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
test.expr.c_str());
|
test.expr.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2098,8 +2115,10 @@ inline bool run_test02()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2161,6 +2180,7 @@ inline bool run_test03()
|
||||||
printf("run_test03() - Error - Invalid number of variables in symbol_table! Expected: %d got: %d\n",
|
printf("run_test03() - Error - Invalid number of variables in symbol_table! Expected: %d got: %d\n",
|
||||||
static_cast<unsigned int>(variable_list_size),
|
static_cast<unsigned int>(variable_list_size),
|
||||||
static_cast<unsigned int>(symbol_table.variable_count()));
|
static_cast<unsigned int>(symbol_table.variable_count()));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2176,6 +2196,7 @@ inline bool run_test03()
|
||||||
printf("run_test03() - Error: %s Expression: %s\n",
|
printf("run_test03() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2217,6 +2238,7 @@ inline bool run_test04()
|
||||||
printf("run_test04() - Error: %s Expression: %s\n",
|
printf("run_test04() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2237,6 +2259,7 @@ inline bool run_test04()
|
||||||
(double)result2,
|
(double)result2,
|
||||||
(double)x,
|
(double)x,
|
||||||
(double)y);
|
(double)y);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,6 +2300,7 @@ inline bool run_test05()
|
||||||
printf("run_test05() - Error: %s Expression: %s\n",
|
printf("run_test05() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2306,6 +2330,7 @@ inline bool run_test05()
|
||||||
(double)x,
|
(double)x,
|
||||||
(double)y,
|
(double)y,
|
||||||
static_cast<unsigned int>(i));
|
static_cast<unsigned int>(i));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2339,6 +2364,7 @@ inline bool run_test06()
|
||||||
printf("run_test06() - Error: %s Expression: %s\n",
|
printf("run_test06() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2358,6 +2384,7 @@ inline bool run_test06()
|
||||||
printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n",
|
printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n",
|
||||||
(double)(pi / T(2)),
|
(double)(pi / T(2)),
|
||||||
(double)total_area1);
|
(double)total_area1);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2410,6 +2437,7 @@ inline bool run_test07()
|
||||||
(double)x,
|
(double)x,
|
||||||
(double)deriv1_real_result,
|
(double)deriv1_real_result,
|
||||||
(double)deriv1_result1);
|
(double)deriv1_result1);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2431,6 +2459,7 @@ inline bool run_test07()
|
||||||
(double)x,
|
(double)x,
|
||||||
(double)deriv2_real_result,
|
(double)deriv2_real_result,
|
||||||
(double)deriv2_result1);
|
(double)deriv2_result1);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2452,6 +2481,7 @@ inline bool run_test07()
|
||||||
(double)x,
|
(double)x,
|
||||||
(double)deriv3_real_result,
|
(double)deriv3_real_result,
|
||||||
(double)deriv3_result1);
|
(double)deriv3_result1);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2636,6 +2666,7 @@ inline bool run_test08()
|
||||||
printf("run_test08() - Error: %s Expression: %s\n",
|
printf("run_test08() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str[j].c_str());
|
expr_str[j].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2716,6 +2747,7 @@ inline bool run_test09()
|
||||||
printf("run_test09() - Error: %s Expression: %s\n",
|
printf("run_test09() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2743,6 +2775,7 @@ inline bool run_test09()
|
||||||
printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n",
|
printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n",
|
||||||
(double)expected,
|
(double)expected,
|
||||||
(double)result);
|
(double)result);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2772,6 +2805,7 @@ inline bool run_test10()
|
||||||
static inline bool variable(exprtk::symbol_table<T>& symbol_table, const std::string& variable_name, const T& value)
|
static inline bool variable(exprtk::symbol_table<T>& symbol_table, const std::string& variable_name, const T& value)
|
||||||
{
|
{
|
||||||
exprtk::details::variable_node<T>* var = symbol_table.get_variable(variable_name);
|
exprtk::details::variable_node<T>* var = symbol_table.get_variable(variable_name);
|
||||||
|
|
||||||
if (var)
|
if (var)
|
||||||
return (!not_equal(var->ref(),value));
|
return (!not_equal(var->ref(),value));
|
||||||
else
|
else
|
||||||
|
@ -2781,6 +2815,7 @@ inline bool run_test10()
|
||||||
static inline bool string(exprtk::symbol_table<T>& symbol_table, const std::string& string_name, const std::string& str)
|
static inline bool string(exprtk::symbol_table<T>& symbol_table, const std::string& string_name, const std::string& str)
|
||||||
{
|
{
|
||||||
exprtk::details::stringvar_node<T>* str_node = symbol_table.get_stringvar(string_name);
|
exprtk::details::stringvar_node<T>* str_node = symbol_table.get_stringvar(string_name);
|
||||||
|
|
||||||
if (str_node)
|
if (str_node)
|
||||||
return (str_node->ref() == str);
|
return (str_node->ref() == str);
|
||||||
else
|
else
|
||||||
|
@ -3173,11 +3208,13 @@ inline bool run_test10()
|
||||||
|
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
if (!parser.compile(expression_string,expression0))
|
if (!parser.compile(expression_string,expression0))
|
||||||
{
|
{
|
||||||
printf("run_test10() - Error: %s Expression: %s\n",
|
printf("run_test10() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3189,11 +3226,13 @@ inline bool run_test10()
|
||||||
|
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
if (!parser.compile(expression_string,expression1))
|
if (!parser.compile(expression_string,expression1))
|
||||||
{
|
{
|
||||||
printf("run_test10() - Error: %s Expression: %s\n",
|
printf("run_test10() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3230,14 +3269,18 @@ inline bool run_test10()
|
||||||
|
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
parser.cache_symbols() = true;
|
parser.cache_symbols() = true;
|
||||||
|
|
||||||
if (!parser.compile(expression_string,expression))
|
if (!parser.compile(expression_string,expression))
|
||||||
{
|
{
|
||||||
printf("run_test10() - Error: %s Expression: %s\n",
|
printf("run_test10() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.expression_symbols(variable_list);
|
parser.expression_symbols(variable_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3553,11 +3596,13 @@ inline bool run_test10()
|
||||||
|
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
if (!parser.compile(expression_list[i],expression))
|
if (!parser.compile(expression_list[i],expression))
|
||||||
{
|
{
|
||||||
printf("run_test10() - swaps Error: %s Expression: %s\n",
|
printf("run_test10() - swaps Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_list[i].c_str());
|
expression_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3573,9 +3618,11 @@ inline bool run_test10()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failed)
|
if (failed)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3602,11 +3649,13 @@ inline bool run_test11()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
if (!parser.compile(expression_string,expression))
|
if (!parser.compile(expression_string,expression))
|
||||||
{
|
{
|
||||||
printf("run_test11() - Error: %s Expression: %s\n",
|
printf("run_test11() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_string.c_str());
|
expression_string.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3627,6 +3676,7 @@ inline bool run_test11()
|
||||||
|
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
if (!parser.compile(expression_string,expression))
|
if (!parser.compile(expression_string,expression))
|
||||||
{
|
{
|
||||||
printf("run_test11() - Error: %s Expression: %s\n",
|
printf("run_test11() - Error: %s Expression: %s\n",
|
||||||
|
@ -3732,11 +3782,13 @@ inline bool run_test12()
|
||||||
|
|
||||||
{
|
{
|
||||||
exprtk::parser<T> parser;
|
exprtk::parser<T> parser;
|
||||||
|
|
||||||
if (!parser.compile(expr_str,expression))
|
if (!parser.compile(expr_str,expression))
|
||||||
{
|
{
|
||||||
printf("run_test12() - Error: %s Expression: %s\n",
|
printf("run_test12() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str.c_str());
|
expr_str.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3827,6 +3879,7 @@ inline bool run_test13()
|
||||||
printf("run_test13() - Error: %s Expression: %s\n",
|
printf("run_test13() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str.c_str());
|
expr_str.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3848,16 +3901,21 @@ inline std::size_t load_expressions(const std::string& file_name,
|
||||||
Sequence<std::string,Allocator>& sequence)
|
Sequence<std::string,Allocator>& sequence)
|
||||||
{
|
{
|
||||||
std::ifstream stream(file_name.c_str());
|
std::ifstream stream(file_name.c_str());
|
||||||
|
|
||||||
if (!stream) return 0;
|
if (!stream) return 0;
|
||||||
|
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
buffer.reserve(1024);
|
buffer.reserve(1024);
|
||||||
|
|
||||||
std::size_t line_count = 0;
|
std::size_t line_count = 0;
|
||||||
|
|
||||||
while (std::getline(stream,buffer))
|
while (std::getline(stream,buffer))
|
||||||
{
|
{
|
||||||
if (buffer.empty())
|
if (buffer.empty())
|
||||||
continue;
|
continue;
|
||||||
else if ('#' == buffer[0])
|
else if ('#' == buffer[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
++line_count;
|
++line_count;
|
||||||
sequence.push_back(buffer);
|
sequence.push_back(buffer);
|
||||||
}
|
}
|
||||||
|
@ -3939,6 +3997,7 @@ inline bool run_test14()
|
||||||
printf("run_test14() - Error: %s Expression: %s\n",
|
printf("run_test14() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3951,9 +4010,11 @@ inline bool run_test14()
|
||||||
for (std::size_t i = 0; i < expression_list.size(); ++i)
|
for (std::size_t i = 0; i < expression_list.size(); ++i)
|
||||||
{
|
{
|
||||||
T result = expression_list[i].value();
|
T result = expression_list[i].value();
|
||||||
|
|
||||||
if (result != T(1))
|
if (result != T(1))
|
||||||
{
|
{
|
||||||
failure = true;
|
failure = true;
|
||||||
|
|
||||||
printf("run_test14() - Error with evaluation of expression: %s\n",
|
printf("run_test14() - Error with evaluation of expression: %s\n",
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
}
|
}
|
||||||
|
@ -4020,6 +4081,7 @@ inline bool run_test15()
|
||||||
printf("run_test15() - Error: %s Expression: %s\n",
|
printf("run_test15() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4039,6 +4101,7 @@ inline bool run_test15()
|
||||||
printf("run_test15() - Error: %s Expression: %s\n",
|
printf("run_test15() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
base_expr_str.c_str());
|
base_expr_str.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4056,6 +4119,7 @@ inline bool run_test15()
|
||||||
(double)base_result,
|
(double)base_result,
|
||||||
(double)result,
|
(double)result,
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4198,6 +4262,7 @@ inline bool run_test16()
|
||||||
printf("run_test16() - Error: %s Expression: %s\n",
|
printf("run_test16() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4212,6 +4277,7 @@ inline bool run_test16()
|
||||||
{
|
{
|
||||||
printf("run_test16() - Error in evaluation! (1) Expression: %s\n",
|
printf("run_test16() - Error in evaluation! (1) Expression: %s\n",
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4314,6 +4380,7 @@ inline bool run_test17()
|
||||||
printf("run_test17() - Error: %s Expression: %s\n",
|
printf("run_test17() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4328,6 +4395,7 @@ inline bool run_test17()
|
||||||
{
|
{
|
||||||
printf("run_test17() - Error in evaluation! (1) Expression: %s\n",
|
printf("run_test17() - Error in evaluation! (1) Expression: %s\n",
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4341,10 +4409,12 @@ struct va_func : public exprtk::ivararg_function<T>
|
||||||
inline T operator()(const std::vector<T>& arglist)
|
inline T operator()(const std::vector<T>& arglist)
|
||||||
{
|
{
|
||||||
T result = T(0);
|
T result = T(0);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < arglist.size(); ++i)
|
for (std::size_t i = 0; i < arglist.size(); ++i)
|
||||||
{
|
{
|
||||||
result += arglist[i];
|
result += arglist[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -4409,6 +4479,7 @@ inline bool run_test18()
|
||||||
printf("run_test18() - Error: %s Expression: %s\n",
|
printf("run_test18() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4423,6 +4494,7 @@ inline bool run_test18()
|
||||||
{
|
{
|
||||||
printf("run_test18() - Error in evaluation! (1) Expression: %s\n",
|
printf("run_test18() - Error in evaluation! (1) Expression: %s\n",
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4499,6 +4571,7 @@ inline bool run_test19()
|
||||||
printf("run_test19() - Error: %s Expression: %s\n",
|
printf("run_test19() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4513,6 +4586,7 @@ inline bool run_test19()
|
||||||
{
|
{
|
||||||
printf("run_test19() - Error in evaluation! (1) Expression: %s\n",
|
printf("run_test19() - Error in evaluation! (1) Expression: %s\n",
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4621,6 +4695,7 @@ inline bool run_test19()
|
||||||
printf("run_test19() - Error: %s Expression: %s\n",
|
printf("run_test19() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4632,6 +4707,7 @@ inline bool run_test19()
|
||||||
expr_str_list[i].c_str(),
|
expr_str_list[i].c_str(),
|
||||||
result_list[i],
|
result_list[i],
|
||||||
result);
|
result);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4760,6 +4836,7 @@ inline bool run_test19()
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
static_cast<unsigned int>(i),
|
static_cast<unsigned int>(i),
|
||||||
expression_str[i].c_str());
|
expression_str[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4945,6 +5022,7 @@ inline bool run_test19()
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
static_cast<unsigned int>(i),
|
static_cast<unsigned int>(i),
|
||||||
expression_str[i].c_str());
|
expression_str[i].c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5066,6 +5144,7 @@ inline bool run_test19()
|
||||||
printf("run_test19() - Error: %s Expression: %s\n",
|
printf("run_test19() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_str.c_str());
|
expression_str.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5083,6 +5162,7 @@ inline bool run_test19()
|
||||||
expression_str.c_str(),
|
expression_str.c_str(),
|
||||||
(double)std::sqrt(x),
|
(double)std::sqrt(x),
|
||||||
(double)result);
|
(double)result);
|
||||||
|
|
||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5146,6 +5226,7 @@ inline bool run_test19()
|
||||||
printf("run_test19() - Error: %s Expression: %s\n",
|
printf("run_test19() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_str.c_str());
|
expression_str.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5186,6 +5267,7 @@ inline bool run_test19()
|
||||||
printf("run_test19() - Error: %s Expression: %s\n",
|
printf("run_test19() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expression_str.c_str());
|
expression_str.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5203,6 +5285,7 @@ inline bool run_test19()
|
||||||
x,
|
x,
|
||||||
sum,
|
sum,
|
||||||
result);
|
result);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5215,7 +5298,6 @@ inline bool run_test19()
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct my_usr : public exprtk::parser<T>::unknown_symbol_resolver
|
struct my_usr : public exprtk::parser<T>::unknown_symbol_resolver
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef typename exprtk::parser<T>::unknown_symbol_resolver usr_t;
|
typedef typename exprtk::parser<T>::unknown_symbol_resolver usr_t;
|
||||||
|
|
||||||
bool process(const std::string& unknown_symbol,
|
bool process(const std::string& unknown_symbol,
|
||||||
|
@ -5228,6 +5310,7 @@ struct my_usr : public exprtk::parser<T>::unknown_symbol_resolver
|
||||||
st = usr_t::e_variable_type;
|
st = usr_t::e_variable_type;
|
||||||
default_value = next_value();
|
default_value = next_value();
|
||||||
error_message = "";
|
error_message = "";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (unknown_symbol[0] == 'c')
|
else if (unknown_symbol[0] == 'c')
|
||||||
|
@ -5235,6 +5318,7 @@ struct my_usr : public exprtk::parser<T>::unknown_symbol_resolver
|
||||||
st = usr_t::e_constant_type;
|
st = usr_t::e_constant_type;
|
||||||
default_value = next_value();
|
default_value = next_value();
|
||||||
error_message = "";
|
error_message = "";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5247,6 +5331,7 @@ struct my_usr : public exprtk::parser<T>::unknown_symbol_resolver
|
||||||
T next_value(const bool reset = false)
|
T next_value(const bool reset = false)
|
||||||
{
|
{
|
||||||
static T value = 0;
|
static T value = 0;
|
||||||
|
|
||||||
if (reset)
|
if (reset)
|
||||||
return (value = 0);
|
return (value = 0);
|
||||||
else
|
else
|
||||||
|
@ -5282,6 +5367,7 @@ inline bool run_test20()
|
||||||
printf("run_test20() - Error: %s Expression: %s\n",
|
printf("run_test20() - Error: %s Expression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str.c_str());
|
expr_str.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5292,6 +5378,7 @@ inline bool run_test20()
|
||||||
{
|
{
|
||||||
printf("run_test20() - Error in evaluation! (1) Expression: %s\n",
|
printf("run_test20() - Error in evaluation! (1) Expression: %s\n",
|
||||||
expr_str.c_str());
|
expr_str.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
216
readme.txt
216
readme.txt
|
@ -67,10 +67,10 @@ expressions that can be parsed and evaluated using the ExprTk library.
|
||||||
(14) (sin(x / pi) cos(2y) + 1) == (sin(x / pi) * cos(2 * y) + 1)
|
(14) (sin(x / pi) cos(2y) + 1) == (sin(x / pi) * cos(2 * y) + 1)
|
||||||
(15) 75x^17 + 25.1x^5 - 35x^4 - 15.2x^3 + 40x^2 - 15.3x + 1
|
(15) 75x^17 + 25.1x^5 - 35x^4 - 15.2x^3 + 40x^2 - 15.3x + 1
|
||||||
(16) (avg(x,y) <= x + y ? x - y : x * y) + 2.345 * pi / x
|
(16) (avg(x,y) <= x + y ? x - y : x * y) + 2.345 * pi / x
|
||||||
(17) fib_i := fib_i + (x := y + 0 * (fib_i := x + (y := fib_i)))
|
(17) while (x <= 100) { x -= 1; }
|
||||||
(18) while (x <= 100) { x -= 1; }
|
(18) x <= 'abc123' and (y in 'AString') or ('1x2y3z' != z)
|
||||||
(19) x <= 'abc123' and (y in 'AString') or ('1x2y3z' != z)
|
(19) (x like '*123*') or ('a123b' ilike y)
|
||||||
(20) (x like '*123*') or ('a123b' ilike y)
|
(20) sgn(+1.2^3.4z / -5.6y) <= {-7.8^9 / -10.11x }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,8 +88,8 @@ The most recent version of the C++ Mathematical Expression Toolkit
|
||||||
Library including all updates and tests can be found at the following
|
Library including all updates and tests can be found at the following
|
||||||
locations:
|
locations:
|
||||||
|
|
||||||
(1) Download: http://www.partow.net/programming/exprtk/index.html
|
(a) Download: http://www.partow.net/programming/exprtk/index.html
|
||||||
(2) Repository: https://exprtk.googlecode.com/svn/
|
(b) Repository: https://exprtk.googlecode.com/svn/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ of C++ compilers:
|
||||||
| for | The structure will repeatedly evaluate the internal |
|
| for | The structure will repeatedly evaluate the internal |
|
||||||
| | statement(s) while the condition is true. On each loop |
|
| | statement(s) while the condition is true. On each loop |
|
||||||
| | iteration, an 'incrementing' expression is evaluated. |
|
| | iteration, an 'incrementing' expression is evaluated. |
|
||||||
| | The conditional is mandatory whereas the initializer |
|
| | The conditional is mandatory whereas the initialiser |
|
||||||
| | and incrementing expressions are optional. |
|
| | and incrementing expressions are optional. |
|
||||||
| | eg: |
|
| | eg: |
|
||||||
| | for (var x := 0; (x < n) and (x != y); x += 1) |
|
| | for (var x := 0; (x < n) and (x != y); x += 1) |
|
||||||
|
@ -868,7 +868,7 @@ vectors. The definitions must be unique as shadowing is not allowed
|
||||||
and object life-times are based on scope. Definitions use the
|
and object life-times are based on scope. Definitions use the
|
||||||
following general form:
|
following general form:
|
||||||
|
|
||||||
var <name> := <initializer>;
|
var <name> := <initialiser>;
|
||||||
|
|
||||||
(1) Variable Definition
|
(1) Variable Definition
|
||||||
Variables are of numeric type denoting a single value. They can be
|
Variables are of numeric type denoting a single value. They can be
|
||||||
|
@ -905,7 +905,7 @@ zero. The following are examples of vector definitions:
|
||||||
(e) Initialise the first three (all) values
|
(e) Initialise the first three (all) values
|
||||||
var x[3] := { 1, 2, 3 };
|
var x[3] := { 1, 2, 3 };
|
||||||
|
|
||||||
(f) Error as there are too many initializers
|
(f) Error as there are too many initialisers
|
||||||
var x[3] := { 1, 2, 3, 4 };
|
var x[3] := { 1, 2, 3, 4 };
|
||||||
|
|
||||||
(g) Error as a vector of size zero is not allowed.
|
(g) Error as a vector of size zero is not allowed.
|
||||||
|
@ -914,7 +914,7 @@ zero. The following are examples of vector definitions:
|
||||||
|
|
||||||
(3) Return Value
|
(3) Return Value
|
||||||
Variable and vector definitions have a return value. In the case of
|
Variable and vector definitions have a return value. In the case of
|
||||||
variable definitions, the value to which the variable is initialized
|
variable definitions, the value to which the variable is initialised
|
||||||
will be returned. Where as for vectors, the value of the first element
|
will be returned. Where as for vectors, the value of the first element
|
||||||
(eg: v[0]) will be returned.
|
(eg: v[0]) will be returned.
|
||||||
|
|
||||||
|
@ -1008,7 +1008,9 @@ not a vector but rather a single value.
|
||||||
var x[3] := { 1, 2, 3 };
|
var x[3] := { 1, 2, 3 };
|
||||||
|
|
||||||
sum(1 + 2x) == 15
|
sum(1 + 2x) == 15
|
||||||
7 == avg(3x + 1)
|
avg(3x + 1) == 7
|
||||||
|
min(1 / x) == (1 / 3)
|
||||||
|
max(x / 2) == (3 / 2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1027,6 +1029,7 @@ There are two types of function interface:
|
||||||
|
|
||||||
(1) ifunction
|
(1) ifunction
|
||||||
(2) ivararg_function
|
(2) ivararg_function
|
||||||
|
(3) function_compositor
|
||||||
|
|
||||||
|
|
||||||
(1) ifunction
|
(1) ifunction
|
||||||
|
@ -1061,24 +1064,62 @@ example defines a vararg function called 'boo':
|
||||||
inline T operator()(const std::vector<T>& arglist)
|
inline T operator()(const std::vector<T>& arglist)
|
||||||
{
|
{
|
||||||
T result = T(0);
|
T result = T(0);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < arglist.size(); ++i)
|
for (std::size_t i = 0; i < arglist.size(); ++i)
|
||||||
{
|
{
|
||||||
result += arglist[i] / arglist[i > 0 ? (i - 1) : 0];
|
result += arglist[i] / arglist[i > 0 ? (i - 1) : 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
(3) Using Functions In Expressions
|
(3) function_compositor
|
||||||
For the above denoted custom functions to be used in an expression, an
|
The function compositor interface allows a user to define a function
|
||||||
instance of each function needs to be registered with a symbol_table
|
using ExprTk syntax. The functions are limited to returning a single
|
||||||
that has been associated with the expression instance. The following
|
scalar value and consuming up to six parameters as input.
|
||||||
demonstrates how all the pieces are put together:
|
|
||||||
|
All composited functions are registered with a symbol table, allowing
|
||||||
|
them to call other functions that have been registered with the symbol
|
||||||
|
table instance, furthermore the functions can be recursive in nature.
|
||||||
|
The following example defines, using two different methods, composited
|
||||||
|
functions then implicitly registers the functions with the denoted
|
||||||
|
symbol table.
|
||||||
|
|
||||||
|
typedef exprtk::symbol_table<T> symbol_table_t;
|
||||||
|
typedef exprtk::function_compositor<T> compositor_t;
|
||||||
|
typedef typename compositor_t::function function_t;
|
||||||
|
|
||||||
|
symbol_table_t symbol_table;
|
||||||
|
|
||||||
|
compositor_t compositor(symbol_table);
|
||||||
|
|
||||||
|
// define function koo0(v1,v2) { ... }
|
||||||
|
compositor
|
||||||
|
.add("koo0",
|
||||||
|
" 1 + cos(v1 * v2) / 3;",
|
||||||
|
"v1","v2");
|
||||||
|
|
||||||
|
// define function koo1(x,y,z) { ... }
|
||||||
|
compositor
|
||||||
|
.add(function_t()
|
||||||
|
.name("koo1")
|
||||||
|
.var("x").var("y").var("z")
|
||||||
|
.expression("1 + cos(x * y) / z;"));
|
||||||
|
|
||||||
|
|
||||||
|
(4) Using Functions In Expressions
|
||||||
|
For the above denoted custom and composited functions to be used in an
|
||||||
|
expression, an instance of each function needs to be registered with a
|
||||||
|
symbol_table that has been associated with the expression instance.
|
||||||
|
The following demonstrates how all the pieces are put together:
|
||||||
|
|
||||||
typedef exprtk::symbol_table<double> symbol_table_t;
|
typedef exprtk::symbol_table<double> symbol_table_t;
|
||||||
typedef exprtk::expression<double> expression_t;
|
typedef exprtk::expression<double> expression_t;
|
||||||
typedef exprtk::parser<double> parser_t;
|
typedef exprtk::parser<double> parser_t;
|
||||||
|
typedef exprtk::function_compositor<T> compositor_t;
|
||||||
|
typedef typename compositor_t::function function_t;
|
||||||
|
|
||||||
foo<double> f;
|
foo<double> f;
|
||||||
boo<double> b;
|
boo<double> b;
|
||||||
|
@ -1087,11 +1128,18 @@ demonstrates how all the pieces are put together:
|
||||||
symbol_table.add_function("foo",f);
|
symbol_table.add_function("foo",f);
|
||||||
symbol_table.add_vararg_function("boo",b);
|
symbol_table.add_vararg_function("boo",b);
|
||||||
|
|
||||||
|
compositor
|
||||||
|
.add(function_t()
|
||||||
|
.name("koo")
|
||||||
|
.var("v1")
|
||||||
|
.var("v2")
|
||||||
|
.expression("1 + cos(v1 * v2) / 3;"));
|
||||||
|
|
||||||
expression_t expression;
|
expression_t expression;
|
||||||
expression.register_symbol_table(symbol_table);
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
std::string expression_str =
|
std::string expression_str =
|
||||||
"foo(1,2,3) + boo(1) / boo(1/2,2/3,3/4,4/5,5/6)";
|
"foo(1,2,3) + boo(1) / boo(1/2,2/3,3/4,4/5) + koo(3,4)";
|
||||||
|
|
||||||
parser_t parser;
|
parser_t parser;
|
||||||
parser.compile(expression_str,expression);
|
parser.compile(expression_str,expression);
|
||||||
|
@ -1099,7 +1147,7 @@ demonstrates how all the pieces are put together:
|
||||||
expression.value();
|
expression.value();
|
||||||
|
|
||||||
|
|
||||||
(4) Function Side-Effects
|
(5) Function Side-Effects
|
||||||
All function calls are assumed to have side-effects by default. This
|
All function calls are assumed to have side-effects by default. This
|
||||||
assumption implicitly disables constant folding optimisations when all
|
assumption implicitly disables constant folding optimisations when all
|
||||||
parameters being passed to the function are deduced as being constants
|
parameters being passed to the function are deduced as being constants
|
||||||
|
@ -1121,7 +1169,7 @@ to the constructor to denote the lack of side-effects.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
(5) Zero Parameter Functions
|
(6) Zero Parameter Functions
|
||||||
When either an ifunction or ivararg_function derived type is defined
|
When either an ifunction or ivararg_function derived type is defined
|
||||||
with zero number of parameters, there are two calling conventions
|
with zero number of parameters, there are two calling conventions
|
||||||
within expressions that are allowed. For a function named 'foo' with
|
within expressions that are allowed. For a function named 'foo' with
|
||||||
|
@ -1132,7 +1180,116 @@ zero input parameters the calling styles are as follows:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[15 - EXPRTK NOTES]
|
[15 - COMPILATION ERRORS]
|
||||||
|
When attempting to compile a malformed or otherwise erroneous ExprTk
|
||||||
|
expression, the compilation process will result in an error, as is
|
||||||
|
indicated by the 'compile' method returning a false value. A
|
||||||
|
diagnostic indicating the first error encountered and its cause can be
|
||||||
|
obtained by invoking the 'error' method, as is demonstrated in the
|
||||||
|
following example:
|
||||||
|
|
||||||
|
if (!parser.compile(expression_string,expression))
|
||||||
|
{
|
||||||
|
printf("Error: %s\n", parser.error().c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Any error(s) resulting from a failed compilation will be stored in the
|
||||||
|
parser instance until the next time a compilation is performed. Before
|
||||||
|
then errors can be enumerated in the order they occurred by invoking
|
||||||
|
the 'get_error' method which itself will return a 'parser_error' type.
|
||||||
|
A parser_error object will contain an error diagnostic, an error mode
|
||||||
|
(or class), and the character position of the error in the expression
|
||||||
|
string. The following example demonstrates the enumeration of error(s)
|
||||||
|
in the event of a failed compilation.
|
||||||
|
|
||||||
|
if (!parser.compile(expression_string,expression))
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < parser.error_count(); ++i)
|
||||||
|
{
|
||||||
|
typedef exprtk::parser_error::type error_t;
|
||||||
|
|
||||||
|
error_t error = parser.get_error(i);
|
||||||
|
|
||||||
|
printf("Error[%02d] Position: %02d Type: [%14s] Msg: %s\n",
|
||||||
|
i,
|
||||||
|
error.token.position,
|
||||||
|
exprtk::parser_error::to_str(error.mode).c_str(),
|
||||||
|
error.diagnostic.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
demonstrated by the following example:
|
||||||
|
|
||||||
|
if (!parser.compile(program_str,expression))
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < parser.error_count(); ++i)
|
||||||
|
{
|
||||||
|
typedef exprtk::parser_error::type error_t;
|
||||||
|
|
||||||
|
error_t error = parser.get_error(i);
|
||||||
|
|
||||||
|
exprtk::parser_error::update_error(error,program_str);
|
||||||
|
|
||||||
|
printf("Error[%02d] at line: %d column: %d\n",
|
||||||
|
i,
|
||||||
|
error.line_no,
|
||||||
|
error.column_no);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Note: The are five distinct error modes in ExprTk which denote the
|
||||||
|
class of an error. These classes are as follows:
|
||||||
|
|
||||||
|
(a) Syntax
|
||||||
|
(b) Token
|
||||||
|
(c) Numeric
|
||||||
|
(d) Symbol Table
|
||||||
|
(e) Lexer
|
||||||
|
|
||||||
|
|
||||||
|
(a) Syntax Errors
|
||||||
|
These are errors related to invalid syntax found within the denoted
|
||||||
|
expression. Examples are invalid sequences of operators and variables,
|
||||||
|
incorrect number of parameters to functions, invalid conditional or
|
||||||
|
loop structures and invalid use of keywords.
|
||||||
|
|
||||||
|
eg: 'for := sin(x,y,z) + 2 * equal > until[2 - x,3]'
|
||||||
|
|
||||||
|
|
||||||
|
(b) Token Errors
|
||||||
|
Errors in this class relate to token level errors detected by one or
|
||||||
|
more of the following checkers:
|
||||||
|
|
||||||
|
(1) Bracket Checker
|
||||||
|
(2) Numeric Checker
|
||||||
|
(3) Sequence Checker
|
||||||
|
|
||||||
|
(c) Numeric Errors
|
||||||
|
This class of error is related to conversion of numeric values from
|
||||||
|
their string form to the underlying numerical type (float, double
|
||||||
|
etc).
|
||||||
|
|
||||||
|
(d) Symbol Table Errors
|
||||||
|
This is the class of errors related to failures when interacting with
|
||||||
|
the registered symbol_table instance. Errors such as not being able to
|
||||||
|
find, within the symbol_table, symbols representing variables or
|
||||||
|
functions, to being unable to create new variables in the symbol_table
|
||||||
|
via the 'unknown symbol resolver' mechanism.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[16 - 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:
|
||||||
|
|
||||||
|
@ -1268,10 +1425,10 @@ into account when using Exprtk:
|
||||||
sum, swap, switch, tanh, tan, true, trunc, until, var,
|
sum, swap, switch, tanh, tan, true, trunc, until, var,
|
||||||
while, xnor, xor, xor
|
while, xnor, xor, xor
|
||||||
|
|
||||||
(28) Every ExprTk statement is a "value returning" expression. Unlike
|
(28) Every valid ExprTk statement is a "value returning" expression.
|
||||||
some languages that limit the types of expressions that can be
|
Unlike some languages that limit the types of expressions that
|
||||||
performed in certain situations, in ExprTk any valid expression
|
can be performed in certain situations, in ExprTk any valid
|
||||||
can be used in any "value consuming" context. Eg:
|
expression can be used in any "value consuming" context. Eg:
|
||||||
|
|
||||||
var y := 3;
|
var y := 3;
|
||||||
for (var x := switch
|
for (var x := switch
|
||||||
|
@ -1292,7 +1449,7 @@ into account when using Exprtk:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[16 - SIMPLE EXPRTK EXAMPLE]
|
[17 - SIMPLE EXPRTK EXAMPLE]
|
||||||
--- snip ---
|
--- snip ---
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -1380,7 +1537,7 @@ int main()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[17 - BUILD OPTIONS]
|
[18 - 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
|
||||||
|
@ -1418,7 +1575,10 @@ in a compilation failure.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[18 - FILES]
|
[19 - FILES]
|
||||||
|
The source distribution of ExprTk is comprised of the following set of
|
||||||
|
files:
|
||||||
|
|
||||||
(00) Makefile
|
(00) Makefile
|
||||||
(01) readme.txt
|
(01) readme.txt
|
||||||
(02) exprtk.hpp
|
(02) exprtk.hpp
|
||||||
|
@ -1443,7 +1603,7 @@ in a compilation failure.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[19 - LANGUAGE STRUCTURE]
|
[20 - LANGUAGE STRUCTURE]
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
|00 - If Statement |
|
|00 - If Statement |
|
||||||
| |
|
| |
|
||||||
|
|
Loading…
Reference in New Issue