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;
402 [_val = multiplication(_val,_1,
405 [_val = division(_val,_1,boost::phoenix::ref(
error_msgs_))])
407 [_val = left_division(_val,_1,
410 [_val = elt_multiplication(_val,_1,
413 [_val = elt_division(_val,_1,
422 [_val = negate_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
424 [_val = logical_negate_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
434 [_val = add_expression_dimss_f(_val, _1, _pass,
438 [_val = transpose_f(_val, boost::phoenix::ref(
error_msgs_))]
449 [_val = set_var_type_f(_1,boost::phoenix::ref(
var_map_),
471 fun_r.name(
"function and argument expressions");
479 %= lexeme[char_(
"a-zA-Z")
480 >> *char_(
"a-zA-Z0-9_.")];
483 args_r.name(
"function argument expressions");
485 %= (lit(
'(') >> lit(
')'))
492 dims_r.name(
"array dimensions");
496 [_pass = validate_int_expr3_f(_1,boost::phoenix::ref(
error_msgs_))]
void generate_expression(const expression &e, std::ostream &o)
boost::spirit::qi::rule< Iterator, variable(), whitespace_grammar< Iterator > > variable_r
static function_signatures & instance()
Probability, optimization and sampling library.
boost::spirit::qi::rule< Iterator, int_literal(), whitespace_grammar< Iterator > > int_literal_r
stan::gm::expression_grammar< Iterator > & expression_g
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > term_r
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > negated_factor_r
boost::spirit::qi::rule< Iterator, double_literal(), whitespace_grammar< Iterator > > double_literal_r
term_grammar(variable_map &var_map, std::stringstream &error_msgs, expression_grammar< Iterator > &eg)
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
std::stringstream & error_msgs_
boost::spirit::qi::rule< Iterator, std::vector< expression >), whitespace_grammar< Iterator > > args_r
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< bool >, expression(), whitespace_grammar< Iterator > > factor_r
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > identifier_r
boost::spirit::qi::rule< Iterator, fun(), whitespace_grammar< Iterator > > fun_r
double e()
Return the base of the natural logarithm.
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > indexed_factor_r
expr_type get_result_type(const std::string &name, const std::vector< expr_type > &args, std::ostream &error_msgs)
boost::spirit::qi::rule< Iterator, std::vector< expression >), whitespace_grammar< Iterator > > dims_r