1 #ifndef _utl_MathExpressionGrammar_h_
2 #define _utl_MathExpressionGrammar_h_
13 #include <utl/SymbolTable.h>
14 #include <utl/ExpressionParser.h>
15 #include <utl/AugerException.h>
16 #include <utl/ErrorLogger.h>
20 #include <boost/version.hpp>
21 #if BOOST_VERSION >= 103800
22 # define BOOST_SPIRIT_USE_OLD_NAMESPACE
23 # include <boost/spirit/include/classic.hpp>
24 # include <boost/spirit/include/phoenix1_binders.hpp>
25 # include <boost/spirit/include/phoenix1_functions.hpp>
27 # include <boost/spirit.hpp>
28 # include <boost/spirit/phoenix/binders.hpp>
29 # include <boost/spirit/phoenix/primitives.hpp>
30 # include <boost/spirit/phoenix/functions.hpp>
41 #define FIMP_std(name) \
42 struct F_ ## name ## _Impl { \
43 template<typename T1> \
44 struct result { typedef double type; }; \
45 template<typename T1> \
46 T1 operator()(T1& t1) const { return std::name(t1); } \
48 const phoenix::function<F_ ## name ## _Impl> F_ ## name = F_ ## name ## _Impl()
58 template<
typename T1,
typename T2>
60 template<
typename T1,
typename T2>
79 struct SValueClosure :
public boost::spirit::closure<SValueClosure, double> {
84 struct SAssignmentClosure :
public boost::spirit::closure<SAssignmentClosure, std::string, double> {
90 struct SStringClosure :
public boost::spirit::closure<SStringClosure, std::string> {
95 template<
typename ScannerT>
113 |
identifier [
term.value = phoenix::bind(&MathExpressionGrammar::Lookup)(
self, phoenix::arg1)]
117 =( boost::spirit::str_p(
"exp") >>
term [
func.value =
F_exp(phoenix::arg1)]
118 | boost::spirit::str_p(
"log10") >>
term [
func.value =
F_log10(phoenix::arg1)]
119 | boost::spirit::str_p(
"log") >>
term [
func.value =
F_log(phoenix::arg1)]
120 | boost::spirit::str_p(
"sin") >>
term [
func.value =
F_sin(phoenix::arg1)]
121 | boost::spirit::str_p(
"cos") >>
term [
func.value =
F_cos(phoenix::arg1)]
122 | boost::spirit::str_p(
"tan") >>
term [
func.value =
F_tan(phoenix::arg1)]
151 = boost::spirit::lexeme_d [(boost::spirit::alpha_p |
'_')
152 >> *(boost::spirit::alnum_p |
'_')][
153 identifier.name = phoenix::construct_<std::string>(phoenix::arg1, phoenix::arg2)
159 >> (boost::spirit::end_p |
';')
163 = boost::spirit::longest_d[
164 boost::spirit::int_p [
literal.value = phoenix::arg1]
165 | boost::spirit::real_p [
literal.value = phoenix::arg1]
187 boost::spirit::rule<ScannerT, SStringClosure::context_t>
identifier;
197 Lookup(
const std::string& symbol)
201 const auto it1 = symbols.find(symbol);
202 if (
it1 != symbols.end())
213 "The symbol '" + symbol +
"' " +
214 "is not defined during the evaluaion with the MathExpressionGrammer\n";
225 bool HasVariable(
const std::string& name)
const {
return fVariables.count(name); }
226 void SetVariable(
const std::string& name,
const double& v) { fVariables[name] = v; }
227 double GetVariable(
const std::string& name)
const {
return fVariables.find(name)->second; }
232 mutable double* fResult =
nullptr;
238 #include <utl/AugerUnits.h>
const phoenix::function< PowerToImpl2 > power2
boost::spirit::rule< ScannerT > const & start() const
const phoenix::function< F_log_Impl > F_log
boost::spirit::rule< ScannerT, SValueClosure::context_t > expression
void SaveResult(const double val) const
const SymbolTable & GetVariables() const
const phoenix::function< F_exp_Impl > F_exp
boost::spirit::rule< ScannerT, SStringClosure::context_t > identifier
MathExpressionGrammar(double &result, const utl::SymbolTable &sym)
boost::spirit::rule< ScannerT, SValueClosure::context_t > literal
double pow(const double x, const unsigned int i)
boost::spirit::rule< ScannerT, SValueClosure::context_t > func
SymbolTable & GetVariables()
T1 operator()(T1 &t1, T2 &t2) const
Boost spirit definition template (Read Boost Spirit documentation)
boost::spirit::rule< ScannerT, SValueClosure::context_t > factor
throw XMLParseException(err)
const phoenix::function< F_sin_Impl > F_sin
bool HasVariable(const std::string &name) const
std::map< std::string, double > SymbolTable
boost::spirit::rule< ScannerT, SValueClosure::context_t > prefix
definition(const MathExpressionGrammar &self)
utl::ExpressionParser< MathExpressionGrammar, AugerUnits > FunctionParser
boost::spirit::rule< ScannerT > statement
MathExpressionGrammar(double &result, const utl::SymbolTable &sym, utl::SymbolTable &vars)
const SymbolTable * fSymbols
const phoenix::function< F_log10_Impl > F_log10
boost::spirit::rule< ScannerT, SValueClosure::context_t > term
const phoenix::function< F_tan_Impl > F_tan
double GetVariable(const std::string &name) const
int GetNVariables() const
const phoenix::function< F_cos_Impl > F_cos
void SetVariable(const std::string &name, const double &v)
void SetResult(double &v) const
boost::spirit::rule< ScannerT, SValueClosure::context_t > multdiv