1 #ifndef STAN__GM__PARSER__VAR_DECLS_GRAMMAR_DEF__HPP
2 #define STAN__GM__PARSER__VAR_DECLS_GRAMMAR_DEF__HPP
4 #include <boost/spirit/include/qi.hpp>
6 #include <boost/spirit/include/phoenix_core.hpp>
7 #include <boost/spirit/include/phoenix_function.hpp>
8 #include <boost/spirit/include/phoenix_fusion.hpp>
9 #include <boost/spirit/include/phoenix_object.hpp>
10 #include <boost/spirit/include/phoenix_operator.hpp>
11 #include <boost/spirit/include/phoenix_stl.hpp>
13 #include <boost/lexical_cast.hpp>
14 #include <boost/fusion/include/adapt_struct.hpp>
15 #include <boost/fusion/include/std_pair.hpp>
16 #include <boost/config/warning_disable.hpp>
17 #include <boost/spirit/include/qi_numeric.hpp>
25 (std::vector<stan::gm::expression>, dims_) )
28 (stan::gm::range, range_)
30 (std::vector<stan::gm::expression>, dims_) )
33 (stan::gm::range, range_)
34 (stan::gm::expression,
M_)
36 (std::vector<stan::gm::expression>, dims_) )
39 (stan::gm::range, range_)
40 (stan::gm::expression,
N_)
42 (std::vector<stan::gm::expression>, dims_) )
45 (stan::gm::range, range_)
46 (stan::gm::expression,
M_)
47 (stan::gm::expression,
N_)
49 (std::vector<stan::gm::expression>, dims_) )
52 (stan::gm::expression, K_)
54 (std::vector<stan::gm::expression>, dims_) )
57 (stan::gm::expression, K_)
59 (std::vector<stan::gm::expression>, dims_) )
62 (stan::gm::expression, K_)
64 (std::vector<stan::gm::expression>, dims_) )
67 (stan::gm::expression, K_)
69 (std::vector<stan::gm::expression>, dims_) )
72 (stan::gm::expression,
M_)
73 (stan::gm::expression,
N_)
75 (std::vector<stan::gm::expression>, dims_) )
78 (stan::gm::expression, K_)
80 (std::vector<stan::gm::expression>, dims_) )
83 (stan::gm::expression, K_)
85 (std::vector<stan::gm::expression>, dims_) )
88 (stan::gm::expression, K_)
90 (std::vector<stan::gm::expression>, dims_) )
96 struct validate_no_constraints_vis :
public boost::static_visitor<bool> {
97 std::stringstream& error_msgs_;
98 validate_no_constraints_vis(std::stringstream& error_msgs)
99 : error_msgs_(error_msgs) {
101 bool operator()(
const nil& )
const {
102 error_msgs_ <<
"nil declarations not allowed";
105 bool operator()(
const int_var_decl& x)
const {
106 if (x.range_.has_low() || x.range_.has_high()) {
107 error_msgs_ <<
"require unconstrained."
108 <<
" found range constraint." << std::endl;
113 bool operator()(
const double_var_decl& x)
const {
114 if (x.range_.has_low() || x.range_.has_high()) {
115 error_msgs_ <<
"require unconstrained."
116 <<
" found range constraint." << std::endl;
121 bool operator()(
const vector_var_decl& )
const {
124 bool operator()(
const row_vector_var_decl& )
const {
127 bool operator()(
const matrix_var_decl& )
const {
130 bool operator()(
const unit_vector_var_decl& )
const {
131 error_msgs_ <<
"require unconstrained variable declaration."
132 <<
" found unit_vector." << std::endl;
135 bool operator()(
const simplex_var_decl& )
const {
136 error_msgs_ <<
"require unconstrained variable declaration."
137 <<
" found simplex." << std::endl;
140 bool operator()(
const ordered_var_decl& )
const {
141 error_msgs_ <<
"require unconstrained variable declaration."
142 <<
" found ordered." << std::endl;
145 bool operator()(
const positive_ordered_var_decl& )
const {
146 error_msgs_ <<
"require unconstrained variable declaration."
147 <<
" found positive_ordered." << std::endl;
150 bool operator()(
const cholesky_factor_var_decl& )
const {
151 error_msgs_ <<
"require unconstrained variable declaration."
152 <<
" found cholesky_factor." << std::endl;
155 bool operator()(
const cholesky_corr_var_decl& )
const {
156 error_msgs_ <<
"require unconstrained variable declaration."
157 <<
" found cholesky_factor_corr." << std::endl;
160 bool operator()(
const cov_matrix_var_decl& )
const {
161 error_msgs_ <<
"require unconstrained variable declaration."
162 <<
" found cov_matrix." << std::endl;
165 bool operator()(
const corr_matrix_var_decl& )
const {
166 error_msgs_ <<
"require unconstrained variable declaration."
167 <<
" found corr_matrix." << std::endl;
176 variable_map& var_map)
177 : error_msgs_(error_msgs),
190 for (
size_t i = 0; i < x.args_.size(); ++i)
191 if (!boost::apply_visitor(*
this,x.args_[i].expr_))
196 var_origin origin = var_map_.get_origin(x.name_);
201 error_msgs_ <<
"non-data variables not allowed in dimension declarations."
203 <<
" found variable=" << x.name_
204 <<
"; declared in block=";
206 error_msgs_ << std::endl;
211 return boost::apply_visitor(*
this, x.y0_.expr_)
212 && boost::apply_visitor(*
this, x.theta_.expr_);
215 for (
size_t i = 0; i < x.args_.size(); ++i)
216 if (!boost::apply_visitor(*
this,x.args_[i].expr_))
221 if (!boost::apply_visitor(*
this,x.expr_.expr_))
223 for (
size_t i = 0; i < x.dimss_.size(); ++i)
224 for (
size_t j = 0; j < x.dimss_[i].size(); ++j)
225 if (!boost::apply_visitor(*
this,x.dimss_[i][j].expr_))
230 return boost::apply_visitor(*
this,x.left.expr_)
231 && boost::apply_visitor(*
this,x.right.expr_);
234 return boost::apply_visitor(*
this,x.subject.expr_);
240 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
243 template <
typename R,
typename T>
249 std::ostream& error_msgs)
const {
250 if (vm.exists(var_decl.name_)) {
253 error_msgs <<
"duplicate declaration of variable, name="
256 error_msgs <<
"; attempt to redeclare as ";
259 error_msgs <<
"; original declaration as ";
262 error_msgs << std::endl;
263 var_decl_result = var_decl;
267 && var_decl.base_type_ ==
INT_T) {
269 error_msgs <<
"integer parameters or transformed parameters are not allowed; "
270 <<
" found declared type int, parameter name=" << var_decl.name_
272 var_decl_result = var_decl;
276 vm.add(var_decl.name_,var_decl,vo);
277 var_decl_result = var_decl;
284 template <
typename T1,
typename T2,
typename T3,
typename T4>
288 const bool& declaration_ok,
289 const var_decl& var_decl,
290 std::stringstream& error_msgs)
const {
291 if (!declaration_ok) {
292 error_msgs <<
"Problem with declaration." << std::endl;
295 if (allow_constraints)
297 validate_no_constraints_vis vis(error_msgs);
298 bool constraints_ok = boost::apply_visitor(vis,var_decl.decl_);
299 return constraints_ok;
302 boost::phoenix::function<validate_decl_constraints>
309 template <
typename T1,
typename T2>
313 reserved_word_set_.insert(w);
316 template <
typename S,
typename T>
319 return s.find(x) != s.end();
323 return contains(reserved_word_set_, identifier)
324 || ( contains(function_signatures::instance().key_set(), identifier)
325 && !contains(const_fun_name_set_, identifier) );
330 const_fun_name_set_.insert(
"pi");
331 const_fun_name_set_.insert(
"e");
332 const_fun_name_set_.insert(
"sqrt2");
333 const_fun_name_set_.insert(
"log2");
334 const_fun_name_set_.insert(
"log10");
335 const_fun_name_set_.insert(
"not_a_number");
336 const_fun_name_set_.insert(
"positive_infinity");
337 const_fun_name_set_.insert(
"negative_infinity");
338 const_fun_name_set_.insert(
"epsilon");
339 const_fun_name_set_.insert(
"negative_epsilon");
356 reserve(
"unit_vector");
359 reserve(
"positive_ordered");
360 reserve(
"row_vector");
362 reserve(
"cholesky_factor_cov");
363 reserve(
"cholesky_factor_corr");
364 reserve(
"cov_matrix");
365 reserve(
"corr_matrix");
370 reserve(
"parameters");
371 reserve(
"quantities");
372 reserve(
"transformed");
373 reserve(
"generated");
395 reserve(
"constexpr");
396 reserve(
"const_cast");
403 reserve(
"dynamic_cast");
419 reserve(
"namespace");
429 reserve(
"protected");
432 reserve(
"reinterpret_cast");
438 reserve(
"static_assert");
439 reserve(
"static_cast");
444 reserve(
"thread_local");
466 const function_signatures& sigs = function_signatures::instance();
468 set<string> fun_names = sigs.key_set();
469 for (set<string>::iterator it = fun_names.begin(); it != fun_names.end(); ++it)
470 if (!contains(const_fun_name_set_, *it))
475 std::stringstream& error_msgs)
const {
476 int len = identifier.size();
478 && identifier[len-1] ==
'_'
479 && identifier[len-2] ==
'_') {
480 error_msgs <<
"variable identifier (name) may not end in double underscore (__)"
482 <<
" found identifer=" << identifier << std::endl;
485 size_t period_position = identifier.find(
'.');
486 if (period_position != std::string::npos) {
487 error_msgs <<
"variable identifier may not contain a period (.)"
489 <<
" found period at position (indexed from 0)=" << period_position
491 <<
" found identifier=" << identifier
495 if (identifier_exists(identifier)) {
496 error_msgs <<
"variable identifier (name) may not be reserved word"
498 <<
" found identifier=" << identifier
509 template <
typename T1>
513 var_decl.N_ = var_decl.M_;
516 boost::phoenix::function<copy_square_cholesky_dimension_if_necessary>
520 template <
typename T1>
529 template <
typename T1,
typename T2,
typename T3>
534 std::stringstream& error_msgs)
const {
535 if (!expr.expression_type().is_primitive_int()) {
536 error_msgs <<
"expression denoting integer required; found type="
537 << expr.expression_type() << std::endl;
548 template <
typename T1,
typename T2,
typename T3,
typename T4>
551 const expression& expr,
553 std::stringstream& error_msgs)
const {
556 validator(expr,pass,error_msgs);
562 template <
typename T1,
typename T2,
typename T3,
typename T4>
565 const expression& expr,
567 std::stringstream& error_msgs)
const {
570 validator(expr,pass,error_msgs);
578 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
584 variable_map& var_map,
585 std::stringstream& error_msgs)
const {
586 if (!expr.expression_type().is_primitive_int()) {
587 error_msgs <<
"dimension declaration requires expression denoting integer;"
589 << expr.expression_type()
594 bool only_data_dimensions = boost::apply_visitor(vis,expr.expr_);
595 pass = only_data_dimensions;
606 template <
typename T1,
typename T2>
610 std::stringstream& error_msgs)
const {
611 if (!expr.expression_type().is_primitive_double()
612 && !expr.expression_type().is_primitive_int()) {
613 error_msgs <<
"expression denoting real required; found type="
614 << expr.expression_type() << std::endl;
624 template <
typename T1,
typename T2,
typename T3,
typename T4>
627 const expression& expr,
629 std::stringstream& error_msgs)
const {
632 pass = validator(expr,error_msgs);
638 template <
typename T1,
typename T2,
typename T3,
typename T4>
641 const expression& expr,
643 std::stringstream& error_msgs)
const {
646 pass = validator(expr,error_msgs);
652 template <
typename Iterator>
654 std::stringstream& error_msgs)
657 error_msgs_(error_msgs),
659 expression_g(var_map,error_msgs),
661 expression07_g(var_map,error_msgs,expression_g)
664 using boost::spirit::qi::_1;
665 using boost::spirit::qi::_3;
666 using boost::spirit::qi::char_;
667 using boost::spirit::qi::eps;
668 using boost::spirit::qi::lexeme;
669 using boost::spirit::qi::lit;
670 using boost::spirit::qi::no_skip;
671 using boost::spirit::qi::_pass;
672 using boost::spirit::qi::_val;
673 using boost::spirit::qi::labels::_a;
674 using boost::spirit::qi::labels::_r1;
675 using boost::spirit::qi::labels::_r2;
689 boost::phoenix::ref(error_msgs))]
736 >> no_skip[!char_(
"a-zA-Z0-9_")] )
745 >> no_skip[!char_(
"a-zA-Z0-9_")] )
754 >> no_skip[!char_(
"a-zA-Z0-9_")] )
766 %= ( lit(
"row_vector")
767 >> no_skip[!char_(
"a-zA-Z0-9_")] )
780 >> no_skip[!char_(
"a-zA-Z0-9_")] )
795 %= ( lit(
"unit_vector")
796 >> no_skip[!char_(
"a-zA-Z0-9_")] )
808 >> no_skip[!char_(
"a-zA-Z0-9_")] )
820 >> no_skip[!char_(
"a-zA-Z0-9_")] )
831 %= ( lit(
"positive_ordered")
832 >> no_skip[!char_(
"a-zA-Z0-9_")] )
843 %= ( lit(
"cholesky_factor_cov")
844 >> no_skip[!char_(
"a-zA-Z0-9_")] )
861 %= ( lit(
"cholesky_factor_corr")
862 >> no_skip[!char_(
"a-zA-Z0-9_")] )
873 %= ( lit(
"cov_matrix")
874 >> no_skip[!char_(
"a-zA-Z0-9_")] )
885 %= ( lit(
"corr_matrix")
886 >> no_skip[!char_(
"a-zA-Z0-9_")] )
895 opt_dims_r.name(
"array dimensions (optional)");
899 dims_r.name(
"array dimensions");
966 %= lexeme[char_(
"a-zA-Z")
967 >> *char_(
"a-zA-Z0-9_.")]
range operator()(std::stringstream &) const
bool operator()(const bool &allow_constraints, const bool &declaration_ok, const var_decl &var_decl, std::stringstream &error_msgs) const
void operator()(cholesky_factor_var_decl &var_decl) const
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > identifier_name_r
boost::spirit::qi::rule< Iterator, matrix_var_decl(var_origin), whitespace_grammar< Iterator > > matrix_decl_r
boost::phoenix::function< empty_range > empty_range_f
boost::phoenix::function< set_int_range_lower > set_int_range_lower_f
BOOST_FUSION_ADAPT_STRUCT(stan::gm::int_var_decl,(stan::gm::range, range_)(std::string, name_)(std::vector< stan::gm::expression >, dims_)) BOOST_FUSION_ADAPT_STRUCT(stan
const int parameter_origin
void operator()(range &range, const expression &expr, bool &pass, std::stringstream &error_msgs) const
boost::spirit::qi::rule< Iterator, row_vector_var_decl(var_origin), whitespace_grammar< Iterator > > row_vector_decl_r
void operator()(range &range, const expression &expr, bool &pass, std::stringstream &error_msgs) const
bool operator()(const index_op &x) const
bool identifier_exists(const std::string &identifier) const
bool operator()(const std::string &identifier, std::stringstream &error_msgs) const
boost::spirit::qi::rule< Iterator, cholesky_factor_var_decl(var_origin), whitespace_grammar< Iterator > > cholesky_factor_decl_r
boost::spirit::qi::rule< Iterator, std::vector< expression >var_origin), whitespace_grammar< Iterator > > dims_r
void print_var_origin(std::ostream &o, const var_origin &vo)
expression07_grammar< Iterator > expression07_g
bool operator()(const variable &x) const
bool operator()(const nil &) const
std::stringstream & error_msgs_
bool operator()(const int_literal &) const
boost::phoenix::function< copy_square_cholesky_dimension_if_necessary > copy_square_cholesky_dimension_if_necessary_f
bool operator()(const array_literal &x) const
static bool contains(const S &s, const T &x)
boost::phoenix::function< validate_double_expr > validate_double_expr_f
boost::spirit::qi::rule< Iterator, unit_vector_var_decl(var_origin), whitespace_grammar< Iterator > > unit_vector_decl_r
bool operator()(const expression &expr, std::stringstream &error_msgs) const
std::vector< std::vector< typename stan::return_type< T1, T2 >::type > > integrate_ode(const F &f, const std::vector< T1 > y0, const double t0, const std::vector< double > &ts, const std::vector< T2 > &theta, const std::vector< double > &x, const std::vector< int > &x_int, std::ostream *msgs)
Return the solutions for the specified system of ordinary differential equations given the specified ...
boost::spirit::qi::rule< Iterator, vector_var_decl(var_origin), whitespace_grammar< Iterator > > vector_decl_r
bool operator()(const unary_op &x) const
boost::spirit::qi::rule< Iterator, corr_matrix_var_decl(var_origin), whitespace_grammar< Iterator > > corr_matrix_decl_r
boost::phoenix::function< validate_int_expr > validate_int_expr_f
boost::phoenix::function< validate_decl_constraints > validate_decl_constraints_f
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > identifier_r
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< bool >, std::vector< var_decl >bool, var_origin), whitespace_grammar< Iterator > > var_decls_r
boost::spirit::qi::rule< Iterator, std::vector< expression >var_origin), whitespace_grammar< Iterator > > opt_dims_r
boost::spirit::qi::rule< Iterator, cholesky_corr_var_decl(var_origin), whitespace_grammar< Iterator > > cholesky_corr_decl_r
boost::spirit::qi::rule< Iterator, ordered_var_decl(var_origin), whitespace_grammar< Iterator > > ordered_decl_r
bool operator()(const integrate_ode &x) const
boost::spirit::qi::rule< Iterator, double_var_decl(var_origin), whitespace_grammar< Iterator > > double_decl_r
std::set< std::string > const_fun_name_set_
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< bool >, var_decl(bool, var_origin), whitespace_grammar< Iterator > > var_decl_r
bool operator()(const fun &x) const
void operator()(const expression &expr, bool &pass, std::stringstream &error_msgs) const
boost::phoenix::function< validate_identifier > validate_identifier_f
void operator()(range &range, const expression &expr, bool &pass, std::stringstream &error_msgs) const
boost::spirit::qi::rule< Iterator, range(var_origin), whitespace_grammar< Iterator > > range_brackets_double_r
data_only_expression(std::stringstream &error_msgs, variable_map &var_map)
boost::phoenix::function< set_int_range_upper > set_int_range_upper_f
boost::phoenix::function< set_double_range_lower > set_double_range_lower_f
bool operator()(const binary_op &x) const
void operator()(range &range, const expression &expr, bool &pass, std::stringstream &error_msgs) const
boost::spirit::qi::rule< Iterator, range(var_origin), whitespace_grammar< Iterator > > range_brackets_int_r
const int transformed_data_origin
bool is_nil(const expression &e)
boost::spirit::qi::rule< Iterator, positive_ordered_var_decl(var_origin), whitespace_grammar< Iterator > > positive_ordered_decl_r
boost::phoenix::function< set_double_range_upper > set_double_range_upper_f
std::set< std::string > reserved_word_set_
std::stringstream & error_msgs_
boost::spirit::qi::rule< Iterator, cov_matrix_var_decl(var_origin), whitespace_grammar< Iterator > > cov_matrix_decl_r
boost::spirit::qi::rule< Iterator, int_var_decl(var_origin), whitespace_grammar< Iterator > > int_decl_r
expression_grammar< Iterator > expression_g
const int transformed_parameter_origin
bool operator()(const double_literal &) const
void operator()(const expression &expr, int var_origin, bool &pass, variable_map &var_map, std::stringstream &error_msgs) const
boost::phoenix::function< validate_int_data_expr > validate_int_data_expr_f
void reserve(const std::string &w)
boost::phoenix::function< add_var > add_var_f
boost::spirit::qi::rule< Iterator, simplex_var_decl(var_origin), whitespace_grammar< Iterator > > simplex_decl_r
void operator()(R &var_decl_result, const T &var_decl, variable_map &vm, bool &pass, const var_origin &vo, std::ostream &error_msgs) const