Stan  2.10.0
probability, sampling & optimization
statement_grammar_def.hpp
Go to the documentation of this file.
1 #ifndef STAN_LANG_GRAMMARS_STATEMENT_GRAMMAR_DEF_HPP
2 #define STAN_LANG_GRAMMARS_STATEMENT_GRAMMAR_DEF_HPP
3 
4 #include <stan/lang/ast.hpp>
12 #include <boost/spirit/include/qi.hpp>
13 #include <boost/phoenix/phoenix.hpp>
14 #include <sstream>
15 #include <string>
16 #include <vector>
17 
19  (stan::lang::variable, lhs_var_)
20  (std::vector<stan::lang::idx>, idxs_)
21  (stan::lang::expression, rhs_) )
22 
23 BOOST_FUSION_ADAPT_STRUCT(stan::lang::assignment,
24  (stan::lang::variable_dims, var_dims_)
25  (stan::lang::expression, expr_) )
26 
27 BOOST_FUSION_ADAPT_STRUCT(stan::lang::variable_dims,
28  (std::string, name_)
29  (std::vector<stan::lang::expression>, dims_) )
30 
31 BOOST_FUSION_ADAPT_STRUCT(stan::lang::distribution,
32  (std::string, family_)
33  (std::vector<stan::lang::expression>, args_) )
34 
35 BOOST_FUSION_ADAPT_STRUCT(stan::lang::for_statement,
36  (std::string, variable_)
37  (stan::lang::range, range_)
38  (stan::lang::statement, statement_) )
39 
40 BOOST_FUSION_ADAPT_STRUCT(stan::lang::return_statement,
41  (stan::lang::expression, return_value_) )
42 
43 BOOST_FUSION_ADAPT_STRUCT(stan::lang::print_statement,
44  (std::vector<stan::lang::printable>, printables_) )
45 
46 BOOST_FUSION_ADAPT_STRUCT(stan::lang::reject_statement,
47  (std::vector<stan::lang::printable>, printables_) )
48 
49 BOOST_FUSION_ADAPT_STRUCT(stan::lang::increment_log_prob_statement,
50  (stan::lang::expression, log_prob_) )
51 
53  (stan::lang::expression, expr_)
54  (stan::lang::distribution, dist_)
55  (stan::lang::range, truncation_) )
56 
57 BOOST_FUSION_ADAPT_STRUCT(stan::lang::statements,
58  (std::vector<stan::lang::var_decl>, local_decl_)
59  (std::vector<stan::lang::statement>, statements_) )
60 
61 namespace stan {
62 
63  namespace lang {
64 
65  template <typename Iterator>
66  statement_grammar<Iterator>::statement_grammar(variable_map& var_map,
67  std::stringstream& error_msgs)
68  : statement_grammar::base_type(statement_r),
69  var_map_(var_map),
70  error_msgs_(error_msgs),
71  expression_g(var_map, error_msgs),
72  var_decls_g(var_map, error_msgs),
73  statement_2_g(var_map, error_msgs, *this),
74  indexes_g(var_map, error_msgs, expression_g) {
75  using boost::spirit::qi::_1;
76  using boost::spirit::qi::char_;
77  using boost::spirit::qi::eps;
78  using boost::spirit::qi::lexeme;
79  using boost::spirit::qi::lit;
80  using boost::spirit::qi::no_skip;
81  using boost::spirit::qi::_pass;
82  using boost::spirit::qi::_val;
83  using boost::spirit::qi::raw;
84 
85  using boost::spirit::qi::labels::_a;
86  using boost::spirit::qi::labels::_r1;
87  using boost::spirit::qi::labels::_r2;
88  using boost::spirit::qi::labels::_r3;
89 
90  using boost::phoenix::begin;
91  using boost::phoenix::end;
92 
93  // inherited features
94  // _r1 true if sample_r allowed
95  // _r2 source of variables allowed for assignments
96  // _r3 true if return_r allowed
97 
98  // raw[ ] just to wrap to get line numbers
99  statement_r.name("statement");
101  = raw[statement_sub_r(_r1, _r2, _r3)[assign_lhs_f(_val, _1)]]
102  [add_line_number_f(_val, begin(_1), end(_1))];
103 
104  statement_sub_r.name("statement");
106  %= no_op_statement_r // key ";"
107  | statement_seq_r(_r1, _r2, _r3) // key "{"
108  | increment_log_prob_statement_r(_r1, _r2) // key "increment_log_prob"
109  | increment_target_statement_r(_r1, _r2) // key "target"
110  | for_statement_r(_r1, _r2, _r3) // key "for"
111  | while_statement_r(_r1, _r2, _r3) // key "while"
112  | statement_2_g(_r1, _r2, _r3) // key "if"
113  | print_statement_r(_r2) // key "print"
114  | reject_statement_r(_r2) // key "reject"
115  | return_statement_r(_r2) // key "return"
116  | void_return_statement_r(_r2) // key "return"
117  | assignment_r(_r2) // lvalue "<-"
118  | assgn_r(_r2) // var[idxs] <- expr
119  | sample_r(_r1, _r2) // expression "~"
120  | expression_g(_r2) // expression
121  [expression_as_statement_f(_pass, _1,
122  boost::phoenix::ref(error_msgs_))];
123 
124  // _r1, _r2, _r3 same as statement_r
125  statement_seq_r.name("sequence of statements");
127  %= lit('{')
129  > *statement_r(_r1, _r2, _r3)
130  > lit('}')
131  > eps[unscope_locals_f(_a, boost::phoenix::ref(var_map_))];
132 
134  %= var_decls_g(false, local_origin); // - constants
135 
136  // inherited _r1 = true if samples allowed as statements
137  increment_log_prob_statement_r.name("increment log prob statement");
139  %= (lit("increment_log_prob") >> no_skip[!char_("a-zA-Z0-9_")])
140  > eps[deprecate_increment_log_prob_f(boost::phoenix::ref(error_msgs_))]
141  > eps[validate_allow_sample_f(_r1, _pass,
142  boost::phoenix::ref(error_msgs_))]
143  > lit('(')
144  > expression_g(_r2)
146  boost::phoenix::ref(error_msgs_))]
147  > lit(')')
148  > lit(';');
149 
150  // just variant syntax for increment_log_prob_r (see above)
151  increment_target_statement_r.name("increment target statement");
153  %= (lit("target") >> lit("+="))
154  > eps[validate_allow_sample_f(_r1, _pass,
155  boost::phoenix::ref(error_msgs_))]
156  > expression_g(_r2)
158  boost::phoenix::ref(error_msgs_))]
159  > lit(';');
160 
161  // _r1, _r2, _r3 same as statement_r
162  while_statement_r.name("while statement");
164  = (lit("while") >> no_skip[!char_("a-zA-Z0-9_")])
165  > lit('(')
166  > expression_g(_r2)
167  [add_while_condition_f(_val, _1, _pass,
168  boost::phoenix::ref(error_msgs_))]
169  > lit(')')
170  > statement_r(_r1, _r2, _r3)
171  [add_while_body_f(_val, _1)];
172 
173 
174  // _r1, _r2, _r3 same as statement_r
175  for_statement_r.name("for statement");
177  %= (lit("for") >> no_skip[!char_("a-zA-Z0-9_")])
178  > lit('(')
179  > identifier_r[add_loop_identifier_f(_1, _a, _pass,
180  boost::phoenix::ref(var_map_),
181  boost::phoenix::ref(error_msgs_))]
182  > lit("in")
183  > range_r(_r2)
184  > lit(')')
185  > statement_r(_r1, _r2, _r3)
186  > eps
187  [remove_loop_identifier_f(_a, boost::phoenix::ref(var_map_))];
188 
189  print_statement_r.name("print statement");
191  %= (lit("print") >> no_skip[!char_("a-zA-Z0-9_")])
192  > lit('(')
193  > (printable_r(_r1) % ',')
194  > lit(')');
195 
196  // reject
197  reject_statement_r.name("reject statement");
199  %= (lit("reject") >> no_skip[!char_("a-zA-Z0-9_")])
200  > lit('(')
201  > (printable_r(_r1) % ',')
202  > lit(')');
203 
204  printable_r.name("printable");
207  | expression_g(_r1);
208 
209  printable_string_r.name("printable quoted string");
211  %= lit('"')
212  > no_skip[*char_("a-zA-Z0-9/~!@#$%^&*()`_+-={}|[]:;'<>?,./ ")]
213  > lit('"');
214 
215  identifier_r.name("identifier");
217  %= (lexeme[char_("a-zA-Z")
218  >> *char_("a-zA-Z0-9_.")]);
219 
220  range_r.name("range expression pair, colon");
221  range_r
222  %= expression_g(_r1)
223  [validate_int_expr_warn_f(_1, _pass,
224  boost::phoenix::ref(error_msgs_))]
225  >> lit(':')
226  >> expression_g(_r1)
227  [validate_int_expr_warn_f(_1, _pass,
228  boost::phoenix::ref(error_msgs_))];
229 
230  // this one comes before assgn_r to deal with simple assignment
231  assignment_r.name("variable assignment by expression");
233  %= var_lhs_r(_r1)
235  > expression_rhs_r(_r1)
236  [validate_assignment_f(_val, _r1, _pass,
237  boost::phoenix::ref(var_map_),
238  boost::phoenix::ref(error_msgs_))]
239  > lit(';');
240 
241  assgn_r.name("indexed variable assginment statement");
242  assgn_r
243  %= var_r(_r1)
244  >> indexes_g(_r1)
246  >> (eps > expression_rhs_r(_r1))
247  [validate_assgn_f(_val, _pass, boost::phoenix::ref(error_msgs_))]
248  > lit(';');
249 
250  assignment_operator_r.name("assignment operator");
252  %= lit("<-")
253  [deprecate_old_assignment_op_f(boost::phoenix::ref(error_msgs_))]
254  | (lit("=") >> no_skip[!char_("=")]);
255 
256  var_r.name("variable for left-hand side of assignment");
257  var_r
258  = identifier_r
259  [identifier_to_var_f(_1, _r1, _val, _pass,
260  boost::phoenix::ref(var_map_),
261  boost::phoenix::ref(error_msgs_))];
262 
263  // separate rule for name on expectation failure
264  expression_rhs_r.name("expression assignable to left-hand side");
266  %= expression_g(_r1);
267 
268  var_lhs_r.name("variable and array dimensions");
269  var_lhs_r
270  %= identifier_r
271  >> opt_dims_r(_r1);
272 
273  opt_dims_r.name("array dimensions (optional)");
274  opt_dims_r
275  %= *dims_r(_r1);
276 
277  dims_r.name("array dimensions");
278  // uses silent test because errors will be reported in sliced rules
279  dims_r
280  %= lit('[')
281  >> (expression_g(_r1)[validate_int_expression_f(_1, _pass)] % ',')
282  >> lit(']');
283 
284  // inherited _r1 = true if samples allowed as statements
285  sample_r.name("distribution of expression");
286  sample_r
287  %= (expression_g(_r2)
288  >> lit('~'))
289  > eps
290  [validate_allow_sample_f(_r1, _pass,
291  boost::phoenix::ref(error_msgs_))]
292  > distribution_r(_r2)
293  > -truncation_range_r(_r2)
294  > lit(';')
295  > eps
296  [validate_sample_f(_val, boost::phoenix::ref(var_map_),
297  _pass, boost::phoenix::ref(error_msgs_))];
298 
299  distribution_r.name("distribution and parameters");
301  %= (identifier_r
302  >> lit('(')
303  >> -(expression_g(_r1) % ','))
304  > lit(')');
305 
306  truncation_range_r.name("range pair");
308  %= lit('T')
309  > lit('[')
310  > -expression_g(_r1)
311  > lit(',')
312  > -expression_g(_r1)
313  > lit(']');
314 
315  // _r1 = allow sampling, _r2 = var origin
316  return_statement_r.name("return statement");
318  %= (lit("return") >> no_skip[!char_("a-zA-Z0-9_")])
319  >> expression_g(_r1)
320  >> lit(';') [validate_return_allowed_f(_r1, _pass,
321  boost::phoenix::ref(error_msgs_))];
322 
323  // _r1 = var origin
324  void_return_statement_r.name("void return statement");
326  = lit("return")[set_void_return_f(_val)] // = expression()]
327  >> lit(';')[validate_void_return_allowed_f(_r1, _pass,
328  boost::phoenix::ref(error_msgs_))];
329 
330  no_op_statement_r.name("no op statement");
332  %= lit(';')[set_no_op_f(_val)];
333  }
334 
335  }
336 }
337 #endif
boost::phoenix::function< validate_return_allowed > validate_return_allowed_f
boost::spirit::qi::rule< Iterator, increment_log_prob_statement(bool, var_origin), whitespace_grammar< Iterator > > increment_target_statement_r
boost::phoenix::function< add_while_body > add_while_body_f
boost::spirit::qi::rule< Iterator, std::vector< expression >var_origin), whitespace_grammar< Iterator > > dims_r
indexes_grammar< Iterator > indexes_g
boost::phoenix::function< validate_assgn > validate_assgn_f
boost::spirit::qi::rule< Iterator, assignment(var_origin), whitespace_grammar< Iterator > > assignment_r
boost::spirit::qi::rule< Iterator, range(var_origin), whitespace_grammar< Iterator > > range_r
boost::spirit::qi::rule< Iterator, std::vector< var_decl >), whitespace_grammar< Iterator > > local_var_decls_r
void sample(stan::mcmc::base_mcmc *sampler, int num_warmup, int num_samples, int num_thin, int refresh, bool save, stan::services::sample::mcmc_writer< Model, SampleRecorder, DiagnosticRecorder, MessageRecorder > &mcmc_writer, stan::mcmc::sample &init_s, Model &model, RNG &base_rng, const std::string &prefix, const std::string &suffix, std::ostream &o, StartTransitionCallback &callback, interface_callbacks::writer::base_writer &info_writer, interface_callbacks::writer::base_writer &error_writer)
Definition: sample.hpp:17
boost::phoenix::function< set_no_op > set_no_op_f
Probability, optimization and sampling library.
boost::phoenix::function< deprecate_increment_log_prob > deprecate_increment_log_prob_f
Template specification of functions in std for Stan.
boost::phoenix::function< validate_int_expression > validate_int_expression_f
boost::spirit::qi::rule< Iterator, variable(var_origin), whitespace_grammar< Iterator > > var_r
boost::spirit::qi::rule< Iterator, printable(var_origin), whitespace_grammar< Iterator > > printable_r
boost::spirit::qi::rule< Iterator, statement(bool, var_origin, bool), whitespace_grammar< Iterator > > statement_r
boost::spirit::qi::rule< Iterator, statement(bool, var_origin, bool), whitespace_grammar< Iterator > > statement_sub_r
boost::spirit::qi::rule< Iterator, boost::spirit::qi::unused_type, whitespace_grammar< Iterator > > assignment_operator_r
boost::phoenix::function< add_loop_identifier > add_loop_identifier_f
expression_grammar< Iterator > expression_g
boost::phoenix::function< validate_void_return_allowed > validate_void_return_allowed_f
boost::spirit::qi::rule< Iterator, distribution(var_origin), whitespace_grammar< Iterator > > distribution_r
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< std::vector< var_decl > >, statements(bool, var_origin, bool), whitespace_grammar< Iterator > > statement_seq_r
boost::phoenix::function< remove_loop_identifier > remove_loop_identifier_f
boost::spirit::qi::rule< Iterator, no_op_statement(), whitespace_grammar< Iterator > > no_op_statement_r
BOOST_FUSION_ADAPT_STRUCT(stan::lang::expr_type,(stan::lang::base_expr_type, base_type_)(size_t, num_dims_)) namespace stan
boost::spirit::qi::rule< Iterator, range(var_origin), whitespace_grammar< Iterator > > truncation_range_r
boost::phoenix::function< add_line_number > add_line_number_f
boost::spirit::qi::rule< Iterator, print_statement(var_origin), whitespace_grammar< Iterator > > print_statement_r
boost::spirit::qi::rule< Iterator, while_statement(bool, var_origin, bool), whitespace_grammar< Iterator > > while_statement_r
boost::phoenix::function< validate_allow_sample > validate_allow_sample_f
boost::phoenix::function< assign_lhs > assign_lhs_f
boost::phoenix::function< expression_as_statement > expression_as_statement_f
boost::spirit::qi::rule< Iterator, sample(bool, var_origin), whitespace_grammar< Iterator > > sample_r
boost::spirit::qi::rule< Iterator, assgn(var_origin), whitespace_grammar< Iterator > > assgn_r
boost::spirit::qi::rule< Iterator, return_statement(var_origin), whitespace_grammar< Iterator > > return_statement_r
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< std::string >, for_statement(bool, var_origin, bool), whitespace_grammar< Iterator > > for_statement_r
boost::spirit::qi::rule< Iterator, expression(var_origin), whitespace_grammar< Iterator > > expression_rhs_r
boost::phoenix::function< validate_int_expr_warn > validate_int_expr_warn_f
boost::spirit::qi::rule< Iterator, reject_statement(var_origin), whitespace_grammar< Iterator > > reject_statement_r
boost::phoenix::function< validate_sample > validate_sample_f
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > identifier_r
const int local_origin
Definition: ast.hpp:83
boost::phoenix::function< unscope_locals > unscope_locals_f
boost::phoenix::function< identifier_to_var > identifier_to_var_f
boost::spirit::qi::rule< Iterator, std::vector< expression >var_origin), whitespace_grammar< Iterator > > opt_dims_r
boost::phoenix::function< add_while_condition > add_while_condition_f
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > printable_string_r
boost::phoenix::function< validate_assignment > validate_assignment_f
boost::spirit::qi::rule< Iterator, variable_dims(var_origin), whitespace_grammar< Iterator > > var_lhs_r
statement_2_grammar< Iterator > statement_2_g
boost::phoenix::function< set_void_return > set_void_return_f
var_decls_grammar< Iterator > var_decls_g
boost::spirit::qi::rule< Iterator, return_statement(var_origin), whitespace_grammar< Iterator > > void_return_statement_r
boost::phoenix::function< deprecate_old_assignment_op > deprecate_old_assignment_op_f
boost::spirit::qi::rule< Iterator, increment_log_prob_statement(bool, var_origin), whitespace_grammar< Iterator > > increment_log_prob_statement_r
boost::phoenix::function< validate_non_void_expression > validate_non_void_expression_f

     [ Stan Home Page ] © 2011–2016, Stan Development Team.