expression.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2021 Nikita Kaskov <nbering@nil.foundation>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 
26 #ifndef CRYPTO3_MATH_EXPRESSION_HPP
27 #define CRYPTO3_MATH_EXPRESSION_HPP
28 
32 
33 #include <memory>
34 #include <stdexcept>
35 #include <string>
36 
37 namespace nil {
38  namespace crypto3 {
39  namespace math {
40  namespace expressions {
41 
58  class Parser {
59  class impl {
60  typename detail::ast::operand ast;
61 
62  public:
63  void parse(std::string const &expr) {
64  auto ast_ = detail::ast::expression{};
65 
66  auto first = expr.begin();
67  auto last = expr.end();
68 
69  boost::spirit::x3::ascii::space_type space;
70  bool r = phrase_parse(first, last, detail::grammar(), space, ast_);
71 
72  if (!r || first != last) {
73  std::string rest(first, last);
74  throw std::runtime_error("Parsing failed at " + rest); // NOLINT
75  }
76 
77  ast = ast_;
78  }
79 
80  void optimize() { ast = boost::apply_visitor(detail::ast::ConstantFolder{}, ast); }
81 
82  double evaluate(std::map<std::string, double> const &st) {
83  return boost::apply_visitor(detail::ast::eval{st}, ast);
84  }
85  };
86  std::unique_ptr<impl> pimpl;
87 
88  public:
90  Parser() : pimpl{std::make_unique<impl>()} {};
91 
93  ~Parser() {};
94 
98  void parse(std::string const &expr) { pimpl->parse(expr); }
99 
101  void optimize() { pimpl->optimize(); }
102 
106  double evaluate(std::map<std::string, double> const &st = {}) {
107  return pimpl->evaluate(st);
108  }
109  };
110 
118  inline double parse(std::string const &expr,
119  std::map<std::string, double> const &st = {}) {
120  Parser parser;
121  parser.parse(expr);
122  return parser.evaluate(st);
123  }
124  } // namespace expressions
125  } // namespace math
126  } // namespace crypto3
127 } // namespace nil
128 
129 #endif // CRYPTO3_MATH_EXPRESSION_HPP
Parse a mathematical expression.
Definition: expression.hpp:58
void optimize()
Perform constant folding onto the abstract syntax tree.
Definition: expression.hpp:101
void parse(std::string const &expr)
Parse the mathematical expression into an abstract syntax tree.
Definition: expression.hpp:98
~Parser()
Destructor.
Definition: expression.hpp:93
Parser()
Constructor.
Definition: expression.hpp:90
double evaluate(std::map< std::string, double > const &st={})
Evaluate the abstract syntax tree for a given symbol table.
Definition: expression.hpp:106
parser::expression_type grammar()
Definition: parser_def.hpp:314
double parse(std::string const &expr, std::map< std::string, double > const &st={})
Convenience function.
Definition: expression.hpp:118
Definition: pair.hpp:31