C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
baa1feb6d2
commit
02d2402ca5
28
Makefile
28
Makefile
|
@ -103,20 +103,20 @@ strip_bin:
|
||||||
strip -s exprtk_simple_example_12
|
strip -s exprtk_simple_example_12
|
||||||
|
|
||||||
valgrind_check:
|
valgrind_check:
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_test
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_test_valgrind.log -v ./exprtk_test
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_benchmark
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_benchmark_valgrind.log -v ./exprtk_benchmark
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_01
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_01_valgrind.log -v ./exprtk_simple_example_01
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_02
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_02_valgrind.log -v ./exprtk_simple_example_02
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_03
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_03_valgrind.log -v ./exprtk_simple_example_03
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_04
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_04_valgrind.log -v ./exprtk_simple_example_04
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_05
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_05_valgrind.log -v ./exprtk_simple_example_05
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_06
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_06_valgrind.log -v ./exprtk_simple_example_06
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_07
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_07_valgrind.log -v ./exprtk_simple_example_07
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_08
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_08_valgrind.log -v ./exprtk_simple_example_08
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_09
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_09_valgrind.log -v ./exprtk_simple_example_09
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_10
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_10_valgrind.log -v ./exprtk_simple_example_10
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_11
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_11_valgrind.log -v ./exprtk_simple_example_11
|
||||||
valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./exprtk_simple_example_12
|
valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=exprtk_simple_example_12_valgrind.log -v ./exprtk_simple_example_12
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f core.* *~ *.o *.bak *stackdump gmon.out *.gcda *.gcno *.gcnor *.gch
|
rm -f core.* *~ *.o *.bak *stackdump gmon.out *.gcda *.gcno *.gcnor *.gch
|
||||||
|
|
3554
exprtk.hpp
3554
exprtk.hpp
File diff suppressed because it is too large
Load Diff
|
@ -28,12 +28,13 @@ void square_wave2()
|
||||||
typedef exprtk::expression<T> expression_t;
|
typedef exprtk::expression<T> expression_t;
|
||||||
typedef exprtk::parser<T> parser_t;
|
typedef exprtk::parser<T> parser_t;
|
||||||
|
|
||||||
std::string expr_string = " r := 0; "
|
std::string wave_program =
|
||||||
|
" r := 0; "
|
||||||
" for(i := 0; i < 1000; i += 1) "
|
" for(i := 0; i < 1000; i += 1) "
|
||||||
" { "
|
" { "
|
||||||
" r += (1/(2i+1))*sin((4i+2)*pi*f*t); "
|
" r += (1 / (2i + 1)) * sin((4i + 2) * pi * f * t); "
|
||||||
" }; "
|
" }; "
|
||||||
" r *= a*(4 / pi); ";
|
" r *= a * (4 / pi); ";
|
||||||
|
|
||||||
static const T pi = T(3.14159265358979323846);
|
static const T pi = T(3.14159265358979323846);
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ void square_wave2()
|
||||||
parser_t parser;
|
parser_t parser;
|
||||||
parser.enable_unknown_symbol_resolver();
|
parser.enable_unknown_symbol_resolver();
|
||||||
|
|
||||||
parser.compile(expr_string,expression);
|
parser.compile(wave_program,expression);
|
||||||
|
|
||||||
const T delta = (T(4) * pi) / T(1000);
|
const T delta = (T(4) * pi) / T(1000);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ void bubble_sort()
|
||||||
typedef exprtk::expression<T> expression_t;
|
typedef exprtk::expression<T> expression_t;
|
||||||
typedef exprtk::parser<T> parser_t;
|
typedef exprtk::parser<T> parser_t;
|
||||||
|
|
||||||
std::string expr_string =
|
std::string bubblesort_program =
|
||||||
" upper_bound := v[]; "
|
" upper_bound := v[]; "
|
||||||
" repeat "
|
" repeat "
|
||||||
" swapped := false; "
|
" swapped := false; "
|
||||||
|
@ -38,9 +38,7 @@ void bubble_sort()
|
||||||
" { "
|
" { "
|
||||||
" if (v[i] > v[j]) "
|
" if (v[i] > v[j]) "
|
||||||
" { "
|
" { "
|
||||||
" temp := v[i]; "
|
" v[i] <=> v[j]; "
|
||||||
" v[i] := v[j]; "
|
|
||||||
" v[j] := temp; "
|
|
||||||
" swapped := true; "
|
" swapped := true; "
|
||||||
" }; "
|
" }; "
|
||||||
" }; "
|
" }; "
|
||||||
|
@ -59,7 +57,7 @@ void bubble_sort()
|
||||||
parser_t parser;
|
parser_t parser;
|
||||||
parser.enable_unknown_symbol_resolver();
|
parser.enable_unknown_symbol_resolver();
|
||||||
|
|
||||||
parser.compile(expr_string,expression);
|
parser.compile(bubblesort_program,expression);
|
||||||
|
|
||||||
expression.value();
|
expression.value();
|
||||||
}
|
}
|
||||||
|
|
165
exprtk_test.cpp
165
exprtk_test.cpp
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "exprtk.hpp"
|
#include "exprtk.hpp"
|
||||||
|
|
||||||
|
|
||||||
typedef double numeric_type;
|
typedef double numeric_type;
|
||||||
typedef std::pair<std::string,numeric_type> test_t;
|
typedef std::pair<std::string,numeric_type> test_t;
|
||||||
|
|
||||||
|
@ -1128,7 +1129,7 @@ inline bool test_expression(const std::string& expression_string, const T& expec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!exprtk::expression_helper<T>::is_head_constant(expression))
|
if (!exprtk::expression_helper<T>::is_constant(expression))
|
||||||
{
|
{
|
||||||
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());
|
||||||
|
@ -2736,6 +2737,8 @@ inline bool run_test09()
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool run_test10()
|
inline bool run_test10()
|
||||||
{
|
{
|
||||||
|
typedef exprtk::expression<T> expression_t;
|
||||||
|
|
||||||
T x = T(1.1);
|
T x = T(1.1);
|
||||||
T y = T(2.2);
|
T y = T(2.2);
|
||||||
T xx = T(3.3);
|
T xx = T(3.3);
|
||||||
|
@ -2748,8 +2751,6 @@ inline bool run_test10()
|
||||||
|
|
||||||
exprtk::symbol_table<T> symbol_table;
|
exprtk::symbol_table<T> symbol_table;
|
||||||
|
|
||||||
typedef exprtk::expression<T> expression_t;
|
|
||||||
|
|
||||||
struct test
|
struct test
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
@ -3241,6 +3242,96 @@ inline bool run_test10()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
exprtk::symbol_table<T> symbol_table0;
|
||||||
|
exprtk::symbol_table<T> symbol_table1;
|
||||||
|
|
||||||
|
if (symbol_table0 == symbol_table1)
|
||||||
|
{
|
||||||
|
printf("run_test10() - Error symbol_table0 and symbol_table1 are equal\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table0 = symbol_table1;
|
||||||
|
symbol_table1 = symbol_table0;
|
||||||
|
|
||||||
|
if (!(symbol_table0 == symbol_table1))
|
||||||
|
{
|
||||||
|
printf("run_test10() - Error symbol_table0 and symbol_table1 are not equal\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::string expression_list[] =
|
||||||
|
{
|
||||||
|
"var x := 1; var y := 2; swap(x,y); (x == 2) and (y == 1)",
|
||||||
|
"var x := 1; var y := 2; x <=> y ; (x == 2) and (y == 1)",
|
||||||
|
"var v[2] := {1,2}; swap(v[0],v[1]); (v[0] == 2) and (v[1] == 1)",
|
||||||
|
"var v[2] := {1,2}; v[0] <=> v[1] ; (v[0] == 2) and (v[1] == 1)",
|
||||||
|
"var x := 1; var y := 2; ~(swap(x,y),(x == 2) and (y == 1))",
|
||||||
|
"var x := 1; var y := 2; ~(x <=> y , (x == 2) and (y == 1))",
|
||||||
|
"var v[2] := {1,2}; ~(swap(v[0],v[1]), (v[0] == 2) and (v[1] == 1))",
|
||||||
|
"var v[2] := {1,2}; ~(v[0] <=> v[1] , (v[0] == 2) and (v[1] == 1))",
|
||||||
|
"var v[2] := {1,2}; swap(v[zero],v[one]); (v[zero] == 2) and (v[one] == 1)",
|
||||||
|
"var v[2] := {1,2}; v[zero] <=> v[one] ; (v[zero] == 2) and (v[one] == 1)",
|
||||||
|
"var v[2] := {1,2}; ~(swap(v[zero],v[one]), (v[zero] == 2) and (v[one] == 1))",
|
||||||
|
"var v[2] := {1,2}; ~(v[zero] <=> v[one] , (v[zero] == 2) and (v[one] == 1))",
|
||||||
|
"var v[2] := {1,2}; swap(v[2 * zero],v[(2 * one) / (1 + 1)]); (v[2 * zero] == 2) and (v[(2 * one) / (1 + 1)] == 1)",
|
||||||
|
"var v[2] := {1,2}; v[2 * zero] <=> v[(2*one)/(1+1)] ; (v[2 * zero] == 2) and (v[(2 * one) / (1 + 1)] == 1)",
|
||||||
|
"var v[2] := {1,2}; ~(swap(v[2 * zero],v[(2 * one) / (1 + 1)]), (v[2 * zero] == 2) and (v[(2 * one) / (1 + 1)] == 1))",
|
||||||
|
"var v[2] := {1,2}; ~(v[2 * zero] <=> v[(2 * one) / (1 + 1)] , (v[2 * zero] == 2) and (v[(2 * one) / (1 + 1)] == 1))",
|
||||||
|
"var x := 1; var y := 2; var v[2] := {3,4}; swap(x,v[0]); swap(v[1],y); (x == 3) and (y == 4)",
|
||||||
|
"var x := 1; var y := 2; var v[2] := {3,4}; x <=> v[0]; v[1] <=> y; (x == 3) and (y == 4)",
|
||||||
|
"var x := 1; var y := 2; var v[2] := {3,4}; swap(x,v[zero]); swap(v[one],y); (x == 3) and (y == 4)",
|
||||||
|
"var x := 1; var y := 2; var v[2] := {3,4}; x <=> v[zero]; v[one] <=> y; (x == 3) and (y == 4)",
|
||||||
|
"var x := 1; var y := 2; var v[2] := {3,4}; swap(x,v[2 * zero]); swap(v[(2 * one) / (1 + 1)],y); (x == 3) and (y == 4)",
|
||||||
|
"var x := 1; var y := 2; var v[2] := {3,4}; x <=> v[zero / 3]; v[(2 * one)/(1 + 1)] <=> y; (x == 3) and (y == 4)"
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
|
||||||
|
|
||||||
|
exprtk::symbol_table<T> symbol_table;
|
||||||
|
|
||||||
|
T zero = T(0);
|
||||||
|
T one = T(1);
|
||||||
|
|
||||||
|
symbol_table.add_variable("zero",zero);
|
||||||
|
symbol_table.add_variable("one" , one);
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < expression_list_size; ++i)
|
||||||
|
{
|
||||||
|
expression_t expression;
|
||||||
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
|
{
|
||||||
|
exprtk::parser<T> parser;
|
||||||
|
if (!parser.compile(expression_list[i],expression))
|
||||||
|
{
|
||||||
|
printf("run_test10() - swaps Error: %s Expression: %s\n",
|
||||||
|
parser.error().c_str(),
|
||||||
|
expression_list[i].c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T result = expression.value();
|
||||||
|
|
||||||
|
if (T(1) != result)
|
||||||
|
{
|
||||||
|
printf("run_test10() - swaps evaluation error Expression: %s\n",
|
||||||
|
expression_list[i].c_str());
|
||||||
|
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4035,6 +4126,8 @@ inline bool run_test18()
|
||||||
|
|
||||||
static const std::string expr_str_list[] =
|
static const std::string expr_str_list[] =
|
||||||
{
|
{
|
||||||
|
"equal(va_func,(0))",
|
||||||
|
"equal(va_func(),(0))",
|
||||||
"equal(va_func(1,2,3,4,5,6,7,8,9),(1+2+3+4+5+6+7+8+9))",
|
"equal(va_func(1,2,3,4,5,6,7,8,9),(1+2+3+4+5+6+7+8+9))",
|
||||||
"equal(va_func(1,x,3,y,5,z,7,w,9),(1+x+3+y+5+z+7+w+9))",
|
"equal(va_func(1,x,3,y,5,z,7,w,9),(1+x+3+y+5+z+7+w+9))",
|
||||||
"equal(va_func(x,2,y,4,z,6,w,8,u),(x+2+y+4+z+6+w+8+u))",
|
"equal(va_func(x,2,y,4,z,6,w,8,u),(x+2+y+4+z+6+w+8+u))",
|
||||||
|
@ -4201,7 +4294,7 @@ inline bool run_test19()
|
||||||
compositor
|
compositor
|
||||||
.add("f2","7 * (f1(x) + f1(y))","x","y");
|
.add("f2","7 * (f1(x) + f1(y))","x","y");
|
||||||
|
|
||||||
// f3(x,y,z) = 9 * (2(x,y) + f2(y,z) + f2(x,z))
|
// f3(x,y,z) = 9 * (f2(x,y) + f2(y,z) + f2(x,z))
|
||||||
compositor
|
compositor
|
||||||
.add("f3","9 * (f2(x,y) + f2(y,z) + f2(x,z))","x","y","z");
|
.add("f3","9 * (f2(x,y) + f2(y,z) + f2(x,z))","x","y","z");
|
||||||
|
|
||||||
|
@ -4711,6 +4804,70 @@ inline bool run_test19()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
symbol_table_t symbol_table;
|
||||||
|
|
||||||
|
symbol_table.add_constants();
|
||||||
|
|
||||||
|
compositor_t compositor(symbol_table);
|
||||||
|
|
||||||
|
compositor
|
||||||
|
.add("mandelbrot",
|
||||||
|
" var width := 118; "
|
||||||
|
" var height := 41; "
|
||||||
|
" var imag_max := +1; "
|
||||||
|
" var imag_min := -1; "
|
||||||
|
" var real_max := +1; "
|
||||||
|
" var real_min := -2.5; "
|
||||||
|
" var x_step := (real_max - real_min) / width; "
|
||||||
|
" var y_step := (imag_max - imag_min) / height; "
|
||||||
|
" for (y := 0; y < height; y += 1) "
|
||||||
|
" { "
|
||||||
|
" var imag := imag_min + (y_step * y); "
|
||||||
|
" for (x := 0; x < width; x += 1) "
|
||||||
|
" { "
|
||||||
|
" var real := real_min + x_step * x; "
|
||||||
|
" var z_real := real; "
|
||||||
|
" var z_imag := imag; "
|
||||||
|
" var plot_value; "
|
||||||
|
" for (n := 0; n < 30; n += 1) "
|
||||||
|
" { "
|
||||||
|
" var a := z_real^2; "
|
||||||
|
" var b := z_imag^2; "
|
||||||
|
" plot_value := n; "
|
||||||
|
" if ((a + b) < 4) "
|
||||||
|
" { "
|
||||||
|
" z_imag := 2 * z_real * z_imag + imag; "
|
||||||
|
" z_real := a - b + real; "
|
||||||
|
" } "
|
||||||
|
" else "
|
||||||
|
" break; "
|
||||||
|
" }; "
|
||||||
|
" }; "
|
||||||
|
" } ");
|
||||||
|
|
||||||
|
std::string expression_str = "mandelbrot()";
|
||||||
|
|
||||||
|
expression_t expression;
|
||||||
|
|
||||||
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
|
parser_t parser;
|
||||||
|
|
||||||
|
if (!parser.compile(expression_str,expression))
|
||||||
|
{
|
||||||
|
printf("run_test19() - Error: %s Expression: %s\n",
|
||||||
|
parser.error().c_str(),
|
||||||
|
expression_str.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < 100; ++i)
|
||||||
|
{
|
||||||
|
expression.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
448
readme.txt
448
readme.txt
|
@ -18,11 +18,11 @@ arithmetic operations, functions and processes:
|
||||||
(01) Functions: abs, avg, ceil, clamp, equal, erf, erfc, exp,
|
(01) Functions: abs, avg, ceil, clamp, equal, erf, erfc, exp,
|
||||||
expm1, floor, frac, log, log10, log1p, log2,
|
expm1, floor, frac, log, log10, log1p, log2,
|
||||||
logn, max, min, mul, nequal, root, round,
|
logn, max, min, mul, nequal, root, round,
|
||||||
roundn, sgn, sqrt, sum, trunc
|
roundn, sgn, sqrt, sum, swap, trunc
|
||||||
|
|
||||||
(02) Trigonometry: acos, acosh, asin, asinh, atan, atanh, atan2,
|
(02) Trigonometry: acos, acosh, asin, asinh, atan, atanh, atan2,
|
||||||
cos, cosh, cot, csc, sec, sin, sinc, sinh, tan,
|
cos, cosh, cot, csc, sec, sin, sinc, sinh,
|
||||||
tanh, hypot, rad2deg, deg2grad, deg2rad,
|
tan, tanh, hypot, rad2deg, deg2grad, deg2rad,
|
||||||
grad2deg
|
grad2deg
|
||||||
|
|
||||||
(03) Equalities &
|
(03) Equalities &
|
||||||
|
@ -36,7 +36,7 @@ arithmetic operations, functions and processes:
|
||||||
|
|
||||||
(06) Loop statements: while, for, repeat-until, break, continue
|
(06) Loop statements: while, for, repeat-until, break, continue
|
||||||
|
|
||||||
(07) Assignment: :=, +=, -=, *=, /=
|
(07) Assignment: :=, +=, -=, *=, /=, %=
|
||||||
|
|
||||||
(08) String
|
(08) String
|
||||||
processing: in, like, ilike
|
processing: in, like, ilike
|
||||||
|
@ -108,6 +108,9 @@ include path (e.g: /usr/include/).
|
||||||
|
|
||||||
|
|
||||||
[07 - COMPILER COMPATIBILITY]
|
[07 - COMPILER COMPATIBILITY]
|
||||||
|
ExprTk has been built error and warning free using the following set
|
||||||
|
of C++ compilers:
|
||||||
|
|
||||||
(*) GNU Compiler Collection (3.3+)
|
(*) GNU Compiler Collection (3.3+)
|
||||||
(*) Intel C++ Compiler (8.x+)
|
(*) Intel C++ Compiler (8.x+)
|
||||||
(*) Clang/LLVM (1.1+)
|
(*) Clang/LLVM (1.1+)
|
||||||
|
@ -150,13 +153,17 @@ include path (e.g: /usr/include/).
|
||||||
+----------+---------------------------------------------------------+
|
+----------+---------------------------------------------------------+
|
||||||
| *= | Assign the multiplication of x by the value of the |
|
| *= | Assign the multiplication of x by the value of the |
|
||||||
| | expression on the righthand side to x. Where x is either|
|
| | expression on the righthand side to x. Where x is either|
|
||||||
| | variable or vector type. |
|
| | a variable or vector type. |
|
||||||
| | (eg: x *= abs(y / z)) |
|
| | (eg: x *= abs(y / z)) |
|
||||||
+----------+---------------------------------------------------------+
|
+----------+---------------------------------------------------------+
|
||||||
| /= | Assign the division of x by the value of the expression |
|
| /= | Assign the division of x by the value of the expression |
|
||||||
| | on the right-hand side to x. Where x is either a |
|
| | on the right-hand side to x. Where x is either a |
|
||||||
| | variable or vector type. (eg: x[i+j] /= abs(y * z)) |
|
| | variable or vector type. (eg: x[i+j] /= abs(y * z)) |
|
||||||
+----------+---------------------------------------------------------+
|
+----------+---------------------------------------------------------+
|
||||||
|
| %= | Assign x modulo the value of the expression on the right|
|
||||||
|
| | hand side to x. Where x is either a variable or vector |
|
||||||
|
| | type. (eg: x[2] %= y ^ 2) |
|
||||||
|
+----------+---------------------------------------------------------+
|
||||||
|
|
||||||
(1) Equalities & Inequalities
|
(1) Equalities & Inequalities
|
||||||
+----------+---------------------------------------------------------+
|
+----------+---------------------------------------------------------+
|
||||||
|
@ -292,6 +299,9 @@ include path (e.g: /usr/include/).
|
||||||
| sum | Sum of all the inputs. |
|
| sum | Sum of all the inputs. |
|
||||||
| | (eg: sum(x,y,z,w,u,v,t) == (x + y + z + w + u + v + t)) |
|
| | (eg: sum(x,y,z,w,u,v,t) == (x + y + z + w + u + v + t)) |
|
||||||
+----------+---------------------------------------------------------+
|
+----------+---------------------------------------------------------+
|
||||||
|
| swap | Swap the values of the variables x and y and return the |
|
||||||
|
| <=> | current value of y. (eg: swap(x,y) or x <=> y) |
|
||||||
|
+----------+---------------------------------------------------------+
|
||||||
| trunc | Integer portion of x. (eg: trunc(x)) |
|
| trunc | Integer portion of x. (eg: trunc(x)) |
|
||||||
+----------+---------------------------------------------------------+
|
+----------+---------------------------------------------------------+
|
||||||
|
|
||||||
|
@ -453,7 +463,7 @@ include path (e.g: /usr/include/).
|
||||||
| | The conditional is mandatory whereas the initializer |
|
| | The conditional is mandatory whereas the initializer |
|
||||||
| | and incrementing expressions are optional. |
|
| | and incrementing expressions are optional. |
|
||||||
| | eg: |
|
| | eg: |
|
||||||
| | for (x := 0; x < n && (x != y); x += 1) |
|
| | for (x := 0; (x < n) and (x != y); x += 1) |
|
||||||
| | { |
|
| | { |
|
||||||
| | y := y + x / 2 - z; |
|
| | y := y + x / 2 - z; |
|
||||||
| | w := u + y; |
|
| | w := u + y; |
|
||||||
|
@ -479,7 +489,7 @@ include path (e.g: /usr/include/).
|
||||||
| continue | Continue results in the remaining portion of the nearest|
|
| continue | Continue results in the remaining portion of the nearest|
|
||||||
| | enclosing loop body to be skipped. |
|
| | enclosing loop body to be skipped. |
|
||||||
| | eg: |
|
| | eg: |
|
||||||
| | for (i := 0; i < 10; i+= 1) |
|
| | for (i := 0; i < 10; i += 1) |
|
||||||
| | { |
|
| | { |
|
||||||
| | if (i < 5) |
|
| | if (i < 5) |
|
||||||
| | continue; |
|
| | continue; |
|
||||||
|
@ -511,6 +521,12 @@ include path (e.g: /usr/include/).
|
||||||
| | case (x + 3) = (y * 4) : y := abs(z / 6) + 7y; |
|
| | case (x + 3) = (y * 4) : y := abs(z / 6) + 7y; |
|
||||||
| | } |
|
| | } |
|
||||||
+----------+---------------------------------------------------------+
|
+----------+---------------------------------------------------------+
|
||||||
|
| [] | The vector size operator returns the size of the vector |
|
||||||
|
| | being actioned. |
|
||||||
|
| | eg: |
|
||||||
|
| | 1. v[] |
|
||||||
|
| | 2. max_size := max(v0[],v1[],v2[],v3[]) |
|
||||||
|
+----------+---------------------------------------------------------+
|
||||||
|
|
||||||
Note: In the above tables, the symbols x, y, z, w, u and v where
|
Note: In the above tables, the symbols x, y, z, w, u and v where
|
||||||
appropriate may represent any of one the following:
|
appropriate may represent any of one the following:
|
||||||
|
@ -518,7 +534,7 @@ appropriate may represent any of one the following:
|
||||||
1. Literal numeric/string value
|
1. Literal numeric/string value
|
||||||
2. A variable
|
2. A variable
|
||||||
3. A vector element
|
3. A vector element
|
||||||
3. An expression comprised of [1], [2] or [3] (eg: 2 + x / vec[3])
|
4. An expression comprised of [1], [2] or [3] (eg: 2 + x / vec[3])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -582,11 +598,19 @@ current values assigned to the variables will be used.
|
||||||
|
|
||||||
x = 1.0;
|
x = 1.0;
|
||||||
y = 2.0;
|
y = 2.0;
|
||||||
parser.value(); // 1 * 2 + 3
|
expression.value(); // 1 * 2 + 3
|
||||||
|
|
||||||
x = 3.7;
|
x = 3.7;
|
||||||
parser.value(); // 3.7 * 2 + 3
|
expression.value(); // 3.7 * 2 + 3
|
||||||
|
|
||||||
y = -9.0;
|
y = -9.0;
|
||||||
parser.value(); // 3.7 * -9 + 3
|
expression.value(); // 3.7 * -9 + 3
|
||||||
|
|
||||||
|
// 'x * -9 + 3' for x in range of [0,100] in steps of 0.0001
|
||||||
|
for (x = 0; x < 100; x += 0.0001)
|
||||||
|
{
|
||||||
|
expression.value(); // x * -9 + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
(2) Expression
|
(2) Expression
|
||||||
|
@ -680,8 +704,7 @@ handle:
|
||||||
(h) '-' '=' ---> '-=' (subtraction assignment)
|
(h) '-' '=' ---> '-=' (subtraction assignment)
|
||||||
(i) '*' '=' ---> '*=' (multiplication assignment)
|
(i) '*' '=' ---> '*=' (multiplication assignment)
|
||||||
(j) '/' '=' ---> '/=' (division assignment)
|
(j) '/' '=' ---> '/=' (division assignment)
|
||||||
|
(j) '%' '=' ---> '%=' (modulo assignment)
|
||||||
|
|
||||||
|
|
||||||
An example of the transformation that takes place is as follows:
|
An example of the transformation that takes place is as follows:
|
||||||
|
|
||||||
|
@ -825,108 +848,295 @@ correctly optimize such expressions for a given architecture.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[12 - EXPRTK NOTES]
|
[12 - VARIABLE & VECTOR DEFINITION]
|
||||||
|
ExprTk supports the definition of expression local variables and
|
||||||
|
vectors. The definitions must be unique as shadowing is not allowed
|
||||||
|
and object life-times are based on scope. Definitions use the
|
||||||
|
following general form:
|
||||||
|
|
||||||
|
var <name> := <initializer>;
|
||||||
|
|
||||||
|
(1) Variable Definition
|
||||||
|
Variables are of numeric type denoting a single value. They can be
|
||||||
|
explicitly initialised to a value, otherwise they will be defaulted to
|
||||||
|
zero. The following are examples of variable definitions:
|
||||||
|
|
||||||
|
(a) Initialise x to zero
|
||||||
|
var x;
|
||||||
|
|
||||||
|
(b) Initialise y to three
|
||||||
|
var y := 3;
|
||||||
|
|
||||||
|
(c) Initialise z to the expression
|
||||||
|
var z := if(max(1,x + y) > 2,w,v);
|
||||||
|
|
||||||
|
|
||||||
|
(2) Vector Definition
|
||||||
|
Vectors are arrays of a common numeric type. The elements in a vector
|
||||||
|
can be explicitly initialised, otherwise they will all be defaulted to
|
||||||
|
zero. The following are examples of vector definitions:
|
||||||
|
|
||||||
|
(a) Initialise all values to zero
|
||||||
|
var x[3];
|
||||||
|
|
||||||
|
(b) Initialise all values to zero
|
||||||
|
var x[3] := {};
|
||||||
|
|
||||||
|
(c) Initialise all values to given expression
|
||||||
|
var x[3] := [123 + 3y + sin(w/z)];
|
||||||
|
|
||||||
|
(d) Initialise the first two values, other elements to zero
|
||||||
|
var x[3] := {1 + x[2], sin(y[0] / x[]) + 3};
|
||||||
|
|
||||||
|
(e) Initialise the first three (all) values
|
||||||
|
var x[3] := {1,2,3};
|
||||||
|
|
||||||
|
(f) Error as there are too many initializers
|
||||||
|
var x[3] := {1,2,3,4};
|
||||||
|
|
||||||
|
(g) Error as a vector of size zero is not allowed.
|
||||||
|
var x[0];
|
||||||
|
|
||||||
|
|
||||||
|
(3) Return Value
|
||||||
|
Variable and vector definitions have a return value. In the case of
|
||||||
|
variable definitions, the value to which the variable is initialized
|
||||||
|
will be returned. Where as for vectors, the value of the first element
|
||||||
|
(eg: v[0]) will be returned.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[13 - USER DEFINED FUNCTIONS]
|
||||||
|
ExprTk provides a means whereby custom functions can be defined and
|
||||||
|
utilized within expressions. The concept requires the user to
|
||||||
|
provide a reference to the function coupled with an associated name
|
||||||
|
that will be invoked within expressions. Function can take in numerous
|
||||||
|
inputs but will always return one value.
|
||||||
|
|
||||||
|
During expression compilation when required the reference to the
|
||||||
|
function will be obtained from the associated symbol_table and be
|
||||||
|
embedded into the expression.
|
||||||
|
|
||||||
|
There are two types of function interface:
|
||||||
|
|
||||||
|
(1) ifunction
|
||||||
|
(2) ivararg_function
|
||||||
|
|
||||||
|
|
||||||
|
(1) ifunction
|
||||||
|
This interface supports zero to 20 input parameters. The usage
|
||||||
|
requires a custom function be derived from ifunction and to override
|
||||||
|
one of the 21 function operators. As part of the constructor the
|
||||||
|
custom function will define how many parameters it expects to handle.
|
||||||
|
The following example defines a 3 parameter function called 'foo':
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct foo : public exprtk::ifunction<T>
|
||||||
|
{
|
||||||
|
foo() : exprtk::ifunction<T>(3)
|
||||||
|
{}
|
||||||
|
|
||||||
|
T operator()(const T& v1, const T& v2, const T& v3)
|
||||||
|
{
|
||||||
|
return T(1) + (v1 * v2) / T(v3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
(2) ivararg_function
|
||||||
|
This interface supports a variable number of arguments as input into
|
||||||
|
the function. The function operator interface uses a std::vector
|
||||||
|
specialized upon type T to facilitate parameter passing. The following
|
||||||
|
example defines a vararg function called 'boo':
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct boo : public exprtk::ivararg_function<T>
|
||||||
|
{
|
||||||
|
inline T operator()(const std::vector<T>& arglist)
|
||||||
|
{
|
||||||
|
T result = T(0);
|
||||||
|
for (std::size_t i = 0; i < arglist.size(); ++i)
|
||||||
|
{
|
||||||
|
result += arglist[i] / arglist[i > 0 ? (i - 1) : 0];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
(3) Using Functions In Expressions
|
||||||
|
For the above denoted custom 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
|
||||||
|
demonstrations how all the pieces are put together:
|
||||||
|
|
||||||
|
typedef exprtk::symbol_table<double> symbol_table_t;
|
||||||
|
typedef exprtk::expression<double> expression_t;
|
||||||
|
typedef exprtk::parser<double> parser_t;
|
||||||
|
|
||||||
|
foo<double> f;
|
||||||
|
boo<double> b;
|
||||||
|
|
||||||
|
symbol_table_t symbol_table;
|
||||||
|
symbol_table.add_function("foo",f);
|
||||||
|
symbol_table.add_function("boo",b);
|
||||||
|
|
||||||
|
expression_t expression;
|
||||||
|
expression.register_symbol_table(symbol_table);
|
||||||
|
|
||||||
|
std::string expression_str =
|
||||||
|
"foo(1,2,3) + boo(1) / boo(1/2,2/3,3/4,4/5,5/6)";
|
||||||
|
|
||||||
|
parser_t parser;
|
||||||
|
parser.compile(expression_str,expression);
|
||||||
|
|
||||||
|
expression.value();
|
||||||
|
|
||||||
|
|
||||||
|
(4) Function Side-Effects
|
||||||
|
All function calls are assumed to have side-effects by default. What
|
||||||
|
that means is that a certain type of optimisation will not be carried
|
||||||
|
out when the function is being called. The optimisation in question
|
||||||
|
is: constant folding. Normally during compilation this optimisation
|
||||||
|
would be invoked when all the parameters being passed into the
|
||||||
|
function are literals, the function will be evaluated at that point
|
||||||
|
and a new literal will replace the function call node in the AST.
|
||||||
|
|
||||||
|
If it is certain that the function being registered does not have any
|
||||||
|
side effects and can be correctly constant folded where appropriate,
|
||||||
|
then during the construction of the function a 'false' can be passed
|
||||||
|
to the constructor to denote the lack of side-effects.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct foo : public exprtk::ifunction<T>
|
||||||
|
{
|
||||||
|
foo() : exprtk::ifunction<T>(3,false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
T operator()(const T& v1, const T& v2, const T& v3)
|
||||||
|
{ ... }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
(5) Zero Parameter Functions
|
||||||
|
When an ifunction derived type is defined with zero number of
|
||||||
|
parameters, there are two calling conventions within expressions that
|
||||||
|
are allowed. For a function named 'foo' with zero input parameters the
|
||||||
|
calling styles are as follows:
|
||||||
|
|
||||||
|
(1) x + sin(foo()- 2) / y
|
||||||
|
(2) x + sin(foo - 2) / y
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[14 - EXPRTK NOTES]
|
||||||
|
The following is a list of facts and suggestions one may want to take
|
||||||
|
into account when using Exprtk:
|
||||||
|
|
||||||
(00) Precision and performance of expression evaluations are the
|
(00) Precision and performance of expression evaluations are the
|
||||||
dominant principles of the ExprTk library.
|
dominant principles of the ExprTk library.
|
||||||
|
|
||||||
(01) Supported types are float, double and long double.
|
(01) ExprTk uses a rudimentary imperative programming model with
|
||||||
|
syntax based on languages such as Pascal and C.
|
||||||
|
|
||||||
(02) Standard mathematical operator precedence is applied (BEDMAS).
|
(02) Supported types are float, double and long double.
|
||||||
|
|
||||||
(03) Results of expressions that are deemed as being 'valid' are to
|
(03) Standard mathematical operator precedence is applied (BEDMAS).
|
||||||
|
|
||||||
|
(04) Results of expressions that are deemed as being 'valid' are to
|
||||||
exist within the set of Real numbers. All other results will be
|
exist within the set of Real numbers. All other results will be
|
||||||
of the value: Not-A-Number (NaN).
|
of the value: Not-A-Number (NaN).
|
||||||
|
|
||||||
(04) Supported user defined types are numeric and string variables
|
(05) Supported user defined types are numeric and string variables
|
||||||
and functions.
|
and functions.
|
||||||
|
|
||||||
(05) All variable and function names are case-insensitive.
|
(06) All variable and function names are case-insensitive.
|
||||||
|
|
||||||
(06) Variable and function names must begin with a letter
|
(07) 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)
|
||||||
|
|
||||||
(07) Expression lengths and sub-expression lists are limited only by
|
(08) Expression lengths and sub-expression lists are limited only by
|
||||||
storage capacity.
|
storage capacity.
|
||||||
|
|
||||||
(08) The life-time of objects registered with or created from a
|
(09) The life-time of objects registered with or created from a
|
||||||
specific symbol-table must span at least the life-time of the
|
specific symbol-table must span at least the life-time of the
|
||||||
compiled expressions which utilize objects, such as variables,
|
compiled expressions which utilize objects, such as variables,
|
||||||
of that symbol-table, otherwise the result will be undefined
|
of that symbol-table, otherwise the result will be undefined
|
||||||
behavior.
|
behavior.
|
||||||
|
|
||||||
(09) Equal/Nequal are normalized equality routines, which use
|
(10) Equal/Nequal are normalized equality routines, which use
|
||||||
epsilons of 0.0000000001 and 0.000001 for double and float
|
epsilons of 0.0000000001 and 0.000001 for double and float
|
||||||
types respectively.
|
types respectively.
|
||||||
|
|
||||||
(10) All trigonometric functions assume radian input unless
|
(11) All trigonometric functions assume radian input unless
|
||||||
stated otherwise.
|
stated otherwise.
|
||||||
|
|
||||||
(11) Expressions may contain white-space characters such as
|
(12) 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')
|
||||||
|
|
||||||
(12) Strings may be constructed from any letters, digits or special
|
(13) 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 do not give a damn!'
|
eg: 'Frankly my dear, I do not give a damn!'
|
||||||
|
|
||||||
(13) User defined normal functions can have up to 20 parameters,
|
(14) 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.
|
||||||
|
|
||||||
(14) The inbuilt polynomial functions can be at most of degree 12.
|
(15) The inbuilt polynomial functions can be at most of degree 12.
|
||||||
|
|
||||||
(15) Where appropriate constant folding optimisations may be
|
(16) Where appropriate constant folding optimisations may 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)')
|
||||||
|
|
||||||
(16) If the strength reduction compilation option has been enabled,
|
(17) If the strength reduction compilation option has been enabled,
|
||||||
then where applicable strength reduction optimisations may be
|
then where applicable strength reduction optimisations may be
|
||||||
applied.
|
applied.
|
||||||
|
|
||||||
(17) String processing capabilities are available by default.
|
(18) 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
|
||||||
|
|
||||||
(18) Composited functions can call themselves or any other functions
|
(19) Composited functions can call themselves or any other functions
|
||||||
that have been defined prior to their own definition.
|
that have been defined prior to their own definition.
|
||||||
|
|
||||||
(19) Recursive calls made from within composited functions will have
|
(20) Recursive calls made from within composited functions will have
|
||||||
a stack size bound by the stack of the executing architecture.
|
a stack size bound by the stack of the executing architecture.
|
||||||
|
|
||||||
(20) User defined functions by default are assumed to have side
|
(21) User defined functions by default are assumed to have side
|
||||||
effects. As such an "all constant parameter" invocation of such
|
effects. As such an "all constant parameter" invocation of such
|
||||||
functions wont result in constant folding. If the function has
|
functions wont result in constant folding. If the function has
|
||||||
no side effects then that can be noted during the constructor
|
no side effects then that can be noted during the constructor
|
||||||
of the ifunction allowing it to be constant folded where
|
of the ifunction allowing it to be constant folded where
|
||||||
appropriate.
|
appropriate.
|
||||||
|
|
||||||
(21) The entity relationship between symbol_table and an expression
|
(22) The entity relationship between symbol_table and an expression
|
||||||
is one-to-many. Hence the intended use case is to have a single
|
is one-to-many. Hence the intended use case is to have a single
|
||||||
symbol table manage the variable and function requirements of
|
symbol table manage the variable and function requirements of
|
||||||
multiple expressions.
|
multiple expressions.
|
||||||
|
|
||||||
(22) The common use-case for an expression is to have it compiled
|
(23) The common use-case for an expression is to have it compiled
|
||||||
only ONCE and then subsequently have it evaluated multiple
|
only ONCE and then subsequently have it evaluated multiple
|
||||||
times. An extremely inefficient and suboptimal approach would
|
times. An extremely inefficient and suboptimal approach would
|
||||||
be to recompile an expression from its string form every time
|
be to recompile an expression from its string form every time
|
||||||
it requires evaluating.
|
it requires evaluating.
|
||||||
|
|
||||||
(23) The following are examples of compliant floating point value
|
(24) The following are examples of compliant floating point value
|
||||||
representations:
|
representations:
|
||||||
(a) 12345 (b) -123.456
|
(a) 12345 (e) -123.456
|
||||||
(c) +123.456e+12 (d) 123.456E-12
|
(b) +123.456e+12 (f) 123.456E-12
|
||||||
(e) +012.045e+07 (f) .1234
|
(c) +012.045e+07 (g) .1234
|
||||||
(g) 123.456f (h) -321.654E+3L
|
(d) 123.456f (h) -321.654E+3L
|
||||||
|
|
||||||
(24) Expressions may contain any of the following comment styles:
|
(25) Expressions may contain any of the following comment styles:
|
||||||
1. // .... \n
|
1. // .... \n
|
||||||
2. # .... \n
|
2. # .... \n
|
||||||
3. /* .... */
|
3. /* .... */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[13 - SIMPLE EXPRTK EXAMPLE]
|
[15 - SIMPLE EXPRTK EXAMPLE]
|
||||||
--- snip ---
|
--- snip ---
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -974,8 +1184,8 @@ int main()
|
||||||
|
|
||||||
if (!parser.compile(expression_str,expression))
|
if (!parser.compile(expression_str,expression))
|
||||||
{
|
{
|
||||||
// A compilation error has occured. Attempt to
|
// A compilation error has occurred. Attempt to
|
||||||
// print all errors to the stdout.
|
// print all errors to stdout.
|
||||||
|
|
||||||
printf("Error: %s\tExpression: %s\n",
|
printf("Error: %s\tExpression: %s\n",
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
|
@ -1014,7 +1224,7 @@ int main()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[14 - FILES]
|
[16 - FILES]
|
||||||
(00) Makefile
|
(00) Makefile
|
||||||
(01) readme.txt
|
(01) readme.txt
|
||||||
(02) exprtk.hpp
|
(02) exprtk.hpp
|
||||||
|
@ -1032,3 +1242,149 @@ int main()
|
||||||
(14) exprtk_simple_example_10.cpp
|
(14) exprtk_simple_example_10.cpp
|
||||||
(15) exprtk_simple_example_11.cpp
|
(15) exprtk_simple_example_11.cpp
|
||||||
(16) exprtk_simple_example_12.cpp
|
(16) exprtk_simple_example_12.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[17 - LANGUAGE STRUCTURE]
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|00 - If Statement |
|
||||||
|
| |
|
||||||
|
| [if] ---> [(] ---> [condition] -+-> [,] -+ |
|
||||||
|
| | | |
|
||||||
|
| +---------------<---------------+ | |
|
||||||
|
| | | |
|
||||||
|
| | +------------------<------------------+ |
|
||||||
|
| | | |
|
||||||
|
| | +--> [consequent] ---> [,] ---> [alternative] ---> [)] |
|
||||||
|
| | |
|
||||||
|
| +--> [)] --+-> [{] ---> [expression*] ---> [}] --+ |
|
||||||
|
| | | |
|
||||||
|
| | +---------<----------+ |
|
||||||
|
| +----<-----+ | |
|
||||||
|
| | v |
|
||||||
|
| +--> [consequent] --> [;] -{*}-> [else-statement] |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|01 - Else Statement |
|
||||||
|
| |
|
||||||
|
| [else] -+-> [alternative] ---> [;] |
|
||||||
|
| | |
|
||||||
|
| +--> [{] ---> [expression*] ---> [}] |
|
||||||
|
| | |
|
||||||
|
| +--> [if-statement] |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|02 - Ternary Statement |
|
||||||
|
| |
|
||||||
|
| [condition] ---> [?] ---> [consequent] ---> [:] --+ |
|
||||||
|
| | |
|
||||||
|
| +------------------------<------------------------+ |
|
||||||
|
| | |
|
||||||
|
| +--> [alternative] --> [;] |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|03 - While Loop |
|
||||||
|
| |
|
||||||
|
| [while] ---> [(] ---> [condition] ---> [)] ---+ |
|
||||||
|
| | |
|
||||||
|
| +----------------------<----------------------+ |
|
||||||
|
| | |
|
||||||
|
| +--> [{] ---> [expression*] ---> [}] |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|04 - Repeat Until Loop |
|
||||||
|
| |
|
||||||
|
| [repeat] ---> [expression*] ---+ |
|
||||||
|
| | |
|
||||||
|
| +--------------<---------------+ |
|
||||||
|
| | |
|
||||||
|
| +--> [until] ---> [(] ---> [condition] --->[)] |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|05 - For Loop |
|
||||||
|
| |
|
||||||
|
| [for] ---> [(] -+-> [initialise expression] --+--+ |
|
||||||
|
| | | | |
|
||||||
|
| +------------->---------------+ v |
|
||||||
|
| | |
|
||||||
|
| +-----------------------<------------------------+ |
|
||||||
|
| | |
|
||||||
|
| +--> [,] -+-> [condition] -+-> [,] ---+ |
|
||||||
|
| | | | |
|
||||||
|
| +------->--------+ v |
|
||||||
|
| | |
|
||||||
|
| +------------------<---------+--------+ |
|
||||||
|
| | | |
|
||||||
|
| +--> [increment expression] -+-> [)] --+ |
|
||||||
|
| | |
|
||||||
|
| +------------------<-------------------+ |
|
||||||
|
| | |
|
||||||
|
| +--> [{] ---> [expression*] ---> [}] |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|06 - Switch Statement |
|
||||||
|
| |
|
||||||
|
| [switch] ---> [{] ---+ |
|
||||||
|
| | |
|
||||||
|
| +---------<----------+-----------<-----------+ |
|
||||||
|
| | | |
|
||||||
|
| +--> [case] ---> [condition] ---> [:] ---+ | |
|
||||||
|
| | | |
|
||||||
|
| +-------------------<--------------------+ | |
|
||||||
|
| | | |
|
||||||
|
| +--> [consequent] ---> [;] --------->--------+ |
|
||||||
|
| | | |
|
||||||
|
| | | |
|
||||||
|
| +--> [default] ---> [consequent] ---> [;] ---+ |
|
||||||
|
| | | |
|
||||||
|
| +---------------------<----------------------+ |
|
||||||
|
| | |
|
||||||
|
| +--> [}] |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|07 - Multi Subexpression Statement |
|
||||||
|
| |
|
||||||
|
| +--------------<---------------+ |
|
||||||
|
| | | |
|
||||||
|
| [~] ---> [{\(] -+-> [expression] -+-> [;\,] ---+ |
|
||||||
|
| | |
|
||||||
|
| +----------------<----------------+ |
|
||||||
|
| | |
|
||||||
|
| +--> [}\)] |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|08 - Multi Case-Consequent Statement |
|
||||||
|
| |
|
||||||
|
| [[*]] ---> [{] ---+ |
|
||||||
|
| | |
|
||||||
|
| +--------<--------+--------------<----------+ |
|
||||||
|
| | | |
|
||||||
|
| +--> [case] ---> [condition] ---> [:] ---+ | |
|
||||||
|
| | | |
|
||||||
|
| +-------------------<--------------------+ | |
|
||||||
|
| | | |
|
||||||
|
| +--> [consequent] ---> [;] ---+------>------+ |
|
||||||
|
| | |
|
||||||
|
| +--> [}] |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|09 - Variable Definition Statement |
|
||||||
|
| |
|
||||||
|
| [var] ---> [symbol] -+-> [:=] ---> [expression] -+-> [;] |
|
||||||
|
| | | |
|
||||||
|
| +------------->-------------+ |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|10 - Vector Definition Statement |
|
||||||
|
| |
|
||||||
|
| [var] ---> [symbol] ---> [[] ---> [constant] ---> []] --+ |
|
||||||
|
| | |
|
||||||
|
| +---------------------------<---------------------------+ |
|
||||||
|
| | |
|
||||||
|
| | +--------->---------+ |
|
||||||
|
| | | | |
|
||||||
|
| +--> [:=] ---> [{] -+-+-> [expression] -+-> [}] -+-> [;] |
|
||||||
|
| | | |
|
||||||
|
| +--<--- [,] <-----+ |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|
Loading…
Reference in New Issue