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_) )
59 (stan::gm::expr_type,type_))
63 (stan::gm::expr_type,type_) )
74 template <
typename T1,
typename T2>
75 struct result {
typedef fun type; };
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());
82 fun.type_ = function_signatures::instance().get_result_type(fun.name_,
93 template <
typename T1,
typename T2,
typename T3>
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);
118 template <
typename T1,
typename T2,
typename T3>
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);
162 template <
typename T1,
typename T2,
typename T3>
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);
191 template <
typename T1,
typename T2,
typename T3>
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;
215 template <
typename T1,
typename T2,
typename T3>
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;
244 template <
typename T1,
typename T2>
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);
263 template <
typename T1,
typename T2>
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);
283 template <
typename T1,
typename T2>
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);
302 template <
typename T1,
typename T2,
typename T3,
typename T4>
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;
322 template <
typename T1,
typename T2,
typename T3,
typename T4>
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));
343 template <
typename T1,
typename T2>
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;
360 template <
typename T1,
typename T2>
364 std::ostream& error_msgs)
const {
365 if (expr.expression_type().is_ill_formed()) {
366 error_msgs <<
"expression is ill formed" << std::endl;
378 template <
typename Iterator>
380 std::stringstream& error_msgs,
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;
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");
boost::spirit::qi::rule< Iterator, variable(), whitespace_grammar< Iterator > > variable_r
boost::phoenix::function< elt_multiplication_expr > elt_multiplication
boost::phoenix::function< set_fun_type > set_fun_type_f
expression operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
variable operator()(variable &var_expr, variable_map &vm, std::ostream &error_msgs, bool &pass) const
boost::phoenix::function< logical_negate_expr > logical_negate_expr_f
boost::phoenix::function< add_expression_dimss > add_expression_dimss_f
fun operator()(fun &fun, std::ostream &error_msgs) const
boost::spirit::qi::rule< Iterator, int_literal(), whitespace_grammar< Iterator > > int_literal_r
expression operator()(expression &expression, std::vector< std::vector< stan::gm::expression > > &dimss, bool &pass, std::ostream &error_msgs) const
stan::gm::expression_grammar< Iterator > & expression_g
expression operator()(const expression &expr, std::ostream &error_msgs) const
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > term_r
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > negated_factor_r
boost::phoenix::function< multiplication_expr > multiplication
boost::spirit::qi::rule< Iterator, double_literal(), whitespace_grammar< Iterator > > double_literal_r
boost::phoenix::function< validate_int_expr3 > validate_int_expr3_f
boost::phoenix::function< elt_division_expr > elt_division
expression operator()(const expression &expr, std::ostream &error_msgs) const
bool operator()(const expression &expr, std::ostream &error_msgs) const
boost::phoenix::function< validate_expr_type > validate_expr_type_f
expression operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
expression operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
expression operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
boost::phoenix::function< negate_expr > negate_expr_f
boost::phoenix::function< division_expr > division
boost::phoenix::function< set_var_type > set_var_type_f
boost::phoenix::function< left_division_expr > left_division
std::stringstream & error_msgs_
boost::spirit::qi::rule< Iterator, std::vector< expression >), whitespace_grammar< Iterator > > args_r
void generate_expression(const expression &e, std::ostream &o)
expression operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< bool >, expression(), whitespace_grammar< Iterator > > factor_r
expression operator()(const expression &expr, std::ostream &error_msgs) const
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
BOOST_FUSION_ADAPT_STRUCT(stan::gm::index_op,(stan::gm::expression, expr_)(std::vector< std::vector< stan::gm::expression > >, dimss_)) BOOST_FUSION_ADAPT_STRUCT(stan
boost::phoenix::function< transpose_expr > transpose_f
boost::spirit::qi::rule< Iterator, std::vector< expression >), whitespace_grammar< Iterator > > dims_r
bool operator()(const expression &expr, std::stringstream &error_msgs) const