MRPT  2.0.1
CRuntimeCompiledExpression.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "expr-precomp.h" // Precompiled headers
11 
12 #include <mrpt/core/exceptions.h>
15 #include <cmath> // M_PI
16 #include <cstdlib>
17 #include <iostream>
18 
19 #define exprtk_disable_string_capabilities // Workaround a bug in Ubuntu
20 // precise's GCC+libstdc++
21 
22 // Disable some parts of exprtk to build faster and reduce lib size:
23 #define exprtk_disable_enhanced_features
24 #define exprtk_disable_superscalar_unroll
25 #define exprtk_disable_rtl_vecops
26 #define exprtk_disable_rtl_io_file
27 #include <mrpt/3rdparty/exprtk.hpp>
28 
29 using namespace mrpt;
30 using namespace mrpt::expr;
31 
33 {
35  {
37  return obj;
38  }
39  void process(const CRuntimeCompiledExpression& rce, const double ret);
40 
41  private:
43  std::vector<std::string> m_verbose_matches;
45  {
46  const char* sp = ::getenv("MRPT_EXPR_VERBOSE");
47  if (nullptr == sp) return;
48  const std::string s = mrpt::system::trim(std::string(sp));
49 
50  if (s == std::string("1"))
51  {
53  return;
54  }
56  }
57 };
58 
59 // We only need this to be on this translation unit, hence the advantage of
60 // using our MRPT wrapper instead of the original exprtk sources.
62 {
64  std::string m_original_expr_str;
65 };
66 
69 {
70 }
71 
73 
75  /** [in] The expression to be compiled. */
76  const std::string& expression,
77  /** [in] Map of variables/constants by `name` -> `value`. The references to
78  the values in this map **must** be ensured to be valid thoughout all the
79  life of the compiled expression. */
80  const std::map<std::string, double>& variables,
81  /** A descriptive name of this formula, to be used when generating error
82  reports via an exception, if needed */
83  const std::string& expr_name_for_error_reporting)
84 {
85  m_impl->m_original_expr_str = expression;
86 
87  exprtk::symbol_table<double> symbol_table;
88  for (const auto& v : variables)
89  {
90  auto& var = const_cast<double&>(v.second);
91  symbol_table.add_variable(v.first, var);
92  }
93  symbol_table.add_constant("M_PI", M_PI);
94  symbol_table.add_constants();
95 
96  m_impl->m_compiled_formula.register_symbol_table(symbol_table);
97 
98  // Compile user-given expressions:
99  exprtk::parser<double> parser;
100  if (!parser.compile(expression, m_impl->m_compiled_formula))
102  "Error compiling expression (name=`%s`): `%s`. Error: `%s`",
103  expr_name_for_error_reporting.c_str(), expression.c_str(),
104  parser.error().c_str());
105 }
106 
108 {
109  ASSERT_(m_impl);
110  double ret = m_impl->m_compiled_formula.value();
111  ExprVerbose::Instance().process(*this, ret);
112  return ret;
113 }
114 
116  /** [in] Map of variables/constants by `name` -> `value`. The
117  references to the values in this map **must** be ensured to be valid
118  thoughout all the life of the compiled expression. */
119  const std::map<std::string, double*>& variables)
120 {
121  exprtk::symbol_table<double> symbol_table;
122  for (const auto& v : variables)
123  {
124  auto* var = const_cast<double*>(v.second);
125  symbol_table.add_variable(v.first, *var);
126  }
127  m_impl->m_compiled_formula.register_symbol_table(symbol_table);
128 }
129 
131 {
132  ASSERT_(m_impl);
133  return m_impl->m_compiled_formula;
134 }
137 {
138  ASSERT_(m_impl);
139  return m_impl->m_compiled_formula;
140 }
141 
143 {
144  ASSERT_(m_impl);
145  return m_impl->m_compiled_formula;
146 }
148 {
149  return m_impl->m_original_expr_str;
150 }
151 
153  const CRuntimeCompiledExpression& rce, const double ret)
154 {
155  if (!m_verbose_always_enabled && m_verbose_matches.empty()) return;
156 
157  const auto& exp = *rce.m_impl.get();
158 
159  if (!m_verbose_matches.empty())
160  {
161  bool matched = false;
162  for (const auto& s : m_verbose_matches)
163  {
164  if (exp.m_original_expr_str.find(s) != std::string::npos)
165  {
166  matched = true;
167  break;
168  }
169  }
170  if (!matched) return;
171  }
172 
173  std::vector<std::pair<std::string, double>> lst;
174  exp.m_compiled_formula.get_symbol_table().get_variable_list(lst);
175  // clang-format off
176  std::cout << "[CRuntimeCompiledExpression::eval()] DEBUG:\n"
177  "* Expression: "
178  << exp.m_original_expr_str << "\n"
179  "* Final value: " << ret << "\n"
180  "* Using these symbols:\n";
181  // clang-format on
182  for (const auto& v : lst)
183  std::cout << " * " << v.first << " = " << v.second << "\n";
184 }
const std::string & get_original_expression() const
Returns the original formula passed to compile(), or an empty string if still not compiled...
exprtk::expression< double > & get_raw_exprtk_expr()
Access raw exprtk expression object.
A wrapper of exprtk runtime expression compiler: it takes a string representing an expression (from a...
void tokenize(const std::string &inString, const std::string &inDelimiters, OUT_CONTAINER &outTokens, bool skipBlankTokens=true) noexcept
Tokenizes a string according to a set of delimiting characters.
static CRuntimeCompiledExpression::ExprVerbose & Instance()
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
void process(const CRuntimeCompiledExpression &rce, const double ret)
bool is_compiled() const
Returns true if compile() was called and ended without errors.
void register_symbol_table(const std::map< std::string, double *> &variables)
Can be used before calling compile() to register additional variables by means of pointers instead of...
void compile(const std::string &expression, const std::map< std::string, double > &variables=std::map< std::string, double >(), const std::string &expr_name_for_error_reporting=std::string())
Initializes the object by compiling an expression.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double eval() const
Evaluates the current value of the precompiled formula.
std::string trim(const std::string &str)
Removes leading and trailing spaces.
pimpl< T > make_impl(Args &&... args)
Definition: pimpl.h:18
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
Definition: exceptions.h:69



Page generated by Doxygen 1.8.14 for MRPT 2.0.1 Git: 0fef1a6d7 Fri Apr 3 23:00:21 2020 +0200 at vie abr 3 23:20:28 CEST 2020