parser_def.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_PARSER_DEF_HPP
27 #define CRYPTO3_MATH_EXPRESSION_PARSER_DEF_HPP
28 
29 #include <cmath>
30 #include <iostream>
31 #include <limits>
32 #include <string>
33 
34 #include <boost/math/constants/constants.hpp>
35 #include <boost/spirit/home/x3.hpp>
36 
41 
42 namespace nil {
43  namespace crypto3 {
44  namespace math {
45  namespace expressions {
46  namespace detail {
47 
48  namespace x3 = boost::spirit::x3;
49 
50  namespace parser {
51 
52  // LOOKUP
53 
54  struct constant_ : x3::symbols<double> {
56  // clang-format off
57  add
58  ("e" , boost::math::constants::e<double>())
59  ("epsilon", std::numeric_limits<double>::epsilon())
60  ("phi" , boost::math::constants::phi<double>())
61  ("pi" , boost::math::constants::pi<double>())
62  ;
63  // clang-format on
64  }
66 
67  struct ufunc_ : x3::symbols<double (*)(double)> {
68  ufunc_() {
69  // clang-format off
70  add
71  ("abs" , static_cast<double (*)(double)>(&std::abs))
72  ("acos" , static_cast<double (*)(double)>(&std::acos))
73  ("acosh" , static_cast<double (*)(double)>(&std::acosh))
74  ("asin" , static_cast<double (*)(double)>(&std::asin))
75  ("asinh" , static_cast<double (*)(double)>(&std::asinh))
76  ("atan" , static_cast<double (*)(double)>(&std::atan))
77  ("atanh" , static_cast<double (*)(double)>(&std::atanh))
78  ("cbrt" , static_cast<double (*)(double)>(&std::cbrt))
79  ("ceil" , static_cast<double (*)(double)>(&std::ceil))
80  ("cos" , static_cast<double (*)(double)>(&std::cos))
81  ("cosh" , static_cast<double (*)(double)>(&std::cosh))
82  ("deg" , static_cast<double (*)(double)>(&math::deg))
83  ("erf" , static_cast<double (*)(double)>(&std::erf))
84  ("erfc" , static_cast<double (*)(double)>(&std::erfc))
85  ("exp" , static_cast<double (*)(double)>(&std::exp))
86  ("exp2" , static_cast<double (*)(double)>(&std::exp2))
87  ("floor" , static_cast<double (*)(double)>(&std::floor))
88  ("isinf" , static_cast<double (*)(double)>(&math::isinf))
89  ("isnan" , static_cast<double (*)(double)>(&math::isnan))
90  ("log" , static_cast<double (*)(double)>(&std::log))
91  ("log2" , static_cast<double (*)(double)>(&std::log2))
92  ("log10" , static_cast<double (*)(double)>(&std::log10))
93  ("rad" , static_cast<double (*)(double)>(&math::rad))
94  ("round" , static_cast<double (*)(double)>(&std::round))
95  ("sgn" , static_cast<double (*)(double)>(&math::sgn))
96  ("sin" , static_cast<double (*)(double)>(&std::sin))
97  ("sinh" , static_cast<double (*)(double)>(&std::sinh))
98  ("sqrt" , static_cast<double (*)(double)>(&std::sqrt))
99  ("tan" , static_cast<double (*)(double)>(&std::tan))
100  ("tanh" , static_cast<double (*)(double)>(&std::tanh))
101  ("tgamma", static_cast<double (*)(double)>(&std::tgamma))
102  ;
103  // clang-format on
104  }
105  } ufunc;
106 
107  struct bfunc_ : x3::symbols<double (*)(double, double)> {
108  bfunc_() {
109  // clang-format off
110  add
111  ("atan2", static_cast<double (*)(double, double)>(&std::atan2))
112  ("max" , static_cast<double (*)(double, double)>(&std::fmax))
113  ("min" , static_cast<double (*)(double, double)>(&std::fmin))
114  ("pow" , static_cast<double (*)(double, double)>(&std::pow))
115  ;
116  // clang-format on
117  }
118  } bfunc;
119 
120  struct unary_op_ : x3::symbols<double (*)(double)> {
122  // clang-format off
123  add
124  ("+", static_cast<double (*)(double)>(&math::plus))
125  ("-", static_cast<double (*)(double)>(&math::minus))
126  ("!", static_cast<double (*)(double)>(&math::unary_not))
127  ;
128  // clang-format on
129  }
131 
132  struct additive_op_ : x3::symbols<double (*)(double, double)> {
134  // clang-format off
135  add
136  ("+", static_cast<double (*)(double, double)>(&math::plus))
137  ("-", static_cast<double (*)(double, double)>(&math::minus))
138  ;
139  // clang-format on
140  }
142 
143  struct multiplicative_op_ : x3::symbols<double (*)(double, double)> {
145  // clang-format off
146  add
147  ("*", static_cast<double (*)(double, double)>(&math::multiplies))
148  ("/", static_cast<double (*)(double, double)>(&math::divides))
149  ("%", static_cast<double (*)(double, double)>(&std::fmod))
150  ;
151  // clang-format on
152  }
154 
155  struct logical_op_ : x3::symbols<double (*)(double, double)> {
157  // clang-format off
158  add
159  ("&&", static_cast<double (*)(double, double)>(&math::logical_and))
160  ("||", static_cast<double (*)(double, double)>(&math::logical_or))
161  ;
162  // clang-format on
163  }
165 
166  struct relational_op_ : x3::symbols<double (*)(double, double)> {
168  // clang-format off
169  add
170  ("<" , static_cast<double (*)(double, double)>(&math::less))
171  ("<=", static_cast<double (*)(double, double)>(&math::less_equals))
172  (">" , static_cast<double (*)(double, double)>(&math::greater))
173  (">=", static_cast<double (*)(double, double)>(&math::greater_equals))
174  ;
175  // clang-format on
176  }
178 
179  struct equality_op_ : x3::symbols<double (*)(double, double)> {
181  // clang-format off
182  add
183  ("==", static_cast<double (*)(double, double)>(&math::equals))
184  ("!=", static_cast<double (*)(double, double)>(&math::not_equals))
185  ;
186  // clang-format on
187  }
189 
190  struct power_ : x3::symbols<double (*)(double, double)> {
191  power_() {
192  // clang-format off
193  add
194  ("**", static_cast<double (*)(double, double)>(&std::pow))
195  ;
196  // clang-format on
197  }
198  } power;
199 
200  // ADL markers
201 
202  struct expression_class;
203  struct logical_class;
204  struct equality_class;
205  struct relational_class;
206  struct additive_class;
207  struct multiplicative_class;
208  struct factor_class;
209  struct primary_class;
210  struct unary_class;
211  struct binary_class;
212  struct variable_class;
213 
214  // clang-format off
215 
216  // Rule declarations
217 
218  auto const expression = x3::rule<expression_class , ast::expression>{"expression"};
219  auto const logical = x3::rule<logical_class , ast::expression>{"logical"};
220  auto const equality = x3::rule<equality_class , ast::expression>{"equality"};
221  auto const relational = x3::rule<relational_class , ast::expression>{"relational"};
222  auto const additive = x3::rule<additive_class , ast::expression>{"additive"};
223  auto const multiplicative = x3::rule<multiplicative_class, ast::expression>{"multiplicative"};
224  auto const factor = x3::rule<factor_class , ast::expression>{"factor"};
225  auto const primary = x3::rule<primary_class , ast::operand >{"primary"};
226  auto const unary = x3::rule<unary_class , ast::unary_op >{"unary"};
227  auto const binary = x3::rule<binary_class , ast::binary_op >{"binary"};
228  auto const variable = x3::rule<variable_class , std::string >{"variable"};
229 
230  // Rule defintions
231 
232  auto const expression_def =
233  logical
234  ;
235 
236  auto const logical_def =
238  ;
239 
240  auto const equality_def =
242  ;
243 
244  auto const relational_def =
246  ;
247 
248  auto const additive_def =
250  ;
251 
252  auto const multiplicative_def =
254  ;
255 
256  auto const factor_def =
257  primary >> *( power > factor )
258  ;
259 
260  auto const unary_def =
261  ufunc > '(' > expression > ')'
262  ;
263 
264  auto const binary_def =
265  bfunc > '(' > expression > ',' > expression > ')'
266  ;
267 
268  auto const variable_def =
269  x3::raw[x3::lexeme[x3::alpha >> *(x3::alnum | '_')]]
270  ;
271 
272  auto const primary_def =
273  x3::double_
274  | ('(' > expression > ')')
275  | (unary_op > primary)
276  | binary
277  | unary
278  | constant
279  | variable
280  ;
281 
283  expression,
284  logical,
285  equality,
286  relational,
287  additive,
289  factor,
290  primary,
291  unary,
292  binary,
293  variable
294  )
295 
296  // clang-format on
297 
298  struct expression_class {
299  template <typename Iterator, typename Exception, typename Context>
300  x3::error_handler_result on_error(Iterator &, Iterator const &last,
301  Exception const &x, Context const &) {
302  std::cout << "Expected " << x.which() << " at \""
303  << std::string{x.where(), last} << "\"" << std::endl;
304  return x3::error_handler_result::fail;
305  }
306  };
307 
308  using expression_type = x3::rule<expression_class, ast::expression>;
309 
310  BOOST_SPIRIT_DECLARE(expression_type)
311 
312  } // namespace parser
313 
315 
316  } // namespace detail
317  } // namespace expressions
318  } // namespace math
319  } // namespace crypto3
320 } // namespace nil
321 
322 #endif // CRYPTO3_MATH_EXPRESSION_PARSER_DEF_HPP
constexpr nil::crypto3::detail::remove_complex_t< T > abs(T x)
computes the absolute value
Definition: algebra/include/nil/crypto3/algebra/scalar/math.hpp:76
constexpr double sqrt(double x)
computes the square root
Definition: algebra/include/nil/crypto3/algebra/scalar/math.hpp:47
constexpr T pow(T x, U n)
Definition: static_pow.hpp:32
T greater_equals(T x, T y)
greater equals
Definition: math/include/nil/crypto3/math/expressions/math.hpp:148
T divides(T x, T y)
divide
Definition: math/include/nil/crypto3/math/expressions/math.hpp:106
T less_equals(T x, T y)
less equals
Definition: math/include/nil/crypto3/math/expressions/math.hpp:136
T deg(T x)
Convert radians to degrees.
Definition: math/include/nil/crypto3/math/expressions/math.hpp:64
T multiplies(T x, T y)
multiply
Definition: math/include/nil/crypto3/math/expressions/math.hpp:100
T equals(T x, T y)
equals
Definition: math/include/nil/crypto3/math/expressions/math.hpp:154
T unary_not(T x)
unary not
Definition: math/include/nil/crypto3/math/expressions/math.hpp:112
T greater(T x, T y)
greater
Definition: math/include/nil/crypto3/math/expressions/math.hpp:142
T isinf(T x)
isinf function with adjusted return type
Definition: math/include/nil/crypto3/math/expressions/math.hpp:58
T less(T x, T y)
less
Definition: math/include/nil/crypto3/math/expressions/math.hpp:130
T plus(T x)
unary plus
Definition: math/include/nil/crypto3/math/expressions/math.hpp:76
T isnan(T x)
isnan function with adjusted return type
Definition: math/include/nil/crypto3/math/expressions/math.hpp:52
T rad(T x)
Convert degrees to radians.
Definition: math/include/nil/crypto3/math/expressions/math.hpp:70
T minus(T x)
unary minus
Definition: math/include/nil/crypto3/math/expressions/math.hpp:88
T not_equals(T x, T y)
not equals
Definition: math/include/nil/crypto3/math/expressions/math.hpp:160
T logical_and(T x, T y)
logical and
Definition: math/include/nil/crypto3/math/expressions/math.hpp:118
T sgn(T x)
Sign function.
Definition: math/include/nil/crypto3/math/expressions/math.hpp:46
T logical_or(T x, T y)
logical or
Definition: math/include/nil/crypto3/math/expressions/math.hpp:124
auto const unary
Definition: parser_def.hpp:226
auto const expression
Definition: parser_def.hpp:218
auto const logical_def
Definition: parser_def.hpp:236
auto const multiplicative_def
Definition: parser_def.hpp:252
auto const binary
Definition: parser_def.hpp:227
auto const primary_def
Definition: parser_def.hpp:272
auto const variable_def
Definition: parser_def.hpp:268
auto const multiplicative
Definition: parser_def.hpp:223
auto const equality_def
Definition: parser_def.hpp:240
nil::crypto3::math::expressions::detail::parser::ufunc_ ufunc
nil::crypto3::math::expressions::detail::parser::multiplicative_op_ multiplicative_op
auto const factor_def
Definition: parser_def.hpp:256
nil::crypto3::math::expressions::detail::parser::additive_op_ additive_op
nil::crypto3::math::expressions::detail::parser::power_ power
auto const logical
Definition: parser_def.hpp:219
x3::rule< expression_class, ast::expression > expression_type
Definition: parser_def.hpp:308
nil::crypto3::math::expressions::detail::parser::logical_op_ logical_op
auto const relational
Definition: parser_def.hpp:221
auto const equality
Definition: parser_def.hpp:220
nil::crypto3::math::expressions::detail::parser::relational_op_ relational_op
auto const relational_def
Definition: parser_def.hpp:244
auto const variable
Definition: parser_def.hpp:228
auto const additive_def
Definition: parser_def.hpp:248
nil::crypto3::math::expressions::detail::parser::unary_op_ unary_op
auto const additive
Definition: parser_def.hpp:222
auto const factor
Definition: parser_def.hpp:224
auto const binary_def
Definition: parser_def.hpp:264
auto const expression_def
Definition: parser_def.hpp:232
auto const primary
Definition: parser_def.hpp:225
BOOST_SPIRIT_DEFINE(expression, logical, equality, relational, additive, multiplicative, factor, primary, unary, binary, variable) struct expression_class
Definition: parser_def.hpp:282
nil::crypto3::math::expressions::detail::parser::constant_ constant
nil::crypto3::math::expressions::detail::parser::bfunc_ bfunc
auto const unary_def
Definition: parser_def.hpp:260
nil::crypto3::math::expressions::detail::parser::equality_op_ equality_op
parser::expression_type grammar()
Definition: parser_def.hpp:314
Definition: pair.hpp:31