Skip to content

Commit 8ac8348

Browse files
committed
Updates to ExprTk
1 parent 34d07e2 commit 8ac8348

File tree

3 files changed

+153
-39
lines changed

3 files changed

+153
-39
lines changed

exprtk/exprtk.hpp

Lines changed: 95 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20191,7 +20191,7 @@ namespace exprtk
2019120191
dec_.return_present_ = true;
2019220192

2019320193
e = expression_generator_
20194-
.return_envelope(e,results_context_,retinvk_ptr);
20194+
.return_envelope(e, results_context_, retinvk_ptr);
2019520195
}
2019620196

2019720197
expr.set_expression(e);
@@ -35328,36 +35328,102 @@ namespace exprtk
3532835328
friend void details::disable_type_checking(ParserType& p);
3532935329
};
3533035330

35331+
namespace details
35332+
{
35333+
template <typename T>
35334+
struct collector_helper
35335+
{
35336+
typedef exprtk::symbol_table<T> symbol_table_t;
35337+
typedef exprtk::expression<T> expression_t;
35338+
typedef exprtk::parser<T> parser_t;
35339+
typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
35340+
typedef typename parser_t::unknown_symbol_resolver usr_t;
35341+
35342+
struct resolve_as_vector : public parser_t::unknown_symbol_resolver
35343+
{
35344+
typedef exprtk::parser<T> parser_t;
35345+
35346+
resolve_as_vector()
35347+
: usr_t(usr_t::e_usrmode_extended)
35348+
{}
35349+
35350+
virtual bool process(const std::string& unknown_symbol,
35351+
symbol_table_t& symbol_table,
35352+
std::string&)
35353+
{
35354+
static T v[1];
35355+
symbol_table.add_vector(unknown_symbol,v);
35356+
return true;
35357+
}
35358+
};
35359+
35360+
static inline bool collection_pass(const std::string& expression_string,
35361+
std::set<std::string>& symbol_set,
35362+
const bool collect_variables,
35363+
const bool collect_functions,
35364+
const bool vector_pass = false)
35365+
{
35366+
symbol_table_t symbol_table;
35367+
expression_t expression;
35368+
parser_t parser;
35369+
35370+
resolve_as_vector vect_resolver;
35371+
35372+
expression.register_symbol_table(symbol_table);
35373+
35374+
if (vector_pass)
35375+
parser.enable_unknown_symbol_resolver(&vect_resolver);
35376+
else
35377+
parser.enable_unknown_symbol_resolver();
35378+
35379+
if (collect_variables)
35380+
parser.dec().collect_variables() = true;
35381+
35382+
if (collect_functions)
35383+
parser.dec().collect_functions() = true;
35384+
35385+
bool pass_result = false;
35386+
35387+
if (parser.compile(expression_string, expression))
35388+
{
35389+
pass_result = true;
35390+
35391+
std::deque<symbol_t> symb_list;
35392+
parser.dec().symbols(symb_list);
35393+
35394+
for (std::size_t i = 0; i < symb_list.size(); ++i)
35395+
{
35396+
symbol_set.insert(symb_list[i].first);
35397+
}
35398+
}
35399+
35400+
return pass_result;
35401+
}
35402+
};
35403+
}
35404+
3533135405
template <typename Allocator,
3533235406
template <typename, typename> class Sequence>
35333-
inline bool collect_variables(const std::string& expr_str,
35407+
inline bool collect_variables(const std::string& expression,
3533435408
Sequence<std::string, Allocator>& symbol_list)
3533535409
{
3533635410
typedef double T;
35337-
typedef exprtk::symbol_table<T> symbol_table_t;
35338-
typedef exprtk::expression<T> expression_t;
35339-
typedef exprtk::parser<T> parser_t;
35340-
typedef parser_t::dependent_entity_collector::symbol_t symbol_t;
35411+
typedef details::collector_helper<T> collect_t;
3534135412

35342-
symbol_table_t symbol_table;
35343-
expression_t expression;
35344-
parser_t parser;
35413+
std::set<std::string> symbol_set;
3534535414

35346-
expression.register_symbol_table(symbol_table);
35415+
const bool variable_pass = collect_t::collection_pass(expression, symbol_set, true, false, false);
35416+
const bool vector_pass = collect_t::collection_pass(expression, symbol_set, true, false, true);
3534735417

35348-
parser.enable_unknown_symbol_resolver();
35349-
parser.dec().collect_variables() = true;
35350-
35351-
if (!parser.compile(expr_str, expression))
35418+
if (!variable_pass && !vector_pass)
3535235419
return false;
3535335420

35354-
std::deque<symbol_t> symb_list;
35355-
35356-
parser.dec().symbols(symb_list);
35421+
std::set<std::string>::iterator itr = symbol_set.begin();
3535735422

35358-
for (std::size_t i = 0; i < symb_list.size(); ++i)
35423+
while (symbol_set.end() != itr)
3535935424
{
35360-
symbol_list.push_back(symb_list[i].first);
35425+
symbol_list.push_back(*itr);
35426+
++itr;
3536135427
}
3536235428

3536335429
return true;
@@ -35404,34 +35470,26 @@ namespace exprtk
3540435470

3540535471
template <typename Allocator,
3540635472
template <typename, typename> class Sequence>
35407-
inline bool collect_functions(const std::string& expr_str,
35473+
inline bool collect_functions(const std::string& expression,
3540835474
Sequence<std::string, Allocator>& symbol_list)
3540935475
{
3541035476
typedef double T;
35411-
typedef exprtk::symbol_table<T> symbol_table_t;
35412-
typedef exprtk::expression<T> expression_t;
35413-
typedef exprtk::parser<T> parser_t;
35414-
typedef parser_t::dependent_entity_collector::symbol_t symbol_t;
35477+
typedef details::collector_helper<T> collect_t;
3541535478

35416-
symbol_table_t symbol_table;
35417-
expression_t expression;
35418-
parser_t parser;
35479+
std::set<std::string> symbol_set;
3541935480

35420-
expression.register_symbol_table(symbol_table);
35481+
const bool variable_pass = collect_t::collection_pass(expression, symbol_set, false, true, false);
35482+
const bool vector_pass = collect_t::collection_pass(expression, symbol_set, false, true, true);
3542135483

35422-
parser.enable_unknown_symbol_resolver();
35423-
parser.dec().collect_functions() = true;
35424-
35425-
if (!parser.compile(expr_str, expression))
35484+
if (!variable_pass && !vector_pass)
3542635485
return false;
3542735486

35428-
std::deque<symbol_t> symb_list;
35429-
35430-
parser.dec().symbols(symb_list);
35487+
std::set<std::string>::iterator itr = symbol_set.begin();
3543135488

35432-
for (std::size_t i = 0; i < symb_list.size(); ++i)
35489+
while (symbol_set.end() != itr)
3543335490
{
35434-
symbol_list.push_back(symb_list[i].first);
35491+
symbol_list.push_back(*itr);
35492+
++itr;
3543535493
}
3543635494

3543735495
return true;

exprtk/exprtk_simple_example_15.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void black_scholes_merton_model()
7171

7272
printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",
7373
callput_flag.c_str(),
74-
s,x,t,r,v,
74+
s, x, t, r, v,
7575
bsm);
7676
}
7777

@@ -82,7 +82,7 @@ void black_scholes_merton_model()
8282

8383
printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",
8484
callput_flag.c_str(),
85-
s,x,t,r,v,
85+
s, x, t, r, v,
8686
bsm);
8787
}
8888
}

