1 #ifndef __STAN__GM__PARSER__EXPRESSION_GRAMMAR_DEF__HPP__
2 #define __STAN__GM__PARSER__EXPRESSION_GRAMMAR_DEF__HPP__
16 #include <boost/spirit/include/qi.hpp>
18 #include <boost/spirit/include/phoenix_core.hpp>
19 #include <boost/spirit/include/phoenix_function.hpp>
20 #include <boost/spirit/include/phoenix_fusion.hpp>
21 #include <boost/spirit/include/phoenix_object.hpp>
22 #include <boost/spirit/include/phoenix_operator.hpp>
23 #include <boost/spirit/include/phoenix_stl.hpp>
25 #include <boost/lexical_cast.hpp>
26 #include <boost/fusion/include/adapt_struct.hpp>
27 #include <boost/fusion/include/std_pair.hpp>
28 #include <boost/config/warning_disable.hpp>
29 #include <boost/spirit/include/qi.hpp>
30 #include <boost/spirit/include/qi_numeric.hpp>
31 #include <boost/spirit/include/classic_position_iterator.hpp>
32 #include <boost/spirit/include/phoenix_core.hpp>
33 #include <boost/spirit/include/phoenix_function.hpp>
34 #include <boost/spirit/include/phoenix_fusion.hpp>
35 #include <boost/spirit/include/phoenix_object.hpp>
36 #include <boost/spirit/include/phoenix_operator.hpp>
37 #include <boost/spirit/include/phoenix_stl.hpp>
38 #include <boost/spirit/include/support_multi_pass.hpp>
39 #include <boost/tuple/tuple.hpp>
40 #include <boost/variant/apply_visitor.hpp>
41 #include <boost/variant/recursive_variant.hpp>
49 (std::vector<std::vector<stan::gm::expression> >,
54 (std::vector<stan::gm::expression>, args_) )
58 (stan::gm::expr_type,type_))
62 (stan::gm::expr_type,type_) )
69 template <
typename T1,
typename T2>
70 struct result {
typedef fun type; };
72 fun operator()(fun& fun,
73 std::ostream& error_msgs)
const {
74 std::vector<expr_type> arg_types;
75 for (
size_t i = 0; i < fun.args_.size(); ++i)
76 arg_types.push_back(fun.args_[i].expression_type());
77 fun.type_ = function_signatures::instance().get_result_type(fun.name_,
83 boost::phoenix::function<set_fun_type> set_fun_type_f;
86 struct addition_expr {
87 template <
typename T1,
typename T2,
typename T3>
88 struct result {
typedef expression type; };
90 expression operator()(expression& expr1,
91 const expression& expr2,
92 std::ostream& error_msgs)
const {
93 if (expr1.expression_type().is_primitive()
94 && expr2.expression_type().is_primitive()) {
95 return expr1 += expr2;
97 std::vector<expression> args;
98 args.push_back(expr1);
99 args.push_back(expr2);
103 return expression(f);
104 return expr1 += expr2;
107 boost::phoenix::function<addition_expr> addition;
110 struct subtraction_expr {
111 template <
typename T1,
typename T2,
typename T3>
112 struct result {
typedef expression type; };
114 expression operator()(expression& expr1,
115 const expression& expr2,
116 std::ostream& error_msgs)
const {
117 if (expr1.expression_type().is_primitive()
118 && expr2.expression_type().is_primitive()) {
119 return expr1 -= expr2;
121 std::vector<expression> args;
122 args.push_back(expr1);
123 args.push_back(expr2);
125 fun f(
"subtract",args);
127 return expression(f);
130 boost::phoenix::function<subtraction_expr> subtraction;
132 struct multiplication_expr {
133 template <
typename T1,
typename T2,
typename T3>
134 struct result {
typedef expression type; };
136 expression operator()(expression& expr1,
137 const expression& expr2,
138 std::ostream& error_msgs)
const {
140 if (expr1.expression_type().is_primitive()
141 && expr2.expression_type().is_primitive()) {
142 return expr1 *= expr2;
144 std::vector<expression> args;
145 args.push_back(expr1);
146 args.push_back(expr2);
148 fun f(
"multiply",args);
150 return expression(f);
153 boost::phoenix::function<multiplication_expr> multiplication;
157 struct division_expr {
158 template <
typename T1,
typename T2,
typename T3>
159 struct result {
typedef expression type; };
161 expression operator()(expression& expr1,
162 const expression& expr2,
163 std::ostream& error_msgs)
const {
164 if (expr1.expression_type().is_primitive_int()
165 && expr2.expression_type().is_primitive_int()) {
167 error_msgs <<
"Warning: integer division implicitly rounds to integer."
168 <<
" Found int division: ";
172 error_msgs << std::endl
173 <<
" Positive values rounded down, negative values rounded up or down"
174 <<
" in platform-dependent way."
178 if (expr1.expression_type().is_primitive()
179 && expr2.expression_type().is_primitive()) {
180 return expr1 /= expr2;
182 std::vector<expression> args;
183 args.push_back(expr1);
184 args.push_back(expr2);
186 if ((expr1.expression_type().type() ==
MATRIX_T
188 && expr2.expression_type().type() ==
MATRIX_T) {
189 fun f(
"mdivide_right",args);
191 return expression(f);
194 fun f(
"divide",args);
196 return expression(f);
199 boost::phoenix::function<division_expr> division;
201 struct left_division_expr {
202 template <
typename T1,
typename T2,
typename T3>
203 struct result {
typedef expression type; };
205 expression operator()(expression& expr1,
206 const expression& expr2,
207 std::ostream& error_msgs)
const {
208 if (expr1.expression_type().is_primitive()
209 && expr2.expression_type().is_primitive()) {
210 return expr1 /= expr2;
212 std::vector<expression> args;
213 args.push_back(expr1);
214 args.push_back(expr2);
216 if (expr1.expression_type().type() ==
MATRIX_T
217 && (expr2.expression_type().type() ==
VECTOR_T
218 || expr2.expression_type().type() ==
MATRIX_T)) {
219 fun f(
"mdivide_left",args);
221 return expression(f);
223 fun f(
"divide_left",args);
225 return expression(f);
228 boost::phoenix::function<left_division_expr> left_division;
230 struct elt_multiplication_expr {
231 template <
typename T1,
typename T2,
typename T3>
232 struct result {
typedef expression type; };
234 expression operator()(expression& expr1,
235 const expression& expr2,
236 std::ostream& error_msgs)
const {
238 if (expr1.expression_type().is_primitive()
239 && expr2.expression_type().is_primitive()) {
240 return expr1 *= expr2;
242 std::vector<expression> args;
243 args.push_back(expr1);
244 args.push_back(expr2);
246 fun f(
"elt_multiply",args);
248 return expression(f);
249 return expr1 += expr2;
252 boost::phoenix::function<elt_multiplication_expr> elt_multiplication;
254 struct elt_division_expr {
255 template <
typename T1,
typename T2,
typename T3>
256 struct result {
typedef expression type; };
258 expression operator()(expression& expr1,
259 const expression& expr2,
260 std::ostream& error_msgs)
const {
262 if (expr1.expression_type().is_primitive()
263 && expr2.expression_type().is_primitive()) {
264 return expr1 /= expr2;
266 std::vector<expression> args;
267 args.push_back(expr1);
268 args.push_back(expr2);
270 fun f(
"elt_divide",args);
272 return expression(f);
273 return expr1 += expr2;
276 boost::phoenix::function<elt_division_expr> elt_division;
284 template <
typename T1,
typename T2>
285 struct result {
typedef expression type; };
287 expression operator()(
const expression& expr,
288 std::ostream& error_msgs)
const {
289 if (expr.expression_type().is_primitive()) {
290 return expression(unary_op(
'-', expr));
292 std::vector<expression> args;
293 args.push_back(expr);
297 return expression(f);
300 boost::phoenix::function<negate_expr> negate_expr_f;
302 struct transpose_expr {
303 template <
typename T1,
typename T2>
304 struct result {
typedef expression type; };
306 expression operator()(
const expression& expr,
307 std::ostream& error_msgs)
const {
308 if (expr.expression_type().is_primitive()) {
311 std::vector<expression> args;
312 args.push_back(expr);
314 fun f(
"transpose",args);
316 return expression(f);
319 boost::phoenix::function<transpose_expr> transpose_f;
321 struct add_expression_dimss {
322 template <
typename T1,
typename T2,
typename T3,
typename T4>
323 struct result {
typedef T1 type; };
324 expression operator()(expression& expression,
325 std::vector<std::vector<stan::gm::expression> >& dimss,
327 std::ostream& error_msgs)
const {
328 index_op iop(expression,dimss);
330 if (iop.type_.is_ill_formed()) {
331 error_msgs <<
"indexes inappropriate for expression." << std::endl;
339 boost::phoenix::function<add_expression_dimss> add_expression_dimss_f;
341 struct set_var_type {
342 template <
typename T1,
typename T2,
typename T3,
typename T4>
343 struct result {
typedef variable type; };
344 variable operator()(variable& var_expr,
346 std::ostream& error_msgs,
348 std::string name = var_expr.name_;
349 if (!vm.exists(name)) {
351 error_msgs <<
"variable \"" << name <<
'"' <<
" does not exist."
356 var_expr.set_type(vm.get_base_type(name),vm.get_num_dims(name));
360 boost::phoenix::function<set_var_type> set_var_type_f;
362 struct validate_int_expr3 {
363 template <
typename T1,
typename T2>
364 struct result {
typedef bool type; };
366 bool operator()(
const expression& expr,
367 std::stringstream& error_msgs)
const {
368 if (!expr.expression_type().is_primitive_int()) {
369 error_msgs <<
"expression denoting integer required; found type="
370 << expr.expression_type() << std::endl;
376 boost::phoenix::function<validate_int_expr3> validate_int_expr3_f;
379 struct validate_expr_type {
380 template <
typename T1,
typename T2>
381 struct result {
typedef bool type; };
383 bool operator()(
const expression& expr,
384 std::ostream& error_msgs)
const {
385 if (expr.expression_type().is_ill_formed()) {
386 error_msgs <<
"expression is ill formed" << std::endl;
392 boost::phoenix::function<validate_expr_type> validate_expr_type_f;
398 template <
typename Iterator>
399 expression_grammar<Iterator>::expression_grammar(variable_map& var_map,
400 std::stringstream& error_msgs)
401 : expression_grammar::base_type(expression_r),
403 error_msgs_(error_msgs)
405 using boost::spirit::qi::_1;
406 using boost::spirit::qi::char_;
407 using boost::spirit::qi::double_;
408 using boost::spirit::qi::eps;
409 using boost::spirit::qi::int_;
410 using boost::spirit::qi::lexeme;
411 using boost::spirit::qi::lit;
412 using boost::spirit::qi::_pass;
413 using boost::spirit::qi::_val;
415 expression_r.name(
"expression");
417 %= term_r [_val = _1]
418 >> *( (lit(
'+') > term_r [_val = addition(_val,_1,boost::phoenix::ref(error_msgs))])
419 | (lit(
'-') > term_r [_val = subtraction(_val,_1,boost::phoenix::ref(error_msgs))])
421 > eps[_pass = validate_expr_type_f(_val,boost::phoenix::ref(error_msgs_))]
426 %= ( negated_factor_r [_val = _1]
427 >> *( (lit(
'*') > negated_factor_r
428 [_val = multiplication(_val,_1,boost::phoenix::ref(error_msgs_))])
429 | (lit(
'/') > negated_factor_r
430 [_val = division(_val,_1,boost::phoenix::ref(error_msgs_))])
431 | (lit(
'\\') > negated_factor_r [_val = left_division(_val,_1,boost::phoenix::ref(error_msgs_))])
432 | (lit(
".*") > negated_factor_r
433 [_val = elt_multiplication(_val,_1,boost::phoenix::ref(error_msgs_))])
434 | (lit(
"./") > negated_factor_r
435 [_val = elt_division(_val,_1,boost::phoenix::ref(error_msgs_))])
441 %= lit(
'-') >> indexed_factor_r [_val = negate_expr_f(_1,boost::phoenix::ref(error_msgs_))]
442 | lit(
'+') >> indexed_factor_r [_val = _1]
443 | indexed_factor_r [_val = _1];
446 indexed_factor_r.name(
"(optionally) indexed factor [sub]");
448 = factor_r [_val = _1]
451 [_val = add_expression_dimss_f(_val, _1, _pass,
452 boost::phoenix::ref(error_msgs_))]
455 [_val = transpose_f(_val, boost::phoenix::ref(error_msgs_))]
459 factor_r.name(
"factor");
461 %= int_literal_r [_val = _1]
462 | double_literal_r [_val = _1]
463 | fun_r [_val = set_fun_type_f(_1,boost::phoenix::ref(error_msgs_))]
465 [_val = set_var_type_f(_1,boost::phoenix::ref(var_map_),
466 boost::phoenix::ref(error_msgs_),
469 > expression_r [_val = _1]
473 int_literal_r.name(
"integer literal");
480 double_literal_r.name(
"real literal");
484 fun_r.name(
"function and argument expressions");
489 identifier_r.name(
"identifier");
491 %= (lexeme[char_(
"a-zA-Z")
492 >> *char_(
"a-zA-Z0-9_.")]);
494 args_r.name(
"function argument expressions");
496 %= (lit(
'(') >> lit(
')'))
498 >> (expression_r %
',')
502 dims_r.name(
"array dimensions");
506 [_pass = validate_int_expr3_f(_1,boost::phoenix::ref(error_msgs_))]
511 variable_r.name(
"variable expression");