1 #ifndef __STAN__GM__PARSER__TERM_GRAMMAR_DEF__HPP__
2 #define __STAN__GM__PARSER__TERM_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>
50 (std::vector<std::vector<stan::gm::expression> >,
55 (std::vector<stan::gm::expression>, args_) )
74 template <
typename T1,
typename T2>
75 struct result {
typedef fun type; };
77 fun operator()(fun& fun,
78 std::ostream& error_msgs)
const {
79 std::vector<expr_type> arg_types;
80 for (
size_t i = 0; i < fun.args_.size(); ++i)
81 arg_types.push_back(fun.args_[i].expression_type());
88 boost::phoenix::function<set_fun_type> set_fun_type_f;
92 struct multiplication_expr {
93 template <
typename T1,
typename T2,
typename T3>
94 struct result {
typedef expression type; };
96 expression operator()(expression& expr1,
97 const expression& expr2,
98 std::ostream& error_msgs)
const {
100 if (expr1.expression_type().is_primitive()
101 && expr2.expression_type().is_primitive()) {
102 return expr1 *= expr2;
104 std::vector<expression> args;
105 args.push_back(expr1);
106 args.push_back(expr2);
108 fun f(
"multiply",args);
110 return expression(f);
113 boost::phoenix::function<multiplication_expr> multiplication;
117 struct division_expr {
118 template <
typename T1,
typename T2,
typename T3>
119 struct result {
typedef expression type; };
121 expression operator()(expression& expr1,
122 const expression& expr2,
123 std::ostream& error_msgs)
const {
124 if (expr1.expression_type().is_primitive_int()
125 && expr2.expression_type().is_primitive_int()) {
127 error_msgs <<
"Warning: integer division implicitly rounds to integer."
128 <<
" Found int division: ";
132 error_msgs << std::endl
133 <<
" Positive values rounded down, negative values rounded up or down"
134 <<
" in platform-dependent way."
138 if (expr1.expression_type().is_primitive()
139 && expr2.expression_type().is_primitive()) {
140 return expr1 /= expr2;
142 std::vector<expression> args;
143 args.push_back(expr1);
144 args.push_back(expr2);
146 if ((expr1.expression_type().type() ==
MATRIX_T
148 && expr2.expression_type().type() ==
MATRIX_T) {
149 fun f(
"mdivide_right",args);
151 return expression(f);
154 fun f(
"divide",args);
156 return expression(f);
159 boost::phoenix::function<division_expr> division;
161 struct left_division_expr {
162 template <
typename T1,
typename T2,
typename T3>
163 struct result {
typedef expression type; };
165 expression operator()(expression& expr1,
166 const expression& expr2,
167 std::ostream& error_msgs)
const {
168 if (expr1.expression_type().is_primitive()
169 && expr2.expression_type().is_primitive()) {
170 return expr1 /= expr2;
172 std::vector<expression> args;
173 args.push_back(expr1);
174 args.push_back(expr2);
176 if (expr1.expression_type().type() ==
MATRIX_T
177 && (expr2.expression_type().type() ==
VECTOR_T
178 || expr2.expression_type().type() ==
MATRIX_T)) {
179 fun f(
"mdivide_left",args);
181 return expression(f);
183 fun f(
"divide_left",args);
185 return expression(f);
188 boost::phoenix::function<left_division_expr> left_division;
190 struct elt_multiplication_expr {
191 template <
typename T1,
typename T2,
typename T3>
192 struct result {
typedef expression type; };
194 expression operator()(expression& expr1,
195 const expression& expr2,
196 std::ostream& error_msgs)
const {
198 if (expr1.expression_type().is_primitive()
199 && expr2.expression_type().is_primitive()) {
200 return expr1 *= expr2;
202 std::vector<expression> args;
203 args.push_back(expr1);
204 args.push_back(expr2);
206 fun f(
"elt_multiply",args);
208 return expression(f);
209 return expr1 += expr2;
212 boost::phoenix::function<elt_multiplication_expr> elt_multiplication;
214 struct elt_division_expr {
215 template <
typename T1,
typename T2,
typename T3>
216 struct result {
typedef expression type; };
218 expression operator()(expression& expr1,
219 const expression& expr2,
220 std::ostream& error_msgs)
const {
222 if (expr1.expression_type().is_primitive()
223 && expr2.expression_type().is_primitive()) {
224 return expr1 /= expr2;
226 std::vector<expression> args;
227 args.push_back(expr1);
228 args.push_back(expr2);
230 fun f(
"elt_divide",args);
232 return expression(f);
233 return expr1 += expr2;
236 boost::phoenix::function<elt_division_expr> elt_division;
244 template <
typename T1,
typename T2>
245 struct result {
typedef expression type; };
247 expression operator()(
const expression& expr,
248 std::ostream& error_msgs)
const {
249 if (expr.expression_type().is_primitive()) {
250 return expression(unary_op(
'-', expr));
252 std::vector<expression> args;
253 args.push_back(expr);
257 return expression(f);
260 boost::phoenix::function<negate_expr> negate_expr_f;
262 struct logical_negate_expr {
263 template <
typename T1,
typename T2>
264 struct result {
typedef expression type; };
266 expression operator()(
const expression& expr,
267 std::ostream& error_msgs)
const {
268 if (!expr.expression_type().is_primitive()) {
269 error_msgs <<
"logical negation operator ! only applies to int or real types; ";
272 std::vector<expression> args;
273 args.push_back(expr);
275 fun f(
"logical_negation",args);
277 return expression(f);
280 boost::phoenix::function<logical_negate_expr> logical_negate_expr_f;
282 struct transpose_expr {
283 template <
typename T1,
typename T2>
284 struct result {
typedef expression type; };
286 expression operator()(
const expression& expr,
287 std::ostream& error_msgs)
const {
288 if (expr.expression_type().is_primitive()) {
291 std::vector<expression> args;
292 args.push_back(expr);
294 fun f(
"transpose",args);
296 return expression(f);
299 boost::phoenix::function<transpose_expr> transpose_f;
301 struct add_expression_dimss {
302 template <
typename T1,
typename T2,
typename T3,
typename T4>
303 struct result {
typedef T1 type; };
304 expression operator()(expression& expression,
305 std::vector<std::vector<stan::gm::expression> >& dimss,
307 std::ostream& error_msgs)
const {
308 index_op iop(expression,dimss);
310 if (iop.type_.is_ill_formed()) {
311 error_msgs <<
"indexes inappropriate for expression." << std::endl;
319 boost::phoenix::function<add_expression_dimss> add_expression_dimss_f;
321 struct set_var_type {
322 template <
typename T1,
typename T2,
typename T3,
typename T4>
323 struct result {
typedef variable type; };
324 variable operator()(variable& var_expr,
326 std::ostream& error_msgs,
328 std::string name = var_expr.name_;
329 if (!vm.exists(name)) {
331 error_msgs <<
"variable \"" << name <<
'"' <<
" does not exist."
336 var_expr.set_type(vm.get_base_type(name),vm.get_num_dims(name));
340 boost::phoenix::function<set_var_type> set_var_type_f;
342 struct validate_int_expr3 {
343 template <
typename T1,
typename T2>
344 struct result {
typedef bool type; };
346 bool operator()(
const expression& expr,
347 std::stringstream& error_msgs)
const {
348 if (!expr.expression_type().is_primitive_int()) {
349 error_msgs <<
"expression denoting integer required; found type="
350 << expr.expression_type() << std::endl;
356 boost::phoenix::function<validate_int_expr3> validate_int_expr3_f;
359 struct validate_expr_type {
360 template <
typename T1,
typename T2>
361 struct result {
typedef bool type; };
363 bool operator()(
const expression& expr,
364 std::ostream& error_msgs)
const {
365 if (expr.expression_type().is_ill_formed()) {
366 error_msgs <<
"expression is ill formed" << std::endl;
372 boost::phoenix::function<validate_expr_type> validate_expr_type_f;
378 template <
typename Iterator>
380 std::stringstream& error_msgs,
381 expression_grammar<Iterator>& eg)
382 : term_grammar::base_type(term_r),
384 error_msgs_(error_msgs),
387 using boost::spirit::qi::_1;
388 using boost::spirit::qi::char_;
389 using boost::spirit::qi::double_;
390 using boost::spirit::qi::eps;
391 using boost::spirit::qi::int_;
392 using boost::spirit::qi::lexeme;
393 using boost::spirit::qi::lit;
394 using boost::spirit::qi::_pass;
395 using boost::spirit::qi::_val;
401 >> *( (lit(
'*') > negated_factor_r
402 [_val = multiplication(_val,_1,
403 boost::phoenix::ref(error_msgs_))])
404 | (lit(
'/') > negated_factor_r
405 [_val = division(_val,_1,boost::phoenix::ref(error_msgs_))])
406 | (lit(
'\\') > negated_factor_r
407 [_val = left_division(_val,_1,
408 boost::phoenix::ref(error_msgs_))])
409 | (lit(
".*") > negated_factor_r
410 [_val = elt_multiplication(_val,_1,
411 boost::phoenix::ref(error_msgs_))])
412 | (lit(
"./") > negated_factor_r
413 [_val = elt_division(_val,_1,
414 boost::phoenix::ref(error_msgs_))])
421 = lit(
'-') >> negated_factor_r
422 [_val = negate_expr_f(_1,boost::phoenix::ref(error_msgs_))]
423 | lit(
'!') >> negated_factor_r
424 [_val = logical_negate_expr_f(_1,boost::phoenix::ref(error_msgs_))]
425 | lit(
'+') >> negated_factor_r [_val = _1]
426 | indexed_factor_r [_val = _1];
429 indexed_factor_r.name(
"(optionally) indexed factor [sub]");
431 = factor_r [_val = _1]
434 [_val = add_expression_dimss_f(_val, _1, _pass,
435 boost::phoenix::ref(error_msgs_))]
438 [_val = transpose_f(_val, boost::phoenix::ref(error_msgs_))]
443 factor_r.name(
"factor");
445 = int_literal_r [_val = _1]
446 | double_literal_r [_val = _1]
447 | fun_r [_val = set_fun_type_f(_1,boost::phoenix::ref(error_msgs_))]
449 [_val = set_var_type_f(_1,boost::phoenix::ref(var_map_),
450 boost::phoenix::ref(error_msgs_),
453 > expression_g [_val = _1]
458 int_literal_r.name(
"integer literal");
466 double_literal_r.name(
"real literal");
471 fun_r.name(
"function and argument expressions");
477 identifier_r.name(
"identifier (expression grammar)");
479 %= lexeme[char_(
"a-zA-Z")
480 >> *char_(
"a-zA-Z0-9_.")];
483 args_r.name(
"function argument expressions");
485 %= (lit(
'(') >> lit(
')'))
487 >> (expression_g %
',')
492 dims_r.name(
"array dimensions");
496 [_pass = validate_int_expr3_f(_1,boost::phoenix::ref(error_msgs_))]
502 variable_r.name(
"variable expression");
static function_signatures & instance()
expr_type get_result_type(const std::string &name, const std::vector< expr_type > &args, std::ostream &error_msgs)
void generate_expression(const expression &e, std::ostream &o)
double e()
Return the base of the natural logarithm.
Probability, optimization and sampling library.
BOOST_FUSION_ADAPT_STRUCT(stan::gm::program,(std::vector< stan::gm::var_decl >, data_decl_)(DUMMY_STRUCT::type, derived_data_decl_)(std::vector< stan::gm::var_decl >, parameter_decl_)(DUMMY_STRUCT::type, derived_decl_)(stan::gm::statement, statement_)(DUMMY_STRUCT::type, generated_decl_)) namespace stan
term_grammar(variable_map &var_map, std::stringstream &error_msgs, expression_grammar< Iterator > &eg)