exprtk/exprtk_test.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4250,6 +4250,62 @@ inline bool run_test10()
42504250
}
42514251
}
42524252

4253+
{
4254+
const std::string expression =
4255+
"for (var i := 0; i < min(x[],y[],z[]); i += 1)"
4256+
"{ z[i] := 3sin(x[i]) + 2log(y[i]); }";
4257+
4258+
std::vector<std::string> var_symbol_list;
4259+
std::vector<std::string> func_symbol_list;
4260+
4261+
if (!exprtk::collect_variables(expression, var_symbol_list))
4262+
{
4263+
printf("run_test10() - Failed to collect variables.\n");
4264+
return false;
4265+
}
4266+
4267+
if (!exprtk::collect_functions(expression, func_symbol_list))
4268+
{
4269+
printf("run_test10() - Failed to collect functions.\n");
4270+
return false;
4271+
}
4272+
4273+
std::sort(var_symbol_list .begin(), var_symbol_list .end());
4274+
std::sort(func_symbol_list.begin(), func_symbol_list.end());
4275+
4276+
std::vector<std::string> expected_var_symbol_list;
4277+
std::vector<std::string> expected_func_symbol_list;
4278+
4279+
expected_var_symbol_list.push_back("i");
4280+
expected_var_symbol_list.push_back("x");
4281+
expected_var_symbol_list.push_back("y");
4282+
expected_var_symbol_list.push_back("z");
4283+
4284+
expected_func_symbol_list.push_back("log");
4285+
expected_func_symbol_list.push_back("min");
4286+
expected_func_symbol_list.push_back("sin");
4287+
4288+
const bool var_result = (var_symbol_list.size() == expected_var_symbol_list.size()) &&
4289+
std::equal(var_symbol_list.begin(),
4290+
var_symbol_list.end(),
4291+
expected_var_symbol_list.begin());
4292+
if (!var_result)
4293+
{
4294+
printf("run_test10() - Failed collected variable comparison between recieved and expected variables\n");
4295+
return false;
4296+
}
4297+
4298+
const bool func_result = (func_symbol_list.size() == expected_func_symbol_list.size()) &&
4299+
std::equal(func_symbol_list.begin(),
4300+
func_symbol_list.end(),
4301+
expected_func_symbol_list.begin());
4302+
if (!func_result)
4303+
{
4304+
printf("run_test10() - Failed collected fuctions comparison between recieved and expected functions\n");
4305+
return false;
4306+
}
4307+
}
4308+
42534309
{
42544310
std::string expression_list[] =
42554311
{

0 commit comments

Comments
 (0)