C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
904f924005
commit
e5f917033f
343
exprtk.hpp
343
exprtk.hpp
|
@ -18,7 +18,7 @@
|
|||
* (03) 1 - sin(2 * x) + cos(pi / y) *
|
||||
* (04) a * exp(2 * t) + c *
|
||||
* (05) if(((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z) *
|
||||
* (06) if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x *
|
||||
* (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x *
|
||||
* (07) z := x + sin(2 * pi / y) *
|
||||
* (08) u := 2 * (pi * z) / (w := x + cos(y / pi)) *
|
||||
* (09) clamp(-1,sin(2 * pi * x) + cos(y / 2 * pi),+1) *
|
||||
|
@ -1514,7 +1514,8 @@ namespace exprtk
|
|||
e_rsqrbracket = ']', e_lsqrbracket = '[', e_rcrlbracket = '}',
|
||||
e_lcrlbracket = '{', e_comma = ',', e_add = '+',
|
||||
e_sub = '-', e_div = '/', e_mul = '*',
|
||||
e_mod = '%', e_pow = '^', e_colon = ':'
|
||||
e_mod = '%', e_pow = '^', e_colon = ':',
|
||||
e_ternary = '?'
|
||||
};
|
||||
|
||||
token()
|
||||
|
@ -1635,6 +1636,7 @@ namespace exprtk
|
|||
case e_mod : return "%";
|
||||
case e_pow : return "^";
|
||||
case e_colon : return ":";
|
||||
case e_ternary : return "?";
|
||||
default : return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
@ -2765,30 +2767,33 @@ namespace exprtk
|
|||
sequence_validator()
|
||||
: lexer::token_scanner(2)
|
||||
{
|
||||
add_invalid(lexer::token::e_number,lexer::token::e_number);
|
||||
add_invalid(lexer::token::e_string,lexer::token::e_string);
|
||||
add_invalid(lexer::token::e_number,lexer::token::e_string);
|
||||
add_invalid(lexer::token::e_string,lexer::token::e_number);
|
||||
add_invalid(lexer::token::e_string,lexer::token::e_colon );
|
||||
add_invalid(lexer::token::e_colon ,lexer::token::e_string);
|
||||
add_invalid(lexer::token::e_assign,lexer::token::e_string);
|
||||
add_invalid_set1(lexer::token::e_assign);
|
||||
add_invalid_set1(lexer::token::e_shr );
|
||||
add_invalid_set1(lexer::token::e_shl );
|
||||
add_invalid_set1(lexer::token::e_lte );
|
||||
add_invalid_set1(lexer::token::e_ne );
|
||||
add_invalid_set1(lexer::token::e_gte );
|
||||
add_invalid_set1(lexer::token::e_lt );
|
||||
add_invalid_set1(lexer::token::e_gt );
|
||||
add_invalid_set1(lexer::token::e_eq );
|
||||
add_invalid_set1(lexer::token::e_comma );
|
||||
add_invalid_set1(lexer::token::e_add );
|
||||
add_invalid_set1(lexer::token::e_sub );
|
||||
add_invalid_set1(lexer::token::e_div );
|
||||
add_invalid_set1(lexer::token::e_mul );
|
||||
add_invalid_set1(lexer::token::e_mod );
|
||||
add_invalid_set1(lexer::token::e_pow );
|
||||
add_invalid_set1(lexer::token::e_colon );
|
||||
add_invalid(lexer::token::e_number ,lexer::token::e_number );
|
||||
add_invalid(lexer::token::e_string ,lexer::token::e_string );
|
||||
add_invalid(lexer::token::e_number ,lexer::token::e_string );
|
||||
add_invalid(lexer::token::e_string ,lexer::token::e_number );
|
||||
add_invalid(lexer::token::e_string ,lexer::token::e_colon );
|
||||
add_invalid(lexer::token::e_string ,lexer::token::e_ternary);
|
||||
add_invalid(lexer::token::e_colon ,lexer::token::e_string );
|
||||
add_invalid(lexer::token::e_ternary,lexer::token::e_string );
|
||||
add_invalid(lexer::token::e_assign ,lexer::token::e_string );
|
||||
add_invalid_set1(lexer::token::e_assign );
|
||||
add_invalid_set1(lexer::token::e_shr );
|
||||
add_invalid_set1(lexer::token::e_shl );
|
||||
add_invalid_set1(lexer::token::e_lte );
|
||||
add_invalid_set1(lexer::token::e_ne );
|
||||
add_invalid_set1(lexer::token::e_gte );
|
||||
add_invalid_set1(lexer::token::e_lt );
|
||||
add_invalid_set1(lexer::token::e_gt );
|
||||
add_invalid_set1(lexer::token::e_eq );
|
||||
add_invalid_set1(lexer::token::e_comma );
|
||||
add_invalid_set1(lexer::token::e_add );
|
||||
add_invalid_set1(lexer::token::e_sub );
|
||||
add_invalid_set1(lexer::token::e_div );
|
||||
add_invalid_set1(lexer::token::e_mul );
|
||||
add_invalid_set1(lexer::token::e_mod );
|
||||
add_invalid_set1(lexer::token::e_pow );
|
||||
add_invalid_set1(lexer::token::e_colon );
|
||||
add_invalid_set1(lexer::token::e_ternary);
|
||||
}
|
||||
|
||||
bool result()
|
||||
|
@ -2878,13 +2883,14 @@ namespace exprtk
|
|||
{
|
||||
switch (t)
|
||||
{
|
||||
case lexer::token::e_number : return false;
|
||||
case lexer::token::e_symbol : return false;
|
||||
case lexer::token::e_string : return false;
|
||||
case lexer::token::e_add : return false;
|
||||
case lexer::token::e_sub : return false;
|
||||
case lexer::token::e_colon : return false;
|
||||
default : return true;
|
||||
case lexer::token::e_number : return false;
|
||||
case lexer::token::e_symbol : return false;
|
||||
case lexer::token::e_string : return false;
|
||||
case lexer::token::e_add : return false;
|
||||
case lexer::token::e_sub : return false;
|
||||
case lexer::token::e_colon : return false;
|
||||
case lexer::token::e_ternary : return false;
|
||||
default : return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2892,12 +2898,13 @@ namespace exprtk
|
|||
{
|
||||
switch (base)
|
||||
{
|
||||
case lexer::token::e_number : return false;
|
||||
case lexer::token::e_symbol : return false;
|
||||
case lexer::token::e_string : return false;
|
||||
case lexer::token::e_eof : return false;
|
||||
case lexer::token::e_colon : return false;
|
||||
default : return true;
|
||||
case lexer::token::e_number : return false;
|
||||
case lexer::token::e_symbol : return false;
|
||||
case lexer::token::e_string : return false;
|
||||
case lexer::token::e_eof : return false;
|
||||
case lexer::token::e_colon : return false;
|
||||
case lexer::token::e_ternary : return false;
|
||||
default : return true;
|
||||
}
|
||||
}
|
||||
else if (details::is_left_bracket(static_cast<char>(t)))
|
||||
|
@ -10776,7 +10783,13 @@ namespace exprtk
|
|||
return error_node();
|
||||
}
|
||||
else
|
||||
{
|
||||
expression = new_expression;
|
||||
if (token_is(token_t::e_ternary,false) && (precedence == e_level00))
|
||||
{
|
||||
expression = parse_ternary_conditional_statement(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return expression;
|
||||
|
@ -11071,6 +11084,8 @@ namespace exprtk
|
|||
expression_node_ptr consequent = error_node();
|
||||
expression_node_ptr alternative = error_node();
|
||||
|
||||
bool result = true;
|
||||
|
||||
next_token();
|
||||
|
||||
if (!token_is(token_t::e_lbracket))
|
||||
|
@ -11095,7 +11110,7 @@ namespace exprtk
|
|||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR19 - Expected ',' between if-statement condition and consequent"));
|
||||
return error_node();
|
||||
result = false;
|
||||
}
|
||||
else if (0 == (consequent = parse_expression()))
|
||||
{
|
||||
|
@ -11103,7 +11118,7 @@ namespace exprtk
|
|||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR20 - Failed to parse consequent for if-statement"));
|
||||
return error_node();
|
||||
result = false;
|
||||
}
|
||||
else if (!token_is(token_t::e_comma))
|
||||
{
|
||||
|
@ -11111,8 +11126,7 @@ namespace exprtk
|
|||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR21 - Expected ',' between if-statement consequent and alternative"));
|
||||
|
||||
return error_node();
|
||||
result = false;
|
||||
}
|
||||
else if (0 == (alternative = parse_expression()))
|
||||
{
|
||||
|
@ -11120,7 +11134,7 @@ namespace exprtk
|
|||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR22 - Failed to parse alternative for if-statement"));
|
||||
return error_node();
|
||||
result = false;
|
||||
}
|
||||
else if (!token_is(token_t::e_rbracket))
|
||||
{
|
||||
|
@ -11128,6 +11142,74 @@ namespace exprtk
|
|||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR23 - Expected ')' at end of if-statement"));
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
free_node(node_allocator_,condition );
|
||||
free_node(node_allocator_,consequent );
|
||||
free_node(node_allocator_,alternative);
|
||||
return error_node();
|
||||
}
|
||||
else
|
||||
return expression_generator_.conditional(condition,consequent,alternative);
|
||||
}
|
||||
|
||||
inline expression_node_ptr parse_ternary_conditional_statement(expression_node_ptr condition)
|
||||
{
|
||||
// Parse: [condition][?][consequent][:][alternative]
|
||||
expression_node_ptr consequent = error_node();
|
||||
expression_node_ptr alternative = error_node();
|
||||
|
||||
bool result = true;
|
||||
|
||||
if (0 == condition)
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR24 - Encountered invalid condition branch for ternary if-statement"));
|
||||
return error_node();
|
||||
}
|
||||
else if (!token_is(token_t::e_ternary))
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR25 - Expected '?' after condition of ternary if-statement"));
|
||||
result = false;
|
||||
}
|
||||
else if (0 == (consequent = parse_expression()))
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR26 - Failed to parse consequent for if-statement"));
|
||||
result = false;
|
||||
}
|
||||
else if (!token_is(token_t::e_colon))
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR27 - Expected ':' between ternary if-statement consequent and alternative"));
|
||||
result = false;
|
||||
}
|
||||
else if (0 == (alternative = parse_expression()))
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR28 - Failed to parse alternative for if-statement"));
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
free_node(node_allocator_,condition );
|
||||
free_node(node_allocator_,consequent );
|
||||
free_node(node_allocator_,alternative);
|
||||
return error_node();
|
||||
}
|
||||
else
|
||||
|
@ -11139,13 +11221,15 @@ namespace exprtk
|
|||
// Parse: [while][(][test expr][)][{][expression][}]
|
||||
expression_node_ptr condition = error_node();
|
||||
expression_node_ptr branch = error_node();
|
||||
|
||||
next_token();
|
||||
|
||||
if (!token_is(token_t::e_lbracket))
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR24 - Expected '(' at start of while-statement condition"));
|
||||
"ERR29 - Expected '(' at start of while-statement condition"));
|
||||
return error_node();
|
||||
}
|
||||
else if (0 == (condition = parse_expression()))
|
||||
|
@ -11153,7 +11237,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR25 - Failed to parse condition for while-loop"));
|
||||
"ERR30 - Failed to parse condition for while-loop"));
|
||||
return error_node();
|
||||
}
|
||||
else if (!token_is(token_t::e_rbracket))
|
||||
|
@ -11161,7 +11245,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR26 - Expected ')' at end of while-statement condition"));
|
||||
"ERR31 - Expected ')' at end of while-statement condition"));
|
||||
return error_node();
|
||||
}
|
||||
if (0 == (branch = parse_multi_sequence("while-loop")))
|
||||
|
@ -11169,7 +11253,8 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR27 - Failed to parse body of while-loop"));
|
||||
"ERR32 - Failed to parse body of while-loop"));
|
||||
free_node(node_allocator_,condition);
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11179,7 +11264,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR28 - Failed to synthesize while-loop"));
|
||||
"ERR33 - Failed to synthesize while-loop"));
|
||||
return error_node();
|
||||
}
|
||||
else
|
||||
|
@ -11217,7 +11302,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR29 - Expected '" + token_t::to_str(seperator) +"' for body of repeat until loop"));
|
||||
"ERR34 - Expected '" + token_t::to_str(seperator) +"' for body of repeat until loop"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11237,7 +11322,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR30 - Failed to parse body of repeat until loop"));
|
||||
"ERR35 - Failed to parse body of repeat until loop"));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
|
@ -11247,7 +11332,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR31 - Expected '(' before condition of repeat until loop"));
|
||||
"ERR36 - Expected '(' before condition of repeat until loop"));
|
||||
return error_node();
|
||||
}
|
||||
else if (0 == (condition = parse_expression()))
|
||||
|
@ -11255,7 +11340,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR32 - Failed to parse condition for repeat until loop"));
|
||||
"ERR37 - Failed to parse condition for repeat until loop"));
|
||||
return error_node();
|
||||
}
|
||||
else if (!token_is(token_t::e_rbracket))
|
||||
|
@ -11263,7 +11348,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR33 - Expected ')' after condition of repeat until loop"));
|
||||
"ERR38 - Expected ')' after condition of repeat until loop"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11273,7 +11358,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR34 - Failed to synthesize repeat until loop"));
|
||||
"ERR39 - Failed to synthesize repeat until loop"));
|
||||
return error_node();
|
||||
}
|
||||
else
|
||||
|
@ -11292,7 +11377,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR35 - Expected keyword 'switch'"));
|
||||
"ERR40 - Expected keyword 'switch'"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11305,7 +11390,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR36 - Expected '{' for call to switch statement"));
|
||||
"ERR41 - Expected '{' for call to switch statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11316,7 +11401,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR37 - Expected either a 'case' or 'default' statement"));
|
||||
"ERR42 - Expected either a 'case' or 'default' statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11331,7 +11416,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR38 - Expected ':' for case of switch statement"));
|
||||
"ERR43 - Expected ':' for case of switch statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11344,7 +11429,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR39 - Expected ';' at end of case for switch statement"));
|
||||
"ERR44 - Expected ';' at end of case for switch statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11370,7 +11455,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR40 - Expected ':' for default of switch statement"));
|
||||
"ERR45 - Expected ':' for default of switch statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11382,7 +11467,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR41 - Expected ';' at end of default for switch statement"));
|
||||
"ERR46 - Expected ';' at end of default for switch statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11396,7 +11481,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR42 - Expected '}' at end of switch statement"));
|
||||
"ERR47 - Expected '}' at end of switch statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11418,7 +11503,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR43 - Expected token '[*]'"));
|
||||
"ERR48 - Expected token '[*]'"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11431,7 +11516,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR44 - Expected '{' for call to [*] statement"));
|
||||
"ERR49 - Expected '{' for call to [*] statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11442,7 +11527,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR45 - Expected a 'case' statement for multi-switch."));
|
||||
"ERR50 - Expected a 'case' statement for multi-switch."));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11457,7 +11542,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR46 - Expected ':' for case of [*] statement"));
|
||||
"ERR51 - Expected ':' for case of [*] statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11470,7 +11555,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR47 - Expected ';' at end of case for [*] statement"));
|
||||
"ERR52 - Expected ';' at end of case for [*] statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11499,7 +11584,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR48 - Expected '}' at end of [*] statement"));
|
||||
"ERR53 - Expected '}' at end of [*] statement"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11538,7 +11623,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR49 - Unsupported vararg function: " + symbol));
|
||||
"ERR54 - Unsupported vararg function: " + symbol));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11550,7 +11635,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR50 - Expected '(' for call to vararg function: " + symbol));
|
||||
"ERR55 - Expected '(' for call to vararg function: " + symbol));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11569,7 +11654,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR51 - Expected ',' for call to vararg function: " + symbol));
|
||||
"ERR56 - Expected ',' for call to vararg function: " + symbol));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
|
@ -11626,7 +11711,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR52 - Expected '"+ details::to_str(close_bracket) + "' for call to multi-sequence" +
|
||||
"ERR57 - Expected '"+ details::to_str(close_bracket) + "' for call to multi-sequence" +
|
||||
((!source.empty()) ? std::string(" section of " + source): "")));
|
||||
return error_node();
|
||||
}
|
||||
|
@ -11654,7 +11739,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR53 - Expected '"+ details::to_str(seperator) +"' for call to multi-sequence section of " + source));
|
||||
"ERR58 - Expected '"+ details::to_str(seperator) +"' for call to multi-sequence section of " + source));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11780,7 +11865,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR54 - Expected '[' for start of range"));
|
||||
"ERR59 - Expected '[' for start of range"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -11798,7 +11883,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR55 - Failed parse begin section of range"));
|
||||
"ERR60 - Failed parse begin section of range"));
|
||||
return false;
|
||||
|
||||
}
|
||||
|
@ -11816,7 +11901,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR56 - Range lower bound less than zero! Constraint: r0 >= 0"));
|
||||
"ERR61 - Range lower bound less than zero! Constraint: r0 >= 0"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -11831,7 +11916,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR57 - Expected ':' for break in range"));
|
||||
"ERR62 - Expected ':' for break in range"));
|
||||
rp.free();
|
||||
return false;
|
||||
}
|
||||
|
@ -11851,7 +11936,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR58 - Failed parse end section of range"));
|
||||
"ERR63 - Failed parse end section of range"));
|
||||
rp.free();
|
||||
return false;
|
||||
|
||||
|
@ -11870,7 +11955,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR59 - Range upper bound less than zero! Constraint: r1 >= 0"));
|
||||
"ERR64 - Range upper bound less than zero! Constraint: r1 >= 0"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -11885,7 +11970,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR60 - Expected ']' for start of range"));
|
||||
"ERR65 - Expected ']' for start of range"));
|
||||
rp.free();
|
||||
return false;
|
||||
}
|
||||
|
@ -11901,7 +11986,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR61 - Invalid range, Constraint: r0 <= r1"));
|
||||
"ERR66 - Invalid range, Constraint: r0 <= r1"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -11926,7 +12011,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR62 - Unknown string symbol"));
|
||||
"ERR67 - Unknown string symbol"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -11987,7 +12072,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR63 - Overflow in range for string: '" + const_str + "'[" +
|
||||
"ERR68 - Overflow in range for string: '" + const_str + "'[" +
|
||||
(rp.n0_c.first ? details::to_str(rp.n0_c.second) : "?") + ":" +
|
||||
(rp.n1_c.first ? details::to_str(rp.n1_c.second) : "?") + "]"));
|
||||
return error_node();
|
||||
|
@ -12016,7 +12101,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR64 - Expected '(' for call to vararg function: " + vararg_function_name));
|
||||
"ERR69 - Expected '(' for call to vararg function: " + vararg_function_name));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -12037,7 +12122,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR65 - Expected ',' for call to vararg function: " + vararg_function_name));
|
||||
"ERR70 - Expected ',' for call to vararg function: " + vararg_function_name));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
|
@ -12066,7 +12151,7 @@ namespace exprtk
|
|||
p.set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
p.current_token(),
|
||||
"ERR66 - Expected '(' for special function"));
|
||||
"ERR71 - Expected '(' for special function"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -12084,7 +12169,7 @@ namespace exprtk
|
|||
p.set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
p.current_token(),
|
||||
"ERR67 - Expected ',' before next parameter of special function"));
|
||||
"ERR72 - Expected ',' before next parameter of special function"));
|
||||
return p.error_node();
|
||||
}
|
||||
}
|
||||
|
@ -12110,7 +12195,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_token,
|
||||
current_token_,
|
||||
"ERR68 - Invalid special function[1]: " + current_token_.value));
|
||||
"ERR73 - Invalid special function[1]: " + current_token_.value));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -12121,7 +12206,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_token,
|
||||
current_token_,
|
||||
"ERR69 - Invalid special function[2]: " + current_token_.value));
|
||||
"ERR74 - Invalid special function[2]: " + current_token_.value));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -12200,7 +12285,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR70 - Invalid number of parameters for function: " + symbol));
|
||||
"ERR75 - Invalid number of parameters for function: " + symbol));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
|
@ -12212,7 +12297,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR71 - Failed to generate node for function: '" + symbol + "'"));
|
||||
"ERR76 - Failed to generate node for function: '" + symbol + "'"));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
|
@ -12232,7 +12317,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR72 - Failed to generate node for vararg function: '" + symbol + "'"));
|
||||
"ERR77 - Failed to generate node for vararg function: '" + symbol + "'"));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
|
@ -12276,7 +12361,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_symtab,
|
||||
current_token_,
|
||||
"ERR73 - Failed to create variable: '" + symbol + "'"));
|
||||
"ERR78 - Failed to create variable: '" + symbol + "'"));
|
||||
|
||||
return error_node();
|
||||
}
|
||||
|
@ -12285,7 +12370,7 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR74 - Undefined variable or function: '" + symbol + "'"));
|
||||
"ERR79 - Undefined variable or function: '" + symbol + "'"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
|
@ -12338,13 +12423,15 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_symtab,
|
||||
current_token_,
|
||||
"ERR75 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token_.value));
|
||||
"ERR80 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token_.value));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
|
||||
inline expression_node_ptr parse_branch(precedence_level precedence = e_level00)
|
||||
{
|
||||
expression_node_ptr branch = error_node();
|
||||
|
||||
if (token_t::e_number == current_token_.type)
|
||||
{
|
||||
T numeric_value = T(0);
|
||||
|
@ -12353,100 +12440,89 @@ namespace exprtk
|
|||
{
|
||||
expression_node_ptr literal_exp = expression_generator_(numeric_value);
|
||||
next_token();
|
||||
return literal_exp;
|
||||
branch = literal_exp;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_numeric,
|
||||
current_token_,
|
||||
"ERR76 - Failed to convert '" + current_token_.value + "' to a number."));
|
||||
"ERR81 - Failed to convert '" + current_token_.value + "' to a number."));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
else if (token_t::e_symbol == current_token_.type)
|
||||
{
|
||||
return parse_symbol();
|
||||
branch = parse_symbol();
|
||||
}
|
||||
#ifndef exprtk_disable_string_capabilities
|
||||
else if (token_t::e_string == current_token_.type)
|
||||
{
|
||||
return parse_const_string();
|
||||
branch = parse_const_string();
|
||||
}
|
||||
#endif
|
||||
else if (token_t::e_lbracket == current_token_.type)
|
||||
{
|
||||
next_token();
|
||||
expression_node_ptr branch = parse_expression();
|
||||
if (0 == branch)
|
||||
if (0 == (branch = parse_expression()))
|
||||
return error_node();
|
||||
else if (token_is(token_t::e_rbracket))
|
||||
return branch;
|
||||
else
|
||||
else if (!token_is(token_t::e_rbracket))
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR77 - Expected ')' instead of: '" + current_token_.value + "'"));
|
||||
"ERR82 - Expected ')' instead of: '" + current_token_.value + "'"));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
else if (token_t::e_lsqrbracket == current_token_.type)
|
||||
{
|
||||
next_token();
|
||||
expression_node_ptr branch = parse_expression();
|
||||
|
||||
if (0 == branch)
|
||||
if (0 == (branch = parse_expression()))
|
||||
return error_node();
|
||||
else if (token_is(token_t::e_rsqrbracket))
|
||||
return branch;
|
||||
else
|
||||
else if (!token_is(token_t::e_rsqrbracket))
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR78 - Expected ']' instead of: '" + current_token_.value + "'"));
|
||||
"ERR83 - Expected ']' instead of: '" + current_token_.value + "'"));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
else if (token_t::e_lcrlbracket == current_token_.type)
|
||||
{
|
||||
next_token();
|
||||
expression_node_ptr branch = parse_expression();
|
||||
|
||||
if (0 == branch)
|
||||
if (0 == (branch = parse_expression()))
|
||||
return error_node();
|
||||
else if (token_is(token_t::e_rcrlbracket))
|
||||
return branch;
|
||||
else
|
||||
else if (!token_is(token_t::e_rcrlbracket))
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR79 - Expected '}' instead of: '" + current_token_.value + "'"));
|
||||
"ERR84 - Expected '}' instead of: '" + current_token_.value + "'"));
|
||||
return error_node();
|
||||
}
|
||||
}
|
||||
else if (token_t::e_sub == current_token_.type)
|
||||
{
|
||||
next_token();
|
||||
return expression_generator_(details::e_neg,
|
||||
// Was the previous operation exponentiation?
|
||||
(e_level12 == precedence) ?
|
||||
parse_branch (e_level09) :
|
||||
parse_expression(e_level09));
|
||||
branch = expression_generator_(details::e_neg,
|
||||
// Was the previous operation exponentiation?
|
||||
(e_level12 == precedence) ?
|
||||
parse_branch (e_level09) :
|
||||
parse_expression(e_level09));
|
||||
}
|
||||
else if (token_t::e_add == current_token_.type)
|
||||
{
|
||||
next_token();
|
||||
return parse_expression(e_level13);
|
||||
branch = parse_expression(e_level13);
|
||||
}
|
||||
else if (token_t::e_eof == current_token_.type)
|
||||
{
|
||||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR80 - Premature end of expression[1]"));
|
||||
"ERR85 - Premature end of expression[1]"));
|
||||
return error_node();
|
||||
}
|
||||
else
|
||||
|
@ -12454,9 +12530,20 @@ namespace exprtk
|
|||
set_error(
|
||||
make_error(parser_error::e_syntax,
|
||||
current_token_,
|
||||
"ERR81 - Premature end of expression[2]"));
|
||||
"ERR86 - Premature end of expression[2]"));
|
||||
return error_node();
|
||||
}
|
||||
|
||||
if (
|
||||
branch &&
|
||||
(e_level00 == precedence) &&
|
||||
token_is(token_t::e_ternary,false)
|
||||
)
|
||||
{
|
||||
branch = parse_ternary_conditional_statement(branch);
|
||||
}
|
||||
|
||||
return branch;
|
||||
}
|
||||
|
||||
inline bool token_is(const typename token_t::token_type& ttype, const bool advance_token = true)
|
||||
|
|
|
@ -1006,7 +1006,29 @@ static const test_t test_list[] =
|
|||
test_t("repeat 1.1234; 1 < 2; (1.1 + 2.2) until (1 < 2)",3.3),
|
||||
test_t("repeat 1.1234; 1 < 2; 1.1 + 2.2; until (1 < 2)",3.3),
|
||||
test_t("repeat 1.1234; 1 < 2; (1.1 + 2.2); until (1 < 2)",3.3),
|
||||
test_t("[*] { case 1 < 2 : 1 / 2; case (1 < 3) : 2 / 2; case 1 < 4 : 3 / 2; case (1 < 5) : 4 / 2; }",2.0)
|
||||
test_t("[*] { case 1 < 2 : 1 / 2; case (1 < 3) : 2 / 2; case 1 < 4 : 3 / 2; case (1 < 5) : 4 / 2; }",2.0),
|
||||
test_t(" 0 ? 1 : 2",2.0),
|
||||
test_t(" 1 ? 3 : 4",3.0),
|
||||
test_t("(0 ? 1 : 2) == 2",1.0),
|
||||
test_t("(1 ? 3 : 4) == 3",1.0),
|
||||
test_t("[(0)] ? [(1)] : [(2)]",2.0),
|
||||
test_t("([(0)] ? [(1)] : [(2)]) == 2",1.0),
|
||||
test_t("([(1)] ? [(3)] : [(4)]) == 3",1.0),
|
||||
test_t("(1 < 2 ? 3 : 4) == 3",1.0),
|
||||
test_t("(1 > 2 ? 3 : 4) == 4",1.0),
|
||||
test_t("(1 < 2 ? 3 + 5 : 4) == 8",1.0),
|
||||
test_t("(1 > 2 ? 3 : 4 + 5) == 9",1.0),
|
||||
test_t("(2 < 3 + 3 ? 7 : 9) == 7",1.0),
|
||||
test_t("(1 + 1 < 3 ? 7 : 9) == 7",1.0),
|
||||
test_t("(1 + 1 < 3 + 3 ? 7 : 9) == 7",1.0),
|
||||
test_t("(2 > 3 + 3 ? 7 : 9) == 9",1.0),
|
||||
test_t("(1 + 1 > 3 ? 7 : 9) == 9",1.0),
|
||||
test_t("(1 + 1 > 3 + 3 ? 7 : 9) == 9",1.0),
|
||||
test_t("(2 < (3 + 3) ? 7 : 9) == 7",1.0),
|
||||
test_t("((1 + 1) < 3 ? 7 : 9) == 7",1.0),
|
||||
test_t("((1 + 1) < (3 + 3) ? 7 : 9) == 7",1.0),
|
||||
test_t("(min(1,2) ? 1 + 3 : 1 + 4) == 4",1.0),
|
||||
test_t("(min(0,1) ? 1 + 3 : 1 + 4) == 5",1.0)
|
||||
};
|
||||
|
||||
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_t);
|
||||
|
@ -1109,13 +1131,17 @@ inline bool run_test00()
|
|||
const std::size_t rounds = 10;
|
||||
for (std::size_t r = 0; r < rounds; ++r)
|
||||
{
|
||||
bool result = true;
|
||||
for (std::size_t i = 0; i < test_list_size; ++i)
|
||||
{
|
||||
if (!test_expression<T>(test_list[i].first,T(test_list[i].second)))
|
||||
{
|
||||
return false;
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1442,7 +1468,23 @@ inline bool run_test01()
|
|||
test_xy<T>("switch { case {(x <= y)} : switch { case ({x <= y}) : x; default: 1.12345; }; default: 1.12345; }",T(1.0),T(2.0),T(1.0)),
|
||||
test_xy<T>("[*]{ case x < y : x + y; case y < x : y - x; }",T(2.0),T(3.0),T(5.0)),
|
||||
test_xy<T>("[*]{ case x > y : x + y; case y > x : y - x; }",T(2.0),T(3.0),T(1.0)),
|
||||
test_xy<T>("[*]{ case x > y : x - y; case y < x : y + x; }",T(2.0),T(3.0),T(0.0))
|
||||
test_xy<T>("[*]{ case x > y : x - y; case y < x : y + x; }",T(2.0),T(3.0),T(0.0)),
|
||||
test_xy<T>("0 ? x : y" ,T(1.0),T(2.0),T( 2.0)),
|
||||
test_xy<T>("1 ? x : y" ,T(1.0),T(2.0),T( 1.0)),
|
||||
test_xy<T>("x ? x : y" ,T(1.0),T(2.0),T( 1.0)),
|
||||
test_xy<T>("x ? x : y" ,T(0.0),T(2.0),T( 2.0)),
|
||||
test_xy<T>("(x + y < 4) ? 1 : 2" ,T(1.0),T(2.0),T( 1.0)),
|
||||
test_xy<T>("(x + y > 4) ? 1 : 2" ,T(1.0),T(2.0),T( 2.0)),
|
||||
test_xy<T>("x < y ? x + y : x - y" ,T(1.0),T(2.0),T( 3.0)),
|
||||
test_xy<T>("x > y ? x + y : x - y" ,T(1.0),T(2.0),T(-1.0)),
|
||||
test_xy<T>("(x + x < y ? 7 : 9) == 7" ,T(1.0),T(3.0),T( 1.0)),
|
||||
test_xy<T>("(x + x < y + y ? 7 : 9) == 7" ,T(1.0),T(3.0),T( 1.0)),
|
||||
test_xy<T>("(x > y + y ? 7 : 9) == 9" ,T(1.0),T(3.0),T( 1.0)),
|
||||
test_xy<T>("(x + x > y ? 7 : 9) == 9" ,T(1.0),T(3.0),T( 1.0)),
|
||||
test_xy<T>("(x + x > y + 3 ? 7 : 9) == 9" ,T(1.0),T(3.0),T( 1.0)),
|
||||
test_xy<T>("(x < (y + y) ? 7 : 9) == 7" ,T(1.0),T(3.0),T( 1.0)),
|
||||
test_xy<T>("((x + x) < y ? 7 : 9) == 7" ,T(1.0),T(3.0),T( 1.0)),
|
||||
test_xy<T>("((x + x) < (y + y) ? 7 : 9) == 7",T(1.0),T(3.0),T( 1.0)),
|
||||
};
|
||||
|
||||
static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_xy<T>);
|
||||
|
@ -2391,6 +2433,13 @@ inline bool run_test08()
|
|||
"equal($f96(x,y,z,w),if(x > y,z,w))",
|
||||
"equal($f97(x,y,z,w),if(x >= y,z,w))",
|
||||
"equal($f98(x,y,z,w),if(equal(x,y),z,w))",
|
||||
"equal($f92(x,y,z,w),x and y ? z : w)",
|
||||
"equal($f93(x,y,z,w),x or y ? z : w)",
|
||||
"equal($f94(x,y,z,w),x < y ? z : w)",
|
||||
"equal($f95(x,y,z,w),x <= y ? z : w)",
|
||||
"equal($f96(x,y,z,w),x > y ? z : w)",
|
||||
"equal($f97(x,y,z,w),x >= y ? z : w)",
|
||||
"equal($f98(x,y,z,w),equal(x,y) ? z : w)",
|
||||
"equal($f99(x,y,z,w),x*sin(y)+z*cos(w))"
|
||||
};
|
||||
static const std::size_t expr_str_size = sizeof(expr_str) / sizeof(std::string);
|
||||
|
|
63
readme.txt
63
readme.txt
|
@ -32,7 +32,8 @@ arithmetic operations, functions and processes:
|
|||
|
||||
(5) Conditional,
|
||||
Switch &
|
||||
Loop statements: if-then-else, switch-case, while, repeat-until
|
||||
Loop statements: if-then-else, ternary conditional, switch-case,
|
||||
while, repeat-until
|
||||
|
||||
(6) Assignment: :=
|
||||
|
||||
|
@ -64,7 +65,7 @@ expressions that can be parsed and evaluated using the ExprTk library.
|
|||
(13) (x + y)z + 1.1 / 2.7 == (x + y) * z + 1.1 / 2.7
|
||||
(14) (sin(x / pi) cos(2y) + 1) == (sin(x / pi) * cos(2 * y) + 1)
|
||||
(15) 75x^17 + 25.1x^5 - 35x^4 - 15.2x^3 + 40x^2 - 15.3x + 1
|
||||
(16) if (avg(x,y) <= x + y, x - y, x * y) + 2.345 * pi / x
|
||||
(16) (avg(x,y) <= x + y ? x - y : x * y) + 2.345 * pi / x
|
||||
(17) fib_i := fib_i + (x := y + 0 * (fib_i := x + (y := fib_i)))
|
||||
(18) while (x <= 100) { x := x + 1 }
|
||||
(19) x <= 'abc123' and (y in 'AString') or ('1x2y3z' != z)
|
||||
|
@ -406,6 +407,13 @@ include path (e.g: /usr/include/).
|
|||
| | w := z + y; |
|
||||
| | until ((x := (x - 1)) <= 0) |
|
||||
+----------+---------------------------------------------------------+
|
||||
| ?: | Ternary conditional statement, similar to that of the |
|
||||
| | above denoted if-statement. |
|
||||
| | eg: |
|
||||
| | 0. x ? y : z |
|
||||
| | 1. x + 1 > 2y ? z + 1 : (w / v) |
|
||||
| | 2. min(x,y) > z ? (x < y + 1) ? x : y : (w * v) |
|
||||
+----------+---------------------------------------------------------+
|
||||
| ~ | Evaluate each sub-expression, then return as the result |
|
||||
| | the value of the last sub-expression. This is sometimes |
|
||||
| | known as multiple sequence point evaluation. |
|
||||
|
@ -459,6 +467,46 @@ types a symbol table can handle:
|
|||
(e) Functions
|
||||
(f) Vararg functions
|
||||
|
||||
During the compilation process if an expression is found to require
|
||||
any of the elements noted above, the expression's associated
|
||||
symbol_table will be queried for the element and if present a
|
||||
reference to the element will be embedded within the expression's AST.
|
||||
This allows for the original element to be modified independently of
|
||||
the expression instance and to also allow the expression to be
|
||||
evaluated using the current value of the element.
|
||||
|
||||
The example below demonstrates the relationship between variables,
|
||||
symbol_table and expression. Note the variables are modified as they
|
||||
normally would in a program, and when the expression is evaluated the
|
||||
current values assigned to the variables will be used.
|
||||
|
||||
typedef exprtk::symbol_table<double> symbol_table_t;
|
||||
typedef exprtk::expression<double> expression_t;
|
||||
typedef exprtk::parser<double> parser_t;
|
||||
|
||||
symbol_table_t symbol_table;
|
||||
expression_t expression;
|
||||
parser_t parser;
|
||||
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
|
||||
std::string expression_string = "x * y + 3";
|
||||
symbol_table.add_variable("x",x);
|
||||
symbol_table.add_variable("y",y);
|
||||
|
||||
expression.register_symbol_table(symbol_table);
|
||||
|
||||
parser.compile(expression_string,expression);
|
||||
|
||||
x = 1.0;
|
||||
y = 2.0;
|
||||
parser.value(); // 1 * 2 + 3
|
||||
x = 3.7;
|
||||
parser.value(); // 3.7 * 2 + 3
|
||||
y = -9.0;
|
||||
parser.value(); // 3.7 * -9 + 3
|
||||
|
||||
|
||||
(2) Expression
|
||||
A structure that holds an AST for a specified expression and is used
|
||||
|
@ -474,21 +522,21 @@ Expression: z := (x + y^-2.345) * sin(pi / min(w - 7.3,v))
|
|||
[Assignment]
|
||||
________/ \_____
|
||||
/ \
|
||||
Variable(z) [Multiply]
|
||||
Variable(z) [Multiplication]
|
||||
____________/ \___________
|
||||
/ \
|
||||
/ [Unary-Func(sin)]
|
||||
[Addition] |
|
||||
____/ \____ [Division]
|
||||
/ \ ___/ \___
|
||||
Variable(x) [Power] / \
|
||||
Variable(x) [Exponentiation] / \
|
||||
______/ \______ Constant(pi) [Binary-Func(min)]
|
||||
/ \ ____/ \____
|
||||
Variable(y) [Negate] / \
|
||||
Variable(y) [Negation] / \
|
||||
| / Variable(v)
|
||||
Constant(2.345) /
|
||||
/
|
||||
[Subtract]
|
||||
[Subtraction]
|
||||
____/ \____
|
||||
/ \
|
||||
Variable(w) Constant(7.3)
|
||||
|
@ -809,7 +857,8 @@ int main()
|
|||
typedef exprtk::parser<double> parser_t;
|
||||
typedef exprtk::parser_error::type error_t;
|
||||
|
||||
std::string expression_str = "z := 2 myfunc([4+sin(x/pi)^3],y^2)";
|
||||
std::string expression_str =
|
||||
"z := 2 myfunc([4 + sin(x / pi)^3],y ^ 2)";
|
||||
|
||||
double x = 1.1;
|
||||
double y = 2.2;
|
||||
|
|
Loading…
Reference in New Issue