C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
13a256fcb2
commit
7d798d0dec
107
exprtk.hpp
107
exprtk.hpp
|
@ -3653,6 +3653,19 @@ namespace exprtk
|
|||
return node && (details::expression_node<T>::e_function == node->type());
|
||||
}
|
||||
|
||||
template <typename T> class unary_node;
|
||||
|
||||
template <typename T>
|
||||
inline bool is_negate_node(const expression_node<T>* node)
|
||||
{
|
||||
if (node && is_unary_node(node))
|
||||
{
|
||||
return (details::e_neg == static_cast<const unary_node<T>*>(node)->operation());
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool branch_deletable(expression_node<T>* node)
|
||||
{
|
||||
|
@ -4059,6 +4072,11 @@ namespace exprtk
|
|||
return branch_;
|
||||
}
|
||||
|
||||
inline void release()
|
||||
{
|
||||
branch_deletable_ = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
operator_type operation_;
|
||||
|
@ -13514,10 +13532,16 @@ namespace exprtk
|
|||
expression_node_ptr right_branch = parse_expression(current_state.right);
|
||||
expression_node_ptr new_expression = error_node();
|
||||
|
||||
details::operator_type current_operation = current_state.operation;
|
||||
|
||||
if (right_branch)
|
||||
{
|
||||
simplify_negation(current_operation,
|
||||
expression,
|
||||
right_branch);
|
||||
|
||||
new_expression = expression_generator_(
|
||||
current_state.operation,
|
||||
current_operation,
|
||||
expression,
|
||||
right_branch
|
||||
);
|
||||
|
@ -13553,6 +13577,77 @@ namespace exprtk
|
|||
return expression;
|
||||
}
|
||||
|
||||
bool simplify_negation_branch(expression_node_ptr& right)
|
||||
{
|
||||
if (is_unary_node(right))
|
||||
{
|
||||
details::unary_node<T>* un = static_cast<details::unary_node<T>*>(right);
|
||||
if (details::e_neg == un->operation())
|
||||
{
|
||||
expression_node_ptr un_r = un->branch(0);
|
||||
un->release();
|
||||
free_node(node_allocator_,right);
|
||||
right = un_r;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void simplify_negation(details::operator_type& current_operation,
|
||||
expression_node_ptr& left,
|
||||
expression_node_ptr& right)
|
||||
{
|
||||
bool simplified = false;
|
||||
do
|
||||
{
|
||||
simplified = false;
|
||||
// (x + - y) --> (x - y)
|
||||
if (details::e_add == current_operation)
|
||||
{
|
||||
if (is_negate_node(right))
|
||||
{
|
||||
if (simplify_negation_branch(right))
|
||||
{
|
||||
current_operation = details::e_sub;
|
||||
simplified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// (x - - y) --> (x + y)
|
||||
else if (details::e_sub == current_operation)
|
||||
{
|
||||
if (is_negate_node(right))
|
||||
{
|
||||
if (simplify_negation_branch(right))
|
||||
{
|
||||
current_operation = details::e_add;
|
||||
simplified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// -x * - y --> x * y
|
||||
// -x / - y --> x / y
|
||||
else if (
|
||||
(details::e_mul == current_operation) ||
|
||||
(details::e_div == current_operation)
|
||||
)
|
||||
{
|
||||
if (
|
||||
is_negate_node(left ) &&
|
||||
is_negate_node(right)
|
||||
)
|
||||
{
|
||||
simplify_negation_branch(left );
|
||||
simplify_negation_branch(right);
|
||||
simplified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (simplified);
|
||||
}
|
||||
|
||||
static inline expression_node_ptr error_node()
|
||||
{
|
||||
return reinterpret_cast<expression_node_ptr>(0);
|
||||
|
@ -16017,7 +16112,7 @@ namespace exprtk
|
|||
!token_is(token_t::e_rsqrbracket,false)
|
||||
)
|
||||
{
|
||||
if (!token_is(token_t::e_eof))
|
||||
if (!token_is(token_t::e_eof,false))
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
|
@ -18686,8 +18781,8 @@ namespace exprtk
|
|||
if (details::is_cob_node(branch[1]))
|
||||
{
|
||||
// Simplify expressions of the form:
|
||||
// 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) ---> 40320 * (9 + x)
|
||||
// 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) ---> 45 + x
|
||||
// 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) --> 40320 * (9 + x)
|
||||
// 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) --> 45 + x
|
||||
if (
|
||||
(operation == details::e_mul) ||
|
||||
(operation == details::e_add)
|
||||
|
@ -18794,8 +18889,8 @@ namespace exprtk
|
|||
if (details::is_boc_node(branch[0]))
|
||||
{
|
||||
// Simplify expressions of the form:
|
||||
// 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) ---> (x + 9) * 40320
|
||||
// 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) ---> x + 45
|
||||
// 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) --> (x + 9) * 40320
|
||||
// 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) --> x + 45
|
||||
if (
|
||||
(operation == details::e_mul) ||
|
||||
(operation == details::e_add)
|
||||
|
|
|
@ -342,6 +342,10 @@ static const test_t test_list[] =
|
|||
test_t("+(1+2)",+3.0),
|
||||
test_t("+(1-2)",-1.0),
|
||||
test_t("-(1-2)",+1.0),
|
||||
test_t("(-3*-6)",+18.0),
|
||||
test_t("(-6*-3)",+18.0),
|
||||
test_t("-(-3*-6)",-18.0),
|
||||
test_t("-(-6*-3)",-18.0),
|
||||
test_t("1.1+2.2+3.3",+6.6),
|
||||
test_t("+1.1+2.2+3.3",+6.6),
|
||||
test_t("-1.1-2.2-3.3",-6.6),
|
||||
|
@ -3277,6 +3281,22 @@ inline bool run_test10()
|
|||
{
|
||||
std::string expression_list[] =
|
||||
{
|
||||
"var x := 3; var y := 6; x + -y == -3",
|
||||
"var x := 3; var y := 6; x - -y == 9",
|
||||
"var x := 3; var y := 6; -x + -y == -9",
|
||||
"var x := 3; var y := 6; -x - -y == 3",
|
||||
"var x := 3; var y := 6; -x * -y == 18",
|
||||
"var x := 6; var y := 3; -x / -y == 2",
|
||||
"var x := 3; var y := 6; -(-x * -y) == -18",
|
||||
"var x := 6; var y := 3; -(-x / -y) == -2",
|
||||
"var x:=3; var y:=6; -(-x)*-(-y) == 18",
|
||||
"var x:=3; var y:=6; -(-x)*-(-(-y)) == -18",
|
||||
"var x:=3; var y:=6; -(-(-x))*-(-y) == -18",
|
||||
"var x:=3; var y:=6; -(-(-x))*-(-(-y)) == 18",
|
||||
"var x:=3; var y:=6; -(-(x+y))*-(-(y+x)) == 81",
|
||||
"var x:=3; var y:=6; -(-(-(x+y)))*-(-(y+x)) == -81",
|
||||
"var x:=3; var y:=6; -(-(x+y))*-(-(-(y+x))) == -81",
|
||||
"var x:=3; var y:=6; -(-(-(x+y)))*-(-(-(y+x))) == 81",
|
||||
"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)",
|
||||
|
|
Loading…
Reference in New Issue