@@ -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;
0 commit comments