17#define BOOST_SPIRIT_QI_DEBUG
20#define _USE_MATH_DEFINES
23#include <boost/fusion/include/adapt_struct.hpp>
24#include <boost/fusion/include/io.hpp>
25#include <boost/phoenix.hpp>
26#include <boost/phoenix/object.hpp>
27#include <boost/spirit/include/qi.hpp>
36namespace qi = boost::spirit::qi;
37namespace ascii = boost::spirit::ascii;
38namespace phx = boost::phoenix;
43 virtual double Eval()
const {
return 0; }
45 Eval(
const std::unordered_map<std::string, double> &variables)
const {
60 return std::make_shared<Expr>(t);
80 double Eval()
const override {
return value; }
82 const std::unordered_map<std::string, double> &variables)
const override {
102 Variable(
const std::string &value =
"") : value(value) {}
109 double Eval()
const override {
return 0; }
111 const std::unordered_map<std::string, double> &variables)
const override {
112 auto it = variables.find(value);
113 if (it != variables.end())
116 throw std::invalid_argument(
"Variable not found: " + value);
137 template <
typename L,
typename R>
139 : op(op), left(
Clone(left)), right(
Clone(right)) {}
144 return left->Eval() + right->Eval();
146 return left->Eval() - right->Eval();
148 return left->Eval() * right->Eval();
150 return left->Eval() / right->Eval();
152 return pow(left->Eval(), right->Eval());
154 throw std::invalid_argument(
"Unknown binary operator");
161 const std::unordered_map<std::string, double> &variables)
const override {
164 return left->Eval(variables) + right->Eval(variables);
166 return left->Eval(variables) - right->Eval(variables);
168 return left->Eval(variables) * right->Eval(variables);
170 return left->Eval(variables) / right->Eval(variables);
172 return pow(left->Eval(variables), right->Eval(variables));
174 throw std::invalid_argument(
"Unknown binary operator");
186 template <
typename,
typename,
typename>
struct result {
190 template <
typename C,
typename L,
typename R>
202 template <
typename R>
208 return right->Eval();
210 return -right->Eval();
212 throw std::invalid_argument(
"Unknown unary operator");
219 const std::unordered_map<std::string, double> &variables)
const override {
222 return right->Eval(variables);
224 return -right->Eval(variables);
226 throw std::invalid_argument(
"Unknown unary operator");
237 template <
typename,
typename>
struct result {
241 template <
typename C,
typename R>
251 template <
typename F>
253 : func(func), param(
Clone(param)) {}
257 return sin(param->Eval());
258 else if (func ==
"cos")
259 return cos(param->Eval());
260 else if (func ==
"tan")
261 return tan(param->Eval());
262 else if (func ==
"exp")
263 return exp(param->Eval());
264 else if (func ==
"ln")
265 return log(param->Eval());
266 else if (func ==
"sqrt")
267 return sqrt(param->Eval());
269 throw std::invalid_argument(
"Unknown function");
275 const std::unordered_map<std::string, double> &variables)
const override {
277 return sin(param->Eval(variables));
278 else if (func ==
"cos")
279 return cos(param->Eval(variables));
280 else if (func ==
"tan")
281 return tan(param->Eval(variables));
282 else if (func ==
"exp")
283 return exp(param->Eval(variables));
284 else if (func ==
"ln")
285 return log(param->Eval(variables));
286 else if (func ==
"sqrt")
287 return sqrt(param->Eval(variables));
289 throw std::invalid_argument(
"Unknown function");
300 template <
typename,
typename,
typename>
struct result {
304 template <
typename Params>
319 double Eval()
const override {
return expr->Eval(); }
322 const std::unordered_map<std::string, double> &variables)
const override {
323 return expr->Eval(variables);
AbstractSyntaxTree(AbstractSyntaxTree &&)=default
AbstractSyntaxTree(const AbstractSyntaxTree &)=default
AbstractSyntaxTree()=default
virtual ~AbstractSyntaxTree()=default
virtual double Eval(const std::unordered_map< std::string, double > &variables) const
virtual double Eval() const
AbstractSyntaxTree & operator=(const AbstractSyntaxTree &)=default
AbstractSyntaxTree & operator=(AbstractSyntaxTree &&)=default
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
BinaryOperator(char op, const L &left, const R &right)
double Eval() const override
Constant & operator=(int value)
Constant & operator=(double value)
double Eval(const std::unordered_map< std::string, double > &variables) const override
friend AbstractSyntaxTreePtr Clone(Expression const &e)
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
Function(const std::string &func, const F ¶m)
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
UnaryOperator(char op, const R &right)
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
Variable & operator=(int value)
double Eval() const override
Variable(const std::string &value="")
double Eval(const std::unordered_map< std::string, double > &variables) const override
phx::function< MakeFunctionExpression > MakeFunction
phx::function< MakeUnaryExpression > MakeUnary
phx::function< MakeBinaryExpression > MakeBinary
static AbstractSyntaxTreePtr Clone(Expr const &t)
std::shared_ptr< AbstractSyntaxTree > AbstractSyntaxTreePtr
phx::function< MakeVariableExpression > MakeVariable
phx::function< MakeConstantExpression > MakeConstant
BinaryOperator operator()(C op, const L &lhs, const R &rhs) const
Constant operator()(C op) const
Function operator()(const std::string &funcName, const Params ¶ms) const
UnaryOperator operator()(C op, const R &rhs) const
Variable operator()(V v) const