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>
24 (std::vector<stan::gm::expression>, dims_) )
27 (stan::gm::range, range_)
29 (std::vector<stan::gm::expression>, dims_) )
32 (stan::gm::range, range_)
33 (stan::gm::expression, M_)
35 (std::vector<stan::gm::expression>, dims_) )
38 (stan::gm::range, range_)
39 (stan::gm::expression, N_)
41 (std::vector<stan::gm::expression>, dims_) )
44 (stan::gm::range, range_)
45 (stan::gm::expression, M_)
46 (stan::gm::expression, N_)
48 (std::vector<stan::gm::expression>, dims_) )
51 (stan::gm::expression, K_)
53 (std::vector<stan::gm::expression>, dims_) )
56 (stan::gm::expression, K_)
58 (std::vector<stan::gm::expression>, dims_) )
61 (stan::gm::expression, K_)
63 (std::vector<stan::gm::expression>, dims_) )
66 (stan::gm::expression, K_)
68 (std::vector<stan::gm::expression>, dims_) )
71 (stan::gm::expression, K_)
73 (std::vector<stan::gm::expression>, dims_) )
76 (stan::gm::expression, K_)
78 (std::vector<stan::gm::expression>, dims_) )
84 struct validate_no_constraints_vis :
public boost::static_visitor<bool> {
85 std::stringstream& error_msgs_;
86 validate_no_constraints_vis(std::stringstream& error_msgs)
87 : error_msgs_(error_msgs) {
89 bool operator()(
const nil& )
const {
90 error_msgs_ <<
"nil declarations not allowed";
93 bool operator()(
const int_var_decl& x)
const {
94 if (x.range_.has_low() || x.range_.has_high()) {
95 error_msgs_ <<
"require unconstrained."
96 <<
" found range constraint." << std::endl;
101 bool operator()(
const double_var_decl& x)
const {
102 if (x.range_.has_low() || x.range_.has_high()) {
103 error_msgs_ <<
"require unconstrained."
104 <<
" found range constraint." << std::endl;
109 bool operator()(
const vector_var_decl& )
const {
112 bool operator()(
const row_vector_var_decl& )
const {
115 bool operator()(
const matrix_var_decl& )
const {
118 bool operator()(
const unit_vector_var_decl& )
const {
119 error_msgs_ <<
"require unconstrained variable declaration."
120 <<
" found unit_vector." << std::endl;
123 bool operator()(
const simplex_var_decl& )
const {
124 error_msgs_ <<
"require unconstrained variable declaration."
125 <<
" found simplex." << std::endl;
128 bool operator()(
const ordered_var_decl& )
const {
129 error_msgs_ <<
"require unconstrained variable declaration."
130 <<
" found ordered." << std::endl;
133 bool operator()(
const positive_ordered_var_decl& )
const {
134 error_msgs_ <<
"require unconstrained variable declaration."
135 <<
" found positive_ordered." << std::endl;
138 bool operator()(
const cov_matrix_var_decl& )
const {
139 error_msgs_ <<
"require unconstrained variable declaration."
140 <<
" found cov_matrix." << std::endl;
143 bool operator()(
const corr_matrix_var_decl& )
const {
144 error_msgs_ <<
"require unconstrained variable declaration."
145 <<
" found corr_matrix." << std::endl;
150 struct data_only_expression :
public boost::static_visitor<bool> {
151 std::stringstream& error_msgs_;
152 variable_map& var_map_;
153 data_only_expression(std::stringstream& error_msgs,
154 variable_map& var_map)
155 : error_msgs_(error_msgs),
158 bool operator()(
const nil& )
const {
161 bool operator()(
const int_literal& )
const {
164 bool operator()(
const double_literal& )
const {
167 bool operator()(
const array_literal& x)
const {
168 for (
size_t i = 0; i < x.args_.size(); ++i)
169 if (!boost::apply_visitor(*
this,x.args_[i].expr_))
173 bool operator()(
const variable& x)
const {
174 var_origin origin = var_map_.get_origin(x.name_);
177 error_msgs_ <<
"non-data variables not allowed in dimension declarations."
179 <<
" found variable=" << x.name_
180 <<
"; declared in block=";
182 error_msgs_ << std::endl;
186 bool operator()(
const fun& x)
const {
187 for (
size_t i = 0; i < x.args_.size(); ++i)
188 if (!boost::apply_visitor(*
this,x.args_[i].expr_))
192 bool operator()(
const index_op& x)
const {
193 if (!boost::apply_visitor(*
this,x.expr_.expr_))
195 for (
size_t i = 0; i < x.dimss_.size(); ++i)
196 for (
size_t j = 0; j < x.dimss_[i].size(); ++j)
197 if (!boost::apply_visitor(*
this,x.dimss_[i][j].expr_))
201 bool operator()(
const binary_op& x)
const {
202 return boost::apply_visitor(*
this,x.left.expr_)
203 && boost::apply_visitor(*
this,x.right.expr_);
205 bool operator()(
const unary_op& x)
const {
206 return boost::apply_visitor(*
this,x.subject.expr_);
212 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
213 struct result {
typedef T1 type; };
215 template <
typename T>
216 T operator()(
const T& var_decl,
220 std::ostream& error_msgs)
const {
221 if (vm.exists(var_decl.name_)) {
224 error_msgs <<
"variable already declared, name="
230 && var_decl.base_type_ ==
INT_T) {
232 error_msgs <<
"integer parameters or transformed parameters are not allowed; "
233 <<
" found declared type int, parameter name=" << var_decl.name_
238 vm.add(var_decl.name_,var_decl,vo);
242 boost::phoenix::function<add_var> add_var_f;
245 struct validate_decl_constraints {
246 template <
typename T1,
typename T2,
typename T3,
typename T4>
247 struct result {
typedef bool type; };
249 bool operator()(
const bool& allow_constraints,
250 const bool& declaration_ok,
251 const var_decl& var_decl,
252 std::stringstream& error_msgs)
const {
253 if (!declaration_ok) {
254 error_msgs <<
"Problem with declaration." << std::endl;
257 if (allow_constraints)
259 validate_no_constraints_vis vis(error_msgs);
260 bool constraints_ok = boost::apply_visitor(vis,var_decl.decl_);
261 return constraints_ok;
264 boost::phoenix::function<validate_decl_constraints>
265 validate_decl_constraints_f;
267 struct validate_identifier {
268 std::set<std::string> reserved_word_set_;
270 template <
typename T1,
typename T2>
271 struct result {
typedef bool type; };
273 void reserve(
const std::string& w) {
274 reserved_word_set_.insert(w);
277 validate_identifier() {
292 reserve(
"unit_vector");
295 reserve(
"positive_ordered");
296 reserve(
"row_vector");
298 reserve(
"corr_matrix");
299 reserve(
"cov_matrix");
304 reserve(
"parameters");
305 reserve(
"quantities");
306 reserve(
"transformed");
307 reserve(
"generated");
328 reserve(
"constexpr");
329 reserve(
"const_cast");
336 reserve(
"dynamic_cast");
352 reserve(
"namespace");
362 reserve(
"protected");
365 reserve(
"reinterpret_cast");
371 reserve(
"static_assert");
372 reserve(
"static_cast");
377 reserve(
"thread_local");
396 bool operator()(
const std::string& identifier,
397 std::stringstream& error_msgs)
const {
398 int len = identifier.size();
400 && identifier[len-1] ==
'_'
401 && identifier[len-2] ==
'_') {
402 error_msgs <<
"variable identifier (name) cannot end in double underscore (__)"
403 <<
"; found identifer=" << identifier;
406 if (reserved_word_set_.find(identifier) != reserved_word_set_.end()) {
407 error_msgs <<
"variable identifier (name) cannot be reserved word"
408 <<
"; found identifier=" << identifier;
414 boost::phoenix::function<validate_identifier> validate_identifier_f;
417 template <
typename T1>
418 struct result {
typedef range type; };
419 range operator()(std::stringstream& )
const {
423 boost::phoenix::function<empty_range> empty_range_f;
425 struct validate_int_expr {
426 template <
typename T1,
typename T2>
427 struct result {
typedef bool type; };
429 bool operator()(
const expression& expr,
430 std::stringstream& error_msgs)
const {
431 if (!expr.expression_type().is_primitive_int()) {
432 error_msgs <<
"expression denoting integer required; found type="
433 << expr.expression_type() << std::endl;
439 boost::phoenix::function<validate_int_expr> validate_int_expr_f;
441 struct set_int_range_lower {
442 template <
typename T1,
typename T2,
typename T3>
443 struct result {
typedef bool type; };
444 bool operator()(range& range,
445 const expression& expr,
446 std::stringstream& error_msgs)
const {
448 validate_int_expr validator;
449 return validator(expr,error_msgs);
452 boost::phoenix::function<set_int_range_lower> set_int_range_lower_f;
454 struct set_int_range_upper {
455 template <
typename T1,
typename T2,
typename T3>
456 struct result {
typedef bool type; };
457 bool operator()(range& range,
458 const expression& expr,
459 std::stringstream& error_msgs)
const {
461 validate_int_expr validator;
462 return validator(expr,error_msgs);
465 boost::phoenix::function<set_int_range_upper> set_int_range_upper_f;
469 struct validate_int_data_expr {
470 template <
typename T1,
typename T2,
typename T3>
471 struct result {
typedef bool type; };
473 bool operator()(
const expression& expr,
474 variable_map& var_map,
475 std::stringstream& error_msgs)
const {
476 if (!expr.expression_type().is_primitive_int()) {
477 error_msgs <<
"dimension declaration requires expression denoting integer;"
479 << expr.expression_type()
483 data_only_expression vis(error_msgs,var_map);
484 bool only_data_dimensions = boost::apply_visitor(vis,expr.expr_);
485 return only_data_dimensions;
488 boost::phoenix::function<validate_int_data_expr> validate_int_data_expr_f;
490 struct validate_double_expr {
491 template <
typename T1,
typename T2>
492 struct result {
typedef bool type; };
494 bool operator()(
const expression& expr,
495 std::stringstream& error_msgs)
const {
496 if (!expr.expression_type().is_primitive_double()
497 && !expr.expression_type().is_primitive_int()) {
498 error_msgs <<
"expression denoting double required; found type="
499 << expr.expression_type() << std::endl;
505 boost::phoenix::function<validate_double_expr> validate_double_expr_f;
508 struct set_double_range_lower {
509 template <
typename T1,
typename T2,
typename T3>
510 struct result {
typedef bool type; };
511 bool operator()(range& range,
512 const expression& expr,
513 std::stringstream& error_msgs)
const {
515 validate_double_expr validator;
516 return validator(expr,error_msgs);
519 boost::phoenix::function<set_double_range_lower> set_double_range_lower_f;
521 struct set_double_range_upper {
522 template <
typename T1,
typename T2,
typename T3>
523 struct result {
typedef bool type; };
524 bool operator()(range& range,
525 const expression& expr,
526 std::stringstream& error_msgs)
const {
528 validate_double_expr validator;
529 return validator(expr,error_msgs);
532 boost::phoenix::function<set_double_range_upper> set_double_range_upper_f;
535 template <
typename Iterator>
536 var_decls_grammar<Iterator>::var_decls_grammar(variable_map& var_map,
537 std::stringstream& error_msgs)
538 : var_decls_grammar::base_type(var_decls_r),
540 error_msgs_(error_msgs),
541 expression_g(var_map,error_msgs),
542 expression07_g(var_map,error_msgs,
false)
545 using boost::spirit::qi::_1;
546 using boost::spirit::qi::_3;
547 using boost::spirit::qi::char_;
548 using boost::spirit::qi::eps;
549 using boost::spirit::qi::lexeme;
550 using boost::spirit::qi::lit;
551 using boost::spirit::qi::no_skip;
552 using boost::spirit::qi::_pass;
553 using boost::spirit::qi::_val;
554 using boost::spirit::qi::labels::_a;
555 using boost::spirit::qi::labels::_r1;
556 using boost::spirit::qi::labels::_r2;
558 var_decls_r.name(
"variable declarations");
560 %= *var_decl_r(_r1,_r2);
565 var_decl_r.name(
"variable declaration");
568 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
569 boost::phoenix::ref(error_msgs))]
571 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
572 boost::phoenix::ref(error_msgs_))]
574 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
575 boost::phoenix::ref(error_msgs_))]
576 | row_vector_decl_r(_r2)
577 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
578 boost::phoenix::ref(error_msgs_))]
580 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
581 boost::phoenix::ref(error_msgs_))]
582 | unit_vector_decl_r(_r2)
583 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
584 boost::phoenix::ref(error_msgs_))]
585 | simplex_decl_r(_r2)
586 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
587 boost::phoenix::ref(error_msgs_))]
588 | ordered_decl_r(_r2)
589 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
590 boost::phoenix::ref(error_msgs_))]
591 | positive_ordered_decl_r(_r2)
592 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
593 boost::phoenix::ref(error_msgs_))]
594 | corr_matrix_decl_r(_r2)
595 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
596 boost::phoenix::ref(error_msgs_))]
597 | cov_matrix_decl_r(_r2)
598 [_val = add_var_f(_1,boost::phoenix::ref(var_map_),_a,_r2,
599 boost::phoenix::ref(error_msgs_))]
603 = validate_decl_constraints_f(_r1,_a,_val,
604 boost::phoenix::ref(error_msgs_))]
607 int_decl_r.name(
"integer declaration");
610 >> no_skip[!char_(
"a-zA-Z0-9_")]
611 > -range_brackets_int_r(_r1)
617 double_decl_r.name(
"real declaration");
620 >> no_skip[!char_(
"a-zA-Z0-9_")]
621 > -range_brackets_double_r(_r1)
626 vector_decl_r.name(
"vector declaration");
629 > -range_brackets_double_r(_r1)
632 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
638 row_vector_decl_r.name(
"row vector declaration");
641 > -range_brackets_double_r(_r1)
644 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
650 matrix_decl_r.name(
"matrix declaration");
653 > -range_brackets_double_r(_r1)
656 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
659 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
665 unit_vector_decl_r.name(
"unit_vector declaration");
667 %= lit(
"unit_vector")
670 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
676 simplex_decl_r.name(
"simplex declaration");
681 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
687 ordered_decl_r.name(
"ordered declaration");
692 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
698 positive_ordered_decl_r.name(
"positive_ordered declaration");
699 positive_ordered_decl_r
700 %= lit(
"positive_ordered")
703 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
709 corr_matrix_decl_r.name(
"correlation matrix declaration");
711 %= lit(
"corr_matrix")
714 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
720 cov_matrix_decl_r.name(
"covariance matrix declaration");
725 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
731 opt_dims_r.name(
"array dimensions (optional)");
735 dims_r.name(
"array dimensions");
739 [_pass = validate_int_data_expr_f(_1,
740 boost::phoenix::ref(var_map_),
741 boost::phoenix::ref(error_msgs_))]
746 range_brackets_int_r.name(
"integer range expression pair, brackets");
748 = lit(
'<') [_val = empty_range_f(boost::phoenix::ref(error_msgs_))]
752 >> expression07_g(_r1)
753 [ _pass = set_int_range_lower_f(_val,_1,
754 boost::phoenix::ref(error_msgs_)) ])
758 >> expression07_g(_r1)
759 [ _pass = set_int_range_upper_f(_val,_1,
760 boost::phoenix::ref(error_msgs_)) ] ) )
764 >> expression07_g(_r1)
765 [ _pass = set_int_range_upper_f(_val,_1,
766 boost::phoenix::ref(error_msgs_)) ])
770 range_brackets_double_r.name(
"real range expression pair, brackets");
771 range_brackets_double_r
772 = lit(
'<') [_val = empty_range_f(boost::phoenix::ref(error_msgs_))]
776 > expression07_g(_r1)
777 [ _pass = set_double_range_lower_f(_val,_1,
778 boost::phoenix::ref(error_msgs_)) ])
782 > expression07_g(_r1)
783 [ _pass = set_double_range_upper_f(_val,_1,
784 boost::phoenix::ref(error_msgs_)) ] ) )
788 > expression07_g(_r1)
789 [ _pass = set_double_range_upper_f(_val,_1,
790 boost::phoenix::ref(error_msgs_)) ])
794 identifier_r.name(
"identifier");
797 [_pass = validate_identifier_f(_val,boost::phoenix::ref(error_msgs_))]
800 identifier_name_r.name(
"identifier subrule");
802 %= lexeme[char_(
"a-zA-Z")
803 >> *char_(
"a-zA-Z0-9_.")]
807 range_r.name(
"range expression pair, colon");
810 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))]
813 [_pass = validate_int_expr_f(_1,boost::phoenix::ref(error_msgs_))];