admin管理员组文章数量:1279209
I would like to integrate ExprTk into a C++ (open source) home automation application I am building.
I have a list of values that can change dynamically, for example a switch position (BOOL) or a temperature value (double) and I would like to be able to evaluate an expression using those values.
I already keep my own symbol table of variables? many of them are recomputed in real time.
for example I would like to evaluate
"OUTSIDE_TEMP > 60" or something like "TODAY_MINS > 3600 && RELAY_1 == TRUE"
do I need to specify all the variable names each time I run the parserpile() or can I have the values looked up and then evaluated at expression.value() time?
what is considered the canonical way to do this? should I create a LOOKUP function and pass the variable name in as a string? ie "LOOKUP("OUTSIDE_TEMP") > 60" ?
I also thought about running the parser without defining any symbols and making a list of needed symbols from the error? I am not sure if that buys me anything, because an unclear if I can serialize the ExprTk context for later?
many thanks
This works, but I'd rather not have to specify all the variables each time.. can I save the context?
void test1() {
using T = double;
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
symbol_table_t immutable_symbol_table( symbol_table_t::symtab_mutability_type::e_immutable);
double outside_temp = -4;
immutable_symbol_table.add_variable("OUTSIDE_TEMP" , outside_temp );
expression_t expression;
expression.register_symbol_table(immutable_symbol_table);
parser_t parser;
if (!parserpile("OUTSIDE_TEMP > 60.0", expression))
{
cout << "Error: " << parser.error() << endl;
}
else
{
outside_temp = 99.0;
cout << expression.value() <<endl;
}
}
I would like to integrate ExprTk into a C++ (open source) home automation application I am building.
I have a list of values that can change dynamically, for example a switch position (BOOL) or a temperature value (double) and I would like to be able to evaluate an expression using those values.
I already keep my own symbol table of variables? many of them are recomputed in real time.
for example I would like to evaluate
"OUTSIDE_TEMP > 60" or something like "TODAY_MINS > 3600 && RELAY_1 == TRUE"
do I need to specify all the variable names each time I run the parserpile() or can I have the values looked up and then evaluated at expression.value() time?
what is considered the canonical way to do this? should I create a LOOKUP function and pass the variable name in as a string? ie "LOOKUP("OUTSIDE_TEMP") > 60" ?
I also thought about running the parser without defining any symbols and making a list of needed symbols from the error? I am not sure if that buys me anything, because an unclear if I can serialize the ExprTk context for later?
many thanks
This works, but I'd rather not have to specify all the variables each time.. can I save the context?
void test1() {
using T = double;
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
symbol_table_t immutable_symbol_table( symbol_table_t::symtab_mutability_type::e_immutable);
double outside_temp = -4;
immutable_symbol_table.add_variable("OUTSIDE_TEMP" , outside_temp );
expression_t expression;
expression.register_symbol_table(immutable_symbol_table);
parser_t parser;
if (!parserpile("OUTSIDE_TEMP > 60.0", expression))
{
cout << "Error: " << parser.error() << endl;
}
else
{
outside_temp = 99.0;
cout << expression.value() <<endl;
}
}
Share
Improve this question
asked Feb 24 at 5:01
vinthewrenchvinthewrench
111 silver badge4 bronze badges
4
|
2 Answers
Reset to default 2Initially, ExprTk is a Parse Once Evaluate Many times math engine.
Meaning once you have registered your variables with a symbol table instance and that symbol table instance is registered to an expression instance which is then used to compile a string form of an expression. Then all you need to do is update the variables used in the expression as you'd normally do in code, then call the value method of the compiled expression instance. It will ensure that only the current values stored in the variables are used.
I would recommend spending a few minutes browsing the examples, such as exprtk_simple_example01.cpp
:
using T = double;
using symbol_table_t = exprtk::symbol_table<T>;
using expression_t = exprtk::expression<T>;
using parser_t = exprtk::parser<T>;
const std::string expression_string =
"clamp(-1.0, sin(2 * pi * x) + cos(x / 2 * pi), +1.0)";
T x;
symbol_table_t symbol_table;
symbol_table.add_variable("x",x);
symbol_table.add_constants();
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
parserpile(expression_string,expression);
for (x = T(-5); x <= T(+5); x += T(0.001))
{
const T y = expression.value();
printf("%19.15f\t%19.15f\n", x, y);
}
In the above a variable x
of type double
is registered with a symbol table (aka object binding). Then an expression in string form using the variable x is compiled. Later on in the subsequent for loop
, the variable x
is modified as one normally would using C++, after each modification the expression is evaluated and the value returned is printed to stdout
.
All one has to decide is where they are going to store their symbol_table and expression instances, eg: as members of a class or somewhere else etc
It is all very simple, and there is nothing complicated to reason about.
I solved my problem above by using the unknown_symbol_resolver. this allows me to bind new variable names on the fly depending on what the equation asks for.
ExprTk is very powerful, it does take some time to walk through the tests and the documentation to find a working sample of how do do things that the author didn't intend. All and All I am very happy with the results.
本文标签: cI would like to use ExprTk to lookup a dynamic external valueStack Overflow
版权声明:本文标题:c++ - I would like to use ExprTk to lookup a dynamic external value - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741293482a2370681.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
unknown_symbol_resolver
on the parser, but it should resolve to a memory location. – Botje Commented Feb 24 at 20:18