1 #ifndef __STAN__GM__PARSER__VAR_DECLS_GRAMMAR_DEF__HPP__ 2 #define __STAN__GM__PARSER__VAR_DECLS_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> 30 #include <boost/spirit/include/qi_numeric.hpp> 52 (std::vector<stan::gm::expression>, dims_) )
57 (std::vector<stan::gm::expression>, dims_) )
63 (std::vector<stan::gm::expression>, dims_) )
69 (std::vector<stan::gm::expression>, dims_) )
76 (std::vector<stan::gm::expression>, dims_) )
81 (std::vector<stan::gm::expression>, dims_) )
86 (std::vector<stan::gm::expression>, dims_) )
91 (std::vector<stan::gm::expression>, dims_) )
96 (std::vector<stan::gm::expression>, dims_) )
101 (std::vector<stan::gm::expression>, dims_) )
107 struct validate_no_constraints_vis :
public boost::static_visitor<bool> {
108 std::stringstream& error_msgs_;
109 validate_no_constraints_vis(std::stringstream& error_msgs)
110 : error_msgs_(error_msgs) {
112 bool operator()(
const nil& x)
const {
113 error_msgs_ <<
"nil declarations not allowed";
116 bool operator()(
const int_var_decl& x)
const {
117 if (x.range_.has_low() || x.range_.has_high()) {
118 error_msgs_ <<
"require unconstrained." 119 <<
" found range constraint." << std::endl;
124 bool operator()(
const double_var_decl& x)
const {
125 if (x.range_.has_low() || x.range_.has_high()) {
126 error_msgs_ <<
"require unconstrained." 127 <<
" found range constraint." << std::endl;
132 bool operator()(
const vector_var_decl& x)
const {
135 bool operator()(
const row_vector_var_decl& x)
const {
138 bool operator()(
const matrix_var_decl& x)
const {
141 bool operator()(
const simplex_var_decl& x)
const {
142 error_msgs_ <<
"require unconstrained variable declaration." 143 <<
" found simplex." << std::endl;
146 bool operator()(
const ordered_var_decl& x)
const {
147 error_msgs_ <<
"require unconstrained variable declaration." 148 <<
" found ordered." << std::endl;
151 bool operator()(
const positive_ordered_var_decl& x)
const {
152 error_msgs_ <<
"require unconstrained variable declaration." 153 <<
" found positive_ordered." << std::endl;
156 bool operator()(
const cov_matrix_var_decl& x)
const {
157 error_msgs_ <<
"require unconstrained variable declaration." 158 <<
" found cov_matrix." << std::endl;
161 bool operator()(
const corr_matrix_var_decl& x)
const {
162 error_msgs_ <<
"require unconstrained variable declaration." 163 <<
" found corr_matrix." << std::endl;
168 struct data_only_expression :
public boost::static_visitor<bool> {
169 std::stringstream& error_msgs_;
170 variable_map& var_map_;
171 data_only_expression(std::stringstream& error_msgs,
172 variable_map& var_map)
173 : error_msgs_(error_msgs),
176 bool operator()(
const nil&
e)
const {
179 bool operator()(
const int_literal& x)
const {
182 bool operator()(
const double_literal& x)
const {
185 bool operator()(
const array_literal& x)
const {
186 for (
size_t i = 0; i < x.args_.size(); ++i)
187 if (!boost::apply_visitor(*
this,x.args_[i].expr_))
191 bool operator()(
const variable& x)
const {
192 var_origin origin = var_map_.get_origin(x.name_);
195 error_msgs_ <<
"non-data variables not allowed in dimension declarations." 197 <<
" found variable=" << x.name_
198 <<
"; declared in block=";
200 error_msgs_ << std::endl;
204 bool operator()(
const fun& x)
const {
205 for (
size_t i = 0; i < x.args_.size(); ++i)
206 if (!boost::apply_visitor(*
this,x.args_[i].expr_))
210 bool operator()(
const index_op& x)
const {
211 if (!boost::apply_visitor(*
this,x.expr_.expr_))
213 for (
size_t i = 0; i < x.dimss_.size(); ++i)
214 for (
size_t j = 0; j < x.dimss_[i].size(); ++j)
215 if (!boost::apply_visitor(*
this,x.dimss_[i][j].expr_))
219 bool operator()(
const binary_op& x)
const {
220 return boost::apply_visitor(*
this,x.left.expr_)
221 && boost::apply_visitor(*
this,x.right.expr_);
223 bool operator()(
const unary_op& x)
const {
224 return boost::apply_visitor(*
this,x.subject.expr_);
230 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
231 struct result {
typedef T1 type; };
233 template <
typename T>
234 T operator()(
const T& var_decl,
238 std::ostream& error_msgs)
const {
239 if (vm.exists(var_decl.name_)) {
242 error_msgs <<
"variable already declared, name=" 248 && var_decl.base_type_ ==
INT_T) {
250 error_msgs <<
"integer parameters or transformed parameters are not allowed; " 251 <<
" found declared type int, parameter name=" << var_decl.name_
256 vm.add(var_decl.name_,var_decl,vo);
260 boost::phoenix::function<add_var> add_var_f;
263 struct validate_decl_constraints {
264 template <
typename T1,
typename T2,
typename T3,
typename T4>
265 struct result {
typedef bool type; };
267 bool operator()(
const bool& allow_constraints,
268 const bool& declaration_ok,
269 const var_decl& var_decl,
270 std::stringstream& error_msgs)
const {
271 if (!declaration_ok) {
272 error_msgs <<
"Problem with declaration." << std::endl;
275 if (allow_constraints)
277 validate_no_constraints_vis vis(error_msgs);
278 bool constraints_ok = boost::apply_visitor(vis,var_decl.decl_);
279 return constraints_ok;
282 boost::phoenix::function<validate_decl_constraints>
283 validate_decl_constraints_f;
285 struct validate_identifier {
286 std::set<std::string> reserved_word_set_;
288 template <
typename T1,
typename T2>
289 struct result {
typedef bool type; };
291 void reserve(
const std::string& w) {
292 reserved_word_set_.insert(w);
295 validate_identifier() {
312 reserve(
"positive_ordered");
313 reserve(
"row_vector");
315 reserve(
"corr_matrix");
316 reserve(
"cov_matrix");
321 reserve(
"parameters");
322 reserve(
"quantities");
323 reserve(
"transformed");
324 reserve(
"generated");
345 reserve(
"constexpr");
346 reserve(
"const_cast");
353 reserve(
"dynamic_cast");
369 reserve(
"namespace");
379 reserve(
"protected");
382 reserve(
"reinterpret_cast");
388 reserve(
"static_assert");
389 reserve(
"static_cast");
394 reserve(
"thread_local");
413 bool operator()(
const std::string& identifier,
414 std::stringstream& error_msgs)
const {
415 int len = identifier.size();
417 && identifier[len-1] ==
'_' 418 && identifier[len-2] ==
'_') {
419 error_msgs <<
"variable identifier (name) cannot end in double underscore (__)" 420 <<
"; found identifer=" << identifier;
423 if (reserved_word_set_.find(identifier) != reserved_word_set_.end()) {
424 error_msgs <<
"variable identifier (name) cannot be reserved word" 425 <<
"; found identifier=" << identifier;
431 boost::phoenix::function<validate_identifier> validate_identifier_f;
434 template <
typename T1>
435 struct result {
typedef range type; };
436 range operator()(std::stringstream& error_msgs)
const {
440 boost::phoenix::function<empty_range> empty_range_f;
442 struct validate_int_expr {
443 template <
typename T1,
typename T2>
444 struct result {
typedef bool type; };
446 bool operator()(
const expression& expr,
447 std::stringstream& error_msgs)
const {
448 if (!expr.expression_type().is_primitive_int()) {
449 error_msgs <<
"expression denoting integer required; found type=" 450 << expr.expression_type() << std::endl;
456 boost::phoenix::function<validate_int_expr> validate_int_expr_f;
458 struct set_int_range_lower {
459 template <
typename T1,
typename T2,
typename T3>
460 struct result {
typedef bool type; };
461 bool operator()(range& range,
462 const expression& expr,
463 std::stringstream& error_msgs)
const {
465 validate_int_expr validator;
466 return validator(expr,error_msgs);
469 boost::phoenix::function<set_int_range_lower> set_int_range_lower_f;
471 struct set_int_range_upper {
472 template <
typename T1,
typename T2,
typename T3>
473 struct result {
typedef bool type; };
474 bool operator()(range& range,
475 const expression& expr,
476 std::stringstream& error_msgs)
const {
478 validate_int_expr validator;
479 return validator(expr,error_msgs);
482 boost::phoenix::function<set_int_range_upper> set_int_range_upper_f;
486 struct validate_int_data_expr {
487 template <
typename T1,
typename T2,
typename T3>
488 struct result {
typedef bool type; };
490 bool operator()(
const expression& expr,
491 variable_map& var_map,
492 std::stringstream& error_msgs)
const {
493 if (!expr.expression_type().is_primitive_int()) {
494 error_msgs <<
"dimension declaration requires expression denoting integer;" 496 << expr.expression_type()
500 data_only_expression vis(error_msgs,var_map);
501 bool only_data_dimensions = boost::apply_visitor(vis,expr.expr_);
502 return only_data_dimensions;
505 boost::phoenix::function<validate_int_data_expr> validate_int_data_expr_f;
507 struct validate_double_expr {
508 template <
typename T1,
typename T2>
509 struct result {
typedef bool type; };
511 bool operator()(
const expression& expr,
512 std::stringstream& error_msgs)
const {
513 if (!expr.expression_type().is_primitive_double()
514 && !expr.expression_type().is_primitive_int()) {
515 error_msgs <<
"expression denoting double required; found type=" 516 << expr.expression_type() << std::endl;
522 boost::phoenix::function<validate_double_expr> validate_double_expr_f;
525 struct set_double_range_lower {
526 template <
typename T1,
typename T2,
typename T3>
527 struct result {
typedef bool type; };
528 bool operator()(range& range,
529 const expression& expr,
530 std::stringstream& error_msgs)
const {
532 validate_double_expr validator;
533 return validator(expr,error_msgs);
536 boost::phoenix::function<set_double_range_lower> set_double_range_lower_f;
538 struct set_double_range_upper {
539 template <
typename T1,
typename T2,
typename T3>
540 struct result {
typedef bool type; };
541 bool operator()(range& range,
542 const expression& expr,
543 std::stringstream& error_msgs)
const {
545 validate_double_expr validator;
546 return validator(expr,error_msgs);
549 boost::phoenix::function<set_double_range_upper> set_double_range_upper_f;
552 template <
typename Iterator>
554 std::stringstream& error_msgs)
555 : var_decls_grammar::base_type(var_decls_r),
557 error_msgs_(error_msgs),
558 expression_g(var_map,error_msgs),
559 expression07_g(var_map,error_msgs,false)
562 using boost::spirit::qi::_1;
563 using boost::spirit::qi::_3;
564 using boost::spirit::qi::char_;
565 using boost::spirit::qi::eps;
566 using boost::spirit::qi::lexeme;
567 using boost::spirit::qi::lit;
568 using boost::spirit::qi::no_skip;
569 using boost::spirit::qi::_pass;
570 using boost::spirit::qi::_val;
571 using boost::spirit::qi::labels::_a;
572 using boost::spirit::qi::labels::_r1;
573 using boost::spirit::qi::labels::_r2;
583 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
584 boost::phoenix::ref(error_msgs))]
586 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
589 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
592 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
595 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
598 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
601 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
604 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
607 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
610 [_val = add_var_f(_1,boost::phoenix::ref(
var_map_),_a,_r2,
615 = validate_decl_constraints_f(_r1,_a,_val,
622 >> no_skip[!char_(
"a-zA-Z0-9_")]
632 >> no_skip[!char_(
"a-zA-Z0-9_")]
644 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
656 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
668 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
671 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
682 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
693 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
701 %= lit(
"positive_ordered")
704 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
712 %= lit(
"corr_matrix")
715 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
726 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
732 opt_dims_r.name(
"array dimensions (optional)");
736 dims_r.name(
"array dimensions");
740 [_pass = validate_int_data_expr_f(_1,
749 = lit(
'<') [_val = empty_range_f(boost::phoenix::ref(
error_msgs_))]
754 [ _pass = set_int_range_lower_f(_val,_1,
760 [ _pass = set_int_range_upper_f(_val,_1,
766 [ _pass = set_int_range_upper_f(_val,_1,
773 = lit(
'<') [_val = empty_range_f(boost::phoenix::ref(
error_msgs_))]
778 [ _pass = set_double_range_lower_f(_val,_1,
784 [ _pass = set_double_range_upper_f(_val,_1,
790 [ _pass = set_double_range_upper_f(_val,_1,
798 [_pass = validate_identifier_f(_val,boost::phoenix::ref(
error_msgs_))]
803 %= lexeme[char_(
"a-zA-Z")
804 >> *char_(
"a-zA-Z0-9_.")]
808 range_r.name(
"range expression pair, colon");
811 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))]
814 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(
error_msgs_))];
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > identifier_name_r
const int parameter_origin
boost::spirit::qi::rule< Iterator, range(), whitespace_grammar< Iterator > > range_brackets_int_r
boost::spirit::qi::rule< Iterator, range(), whitespace_grammar< Iterator > > range_r
boost::spirit::qi::rule< Iterator, simplex_var_decl(), whitespace_grammar< Iterator > > simplex_decl_r
Probability, optimization and sampling library.
boost::spirit::qi::rule< Iterator, vector_var_decl(), whitespace_grammar< Iterator > > vector_decl_r
boost::spirit::qi::rule< Iterator, corr_matrix_var_decl(), whitespace_grammar< Iterator > > corr_matrix_decl_r
void print_var_origin(std::ostream &o, const var_origin &vo)
boost::spirit::qi::rule< Iterator, positive_ordered_var_decl(), whitespace_grammar< Iterator > > positive_ordered_decl_r
boost::spirit::qi::rule< Iterator, std::vector< expression >), whitespace_grammar< Iterator > > opt_dims_r
boost::spirit::qi::rule< Iterator, row_vector_var_decl(), whitespace_grammar< Iterator > > row_vector_decl_r
boost::spirit::qi::rule< Iterator, std::vector< expression >), whitespace_grammar< Iterator > > dims_r
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
boost::spirit::qi::rule< Iterator, int_var_decl(), whitespace_grammar< Iterator > > int_decl_r
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
expression_grammar< Iterator > expression07_g
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< bool >, var_decl(bool, var_origin), whitespace_grammar< Iterator > > var_decl_r
boost::spirit::qi::rule< Iterator, cov_matrix_var_decl(), whitespace_grammar< Iterator > > cov_matrix_decl_r
boost::spirit::qi::rule< Iterator, range(), whitespace_grammar< Iterator > > range_brackets_double_r
var_decls_grammar(variable_map &var_map, std::stringstream &error_msgs)
const int transformed_data_origin
double e()
Return the base of the natural logarithm.
std::stringstream & error_msgs_
expression_grammar< Iterator > expression_g
boost::spirit::qi::rule< Iterator, double_var_decl(), whitespace_grammar< Iterator > > double_decl_r
boost::spirit::qi::rule< Iterator, matrix_var_decl(), whitespace_grammar< Iterator > > matrix_decl_r
const int transformed_parameter_origin
boost::spirit::qi::rule< Iterator, ordered_var_decl(), whitespace_grammar< Iterator > > ordered_decl_r