@@ -3788,6 +3788,91 @@ namespace exprtk
37883788 std::vector<std::pair<lexer::token,lexer::token> > error_list_;
37893789 };
37903790
3791+ class sequence_validator_3tokens : public lexer::token_scanner
3792+ {
3793+ private:
3794+
3795+ typedef lexer::token::token_type token_t;
3796+ typedef std::pair<token_t,std::pair<token_t,token_t>> token_triplet_t;
3797+ typedef std::set<token_triplet_t> set_t;
3798+
3799+ public:
3800+
3801+ using lexer::token_scanner::operator();
3802+
3803+ sequence_validator_3tokens()
3804+ : lexer::token_scanner(3)
3805+ {
3806+ add_invalid(lexer::token::e_number , lexer::token::e_number , lexer::token::e_number);
3807+ add_invalid(lexer::token::e_string , lexer::token::e_string , lexer::token::e_string);
3808+ add_invalid(lexer::token::e_comma , lexer::token::e_comma , lexer::token::e_comma );
3809+
3810+ add_invalid(lexer::token::e_add ,lexer::token::e_add , lexer::token::e_add);
3811+ add_invalid(lexer::token::e_sub ,lexer::token::e_sub , lexer::token::e_sub);
3812+ add_invalid(lexer::token::e_div ,lexer::token::e_div , lexer::token::e_div);
3813+ add_invalid(lexer::token::e_mul ,lexer::token::e_mul , lexer::token::e_mul);
3814+ add_invalid(lexer::token::e_mod ,lexer::token::e_mod , lexer::token::e_mod);
3815+ add_invalid(lexer::token::e_pow ,lexer::token::e_pow , lexer::token::e_pow);
3816+
3817+ add_invalid(lexer::token::e_add ,lexer::token::e_sub , lexer::token::e_add);
3818+ add_invalid(lexer::token::e_sub ,lexer::token::e_add , lexer::token::e_sub);
3819+ add_invalid(lexer::token::e_div ,lexer::token::e_mul , lexer::token::e_div);
3820+ add_invalid(lexer::token::e_mul ,lexer::token::e_div , lexer::token::e_mul);
3821+ add_invalid(lexer::token::e_mod ,lexer::token::e_pow , lexer::token::e_mod);
3822+ add_invalid(lexer::token::e_pow ,lexer::token::e_mod , lexer::token::e_pow);
3823+ }
3824+
3825+ bool result()
3826+ {
3827+ return error_list_.empty();
3828+ }
3829+
3830+ bool operator() (const lexer::token& t0, const lexer::token& t1, const lexer::token& t2)
3831+ {
3832+ const set_t::value_type p = std::make_pair(t0.type,std::make_pair(t1.type,t2.type));
3833+
3834+ if (invalid_comb_.find(p) != invalid_comb_.end())
3835+ {
3836+ error_list_.push_back(std::make_pair(t0,t1));
3837+ }
3838+
3839+ return true;
3840+ }
3841+
3842+ std::size_t error_count() const
3843+ {
3844+ return error_list_.size();
3845+ }
3846+
3847+ std::pair<lexer::token,lexer::token> error(const std::size_t index)
3848+ {
3849+ if (index < error_list_.size())
3850+ {
3851+ return error_list_[index];
3852+ }
3853+ else
3854+ {
3855+ static const lexer::token error_token;
3856+ return std::make_pair(error_token,error_token);
3857+ }
3858+ }
3859+
3860+ void clear_errors()
3861+ {
3862+ error_list_.clear();
3863+ }
3864+
3865+ private:
3866+
3867+ void add_invalid(token_t t0, token_t t1, token_t t2)
3868+ {
3869+ invalid_comb_.insert(std::make_pair(t0,std::make_pair(t1,t2)));
3870+ }
3871+
3872+ set_t invalid_comb_;
3873+ std::vector<std::pair<lexer::token,lexer::token> > error_list_;
3874+ };
3875+
37913876 struct helper_assembly
37923877 {
37933878 inline bool register_scanner(lexer::token_scanner* scanner)
@@ -19908,7 +19993,8 @@ namespace exprtk
1990819993
1990919994 if (settings_.sequence_check_enabled())
1991019995 {
19911- helper_assembly_.register_scanner(&sequence_validator_);
19996+ helper_assembly_.register_scanner(&sequence_validator_ );
19997+ helper_assembly_.register_scanner(&sequence_validator_3tkns_);
1991219998 }
1991319999 }
1991420000 }
@@ -20084,9 +20170,10 @@ namespace exprtk
2008420170 {
2008520171 if (helper_assembly_.error_token_scanner)
2008620172 {
20087- lexer::helper::bracket_checker* bracket_checker_ptr = 0;
20088- lexer::helper::numeric_checker* numeric_checker_ptr = 0;
20089- lexer::helper::sequence_validator* sequence_validator_ptr = 0;
20173+ lexer::helper::bracket_checker* bracket_checker_ptr = 0;
20174+ lexer::helper::numeric_checker* numeric_checker_ptr = 0;
20175+ lexer::helper::sequence_validator* sequence_validator_ptr = 0;
20176+ lexer::helper::sequence_validator_3tokens* sequence_validator3_ptr = 0;
2009020177
2009120178 if (0 != (bracket_checker_ptr = dynamic_cast<lexer::helper::bracket_checker*>(helper_assembly_.error_token_scanner)))
2009220179 {
@@ -20134,6 +20221,26 @@ namespace exprtk
2013420221 sequence_validator_ptr->clear_errors();
2013520222 }
2013620223 }
20224+ else if (0 != (sequence_validator3_ptr = dynamic_cast<lexer::helper::sequence_validator_3tokens*>(helper_assembly_.error_token_scanner)))
20225+ {
20226+ for (std::size_t i = 0; i < sequence_validator3_ptr->error_count(); ++i)
20227+ {
20228+ std::pair<lexer::token,lexer::token> error_token = sequence_validator3_ptr->error(i);
20229+
20230+ set_error(
20231+ make_error(parser_error::e_token,
20232+ error_token.first,
20233+ "ERR007 - Invalid token sequence: '" +
20234+ error_token.first.value + "' and '" +
20235+ error_token.second.value + "'",
20236+ exprtk_error_location));
20237+ }
20238+
20239+ if (sequence_validator3_ptr->error_count())
20240+ {
20241+ sequence_validator3_ptr->clear_errors();
20242+ }
20243+ }
2013720244 }
2013820245
2013920246 return false;
@@ -24055,10 +24162,14 @@ namespace exprtk
2405524162 if (null_initialisation)
2405624163 result = expression_generator_(T(0.0));
2405724164 else if (vec_to_vec_initialiser)
24165+ {
24166+ expression_node_ptr vec_node = node_allocator_.allocate<vector_node_t>(vec_holder);
24167+
2405824168 result = expression_generator_(
2405924169 details::e_assign,
24060- node_allocator_.allocate<vector_node_t>(vec_holder) ,
24170+ vec_node ,
2406124171 vec_initilizer_list[0]);
24172+ }
2406224173 else
2406324174 result = node_allocator_
2406424175 .allocate<details::vector_assignment_node<T> >(
@@ -26293,15 +26404,19 @@ namespace exprtk
2629326404 return (*this)(operation,branch);
2629426405 }
2629526406
26296- inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr b0, expression_node_ptr b1)
26407+ inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr& b0, expression_node_ptr& b1)
2629726408 {
26298- if ((0 == b0) || (0 == b1))
26299- return error_node();
26300- else
26409+ expression_node_ptr result = error_node();
26410+
26411+ if ((0 != b0) && (0 != b1))
2630126412 {
2630226413 expression_node_ptr branch[2] = { b0, b1 };
26303- return expression_generator<Type>::operator()(operation,branch);
26414+ result = expression_generator<Type>::operator()(operation, branch);
26415+ b0 = branch[0];
26416+ b1 = branch[1];
2630426417 }
26418+
26419+ return result;
2630526420 }
2630626421
2630726422 inline expression_node_ptr conditional(expression_node_ptr condition,
@@ -34672,13 +34787,14 @@ namespace exprtk
3467234787
3467334788 lexer::helper::helper_assembly helper_assembly_;
3467434789
34675- lexer::helper::commutative_inserter commutative_inserter_;
34676- lexer::helper::operator_joiner operator_joiner_2_;
34677- lexer::helper::operator_joiner operator_joiner_3_;
34678- lexer::helper::symbol_replacer symbol_replacer_;
34679- lexer::helper::bracket_checker bracket_checker_;
34680- lexer::helper::numeric_checker numeric_checker_;
34681- lexer::helper::sequence_validator sequence_validator_;
34790+ lexer::helper::commutative_inserter commutative_inserter_;
34791+ lexer::helper::operator_joiner operator_joiner_2_;
34792+ lexer::helper::operator_joiner operator_joiner_3_;
34793+ lexer::helper::symbol_replacer symbol_replacer_;
34794+ lexer::helper::bracket_checker bracket_checker_;
34795+ lexer::helper::numeric_checker numeric_checker_;
34796+ lexer::helper::sequence_validator sequence_validator_;
34797+ lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_;
3468234798
3468334799 template <typename ParserType>
3468434800 friend void details::disable_type_checking(ParserType& p);
@@ -38236,9 +38352,9 @@ namespace exprtk
3823638352 namespace information
3823738353 {
3823838354 static const char* library = "Mathematical Expression Toolkit";
38239- static const char* version = "2.718281828459045235360287471352662497757247093699 "
38240- "95957496696762772407663035354759457138217852516642 ";
38241- static const char* date = "20180913 ";
38355+ static const char* version = "2.7182818284590452353602874713526624977572470936999 "
38356+ "595749669676277240766303535475945713821785251664274 ";
38357+ static const char* date = "20181216 ";
3824238358
3824338359 static inline std::string data()
3824438360 {
0 commit comments