Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
statement_grammar_def.hpp
Go to the documentation of this file.
1 #ifndef STAN__GM__PARSER__STATEMENT_GRAMMAR_DEF__HPP
2 #define STAN__GM__PARSER__STATEMENT_GRAMMAR_DEF__HPP
3 
4 #include <cstddef>
5 #include <iomanip>
6 #include <iostream>
7 #include <istream>
8 #include <map>
9 #include <set>
10 #include <sstream>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 #include <stdexcept>
15 
16 
17 #include <boost/spirit/include/qi.hpp>
18 #include <boost/lexical_cast.hpp>
19 #include <boost/fusion/include/adapt_struct.hpp>
20 #include <boost/fusion/include/std_pair.hpp>
21 #include <boost/config/warning_disable.hpp>
22 #include <boost/spirit/include/qi_numeric.hpp>
23 #include <boost/spirit/include/phoenix_core.hpp>
24 #include <boost/spirit/include/phoenix_function.hpp>
25 #include <boost/spirit/include/phoenix_fusion.hpp>
26 #include <boost/spirit/include/phoenix_object.hpp>
27 #include <boost/spirit/include/phoenix_operator.hpp>
28 #include <boost/spirit/include/phoenix_stl.hpp>
29 #include <boost/spirit/include/support_multi_pass.hpp>
30 #include <boost/tuple/tuple.hpp>
31 #include <boost/variant/apply_visitor.hpp>
32 #include <boost/variant/recursive_variant.hpp>
33 
34 #include <boost/spirit/include/version.hpp>
35 #include <boost/spirit/include/support_line_pos_iterator.hpp>
36 
37 #include <stan/gm/ast.hpp>
43 
45  (stan::gm::variable_dims, var_dims_)
46  (stan::gm::expression, expr_) );
47 
49  (std::string, name_)
50  (std::vector<stan::gm::expression>, dims_) );
51 
53  (std::string, family_)
54  (std::vector<stan::gm::expression>, args_) );
55 
57  (std::string, variable_)
58  (stan::gm::range, range_)
59  (stan::gm::statement, statement_) );
60 
62  (stan::gm::expression, return_value_) );
63 
65  (std::vector<stan::gm::printable>, printables_) );
66 
68  (std::vector<stan::gm::printable>, printables_) );
69 
71  (stan::gm::expression, log_prob_) );
72 
74  (stan::gm::expression, expr_)
75  (stan::gm::distribution, dist_)
76  (stan::gm::range, truncation_) );
77 
79  (std::vector<stan::gm::var_decl>, local_decl_)
80  (std::vector<stan::gm::statement>, statements_) );
81 
82 namespace stan {
83 
84  namespace gm {
85 
87  template <typename T1, typename T2, typename T3>
88  struct result { typedef void type; };
89  void operator()(var_origin origin,
90  bool& pass,
91  std::ostream& error_msgs) const {
92  if (origin != function_argument_origin
93  && origin != function_argument_origin_lp
94  && origin != function_argument_origin_rng) {
95  error_msgs << "Returns only allowed from function bodies." << std::endl;
96  pass = false;
97  return;
98  }
99  pass = true;
100  }
101  };
102  boost::phoenix::function<validate_return_allowed> validate_return_allowed_f;
103 
105  template <typename T1, typename T2, typename T3>
106  struct result { typedef void type; };
107  void operator()(var_origin origin,
108  bool& pass,
109  std::ostream& error_msgs) const {
110  if (origin != void_function_argument_origin
112  && origin != void_function_argument_origin_rng) {
113  error_msgs << "Void returns only allowed from function bodies of void return type."
114  << std::endl;
115  pass = false;
116  return;
117  }
118  pass = true;
119  }
120  };
121  boost::phoenix::function<validate_void_return_allowed> validate_void_return_allowed_f;
122 
123 
125  template <typename T1, typename T2, typename T3, typename T4>
126  struct result { typedef bool type; };
127 
129  const var_origin& origin_allowed,
130  variable_map& vm,
131  std::ostream& error_msgs) const {
132 
133  // validate existence
134  std::string name = a.var_dims_.name_;
135  if (!vm.exists(name)) {
136  error_msgs << "unknown variable in assignment"
137  << "; lhs variable=" << a.var_dims_.name_
138  << std::endl;
139  return false;
140  }
141 
142  // validate origin
143  var_origin lhs_origin = vm.get_origin(name);
144  if (lhs_origin != local_origin
145  && lhs_origin != origin_allowed) {
146  error_msgs << "attempt to assign variable in wrong block."
147  << " left-hand-side variable origin=";
148  print_var_origin(error_msgs,lhs_origin);
149  error_msgs << std::endl;
150  return false;
151  }
152 
153  // enforce constancy of function args
154  if (lhs_origin == function_argument_origin
155  || lhs_origin == function_argument_origin_lp
156  || lhs_origin == function_argument_origin_rng
157  || lhs_origin == void_function_argument_origin
158  || lhs_origin == void_function_argument_origin_lp
159  || lhs_origin == void_function_argument_origin_rng) {
160  error_msgs << "Illegal to assign to function argument variables."
161  << std::endl
162  << "Use local variables instead."
163  << std::endl;
164  return false;
165  }
166 
167 
168  // validate types
169  a.var_type_ = vm.get(name);
170  size_t lhs_var_num_dims = a.var_type_.dims_.size();
171  size_t num_index_dims = a.var_dims_.dims_.size();
172 
174  lhs_var_num_dims,
175  num_index_dims);
176 
177  if (lhs_type.is_ill_formed()) {
178  error_msgs << "too many indexes for variable "
179  << "; variable name = " << name
180  << "; num dimensions given = " << num_index_dims
181  << "; variable array dimensions = " << lhs_var_num_dims
182  << std::endl;
183  return false;
184  }
185 
186  base_expr_type lhs_base_type = lhs_type.base_type_;
187  base_expr_type rhs_base_type = a.expr_.expression_type().base_type_;
188  // allow int -> double promotion
189  bool types_compatible
190  = lhs_base_type == rhs_base_type
191  || ( lhs_base_type == DOUBLE_T && rhs_base_type == INT_T );
192  if (!types_compatible) {
193  error_msgs << "base type mismatch in assignment"
194  << "; variable name = "
195  << a.var_dims_.name_
196  << ", type = ";
197  write_base_expr_type(error_msgs,lhs_base_type);
198  error_msgs << "; right-hand side type=";
199  write_base_expr_type(error_msgs,rhs_base_type);
200  error_msgs << std::endl;
201  return false;
202  }
203  if (lhs_type.num_dims_ != a.expr_.expression_type().num_dims_) {
204  error_msgs << "dimension mismatch in assignment"
205  << "; variable name = "
206  << a.var_dims_.name_
207  << ", num dimensions given = "
208  << lhs_type.num_dims_
209  << "; right-hand side dimensions = "
211  << std::endl;
212  return false;
213  }
214  return true;
215  }
216  };
217  boost::phoenix::function<validate_assignment> validate_assignment_f;
218 
220  template <typename T1, typename T2, typename T3>
221  struct result { typedef bool type; };
222 
223  bool is_double_return(const std::string& function_name,
224  const std::vector<expr_type>& arg_types,
225  std::ostream& error_msgs) const {
227  .get_result_type(function_name,arg_types,error_msgs)
229  }
230  static bool is_univariate(const expr_type& et) {
231  return et.num_dims_ == 0
232  && ( et.base_type_ == INT_T
233  || et.base_type_ == DOUBLE_T );
234  }
235  bool operator()(const sample& s,
236  const variable_map& var_map,
237  std::ostream& error_msgs) const {
238  std::vector<expr_type> arg_types;
239  arg_types.push_back(s.expr_.expression_type());
240  for (size_t i = 0; i < s.dist_.args_.size(); ++i)
241  arg_types.push_back(s.dist_.args_[i].expression_type());
242  std::string function_name(s.dist_.family_);
243  function_name += "_log";
244  if (!is_double_return(function_name,arg_types,error_msgs)) {
245  error_msgs << "unknown distribution=" << s.dist_.family_ << std::endl;
246  return false;
247  }
248 
249  if (function_name == "lkj_cov_log") {
250  error_msgs << "Warning: the lkj_cov_log() sampling distribution"
251  << " is deprecated. It will be removed in Stan 3."
252  << std::endl
253  << "Code LKJ covariance in terms of an lkj_corr()"
254  << " distribution on a correlation matrix"
255  << " and independent lognormals on the scales."
256  << std::endl << std::endl;
257 
258  }
259 
260  // test for LHS not being purely a variable
261  if (has_non_param_var(s.expr_,var_map)) {
262  // FIXME: really want to get line numbers in here too
263  error_msgs << "Warning (non-fatal):"
264  << " Left-hand side of sampling statement (~) contains a non-linear"
265  << " transform of a parameter or local variable."
266  << std::endl
267  << " You must call increment_log_prob() with the log absolute determinant"
268  << " of the Jacobian of the transform."
269  << std::endl
270  << " Sampling Statement left-hand-side expression:"
271  << std::endl
272  << " ";
273  generate_expression(s.expr_,error_msgs);
274  error_msgs << " ~ ";
275  error_msgs << function_name << "(...)";
276  error_msgs << std::endl;
277  }
278  // validate that variable and params are univariate if truncated
279  if (s.truncation_.has_low() || s.truncation_.has_high()) {
280  if (!is_univariate(s.expr_.expression_type())) { // .num_dims_ > 0) {
281  error_msgs << "Outcomes in truncated distributions must be univariate."
282  << std::endl
283  << " Found outcome expression: ";
284  generate_expression(s.expr_,error_msgs);
285  error_msgs << std::endl
286  << " with non-univariate type: "
287  << s.expr_.expression_type()
288  << std::endl;
289  return false;
290  }
291  for (size_t i = 0; i < s.dist_.args_.size(); ++i)
292  if (!is_univariate(s.dist_.args_[i].expression_type())) { // .num_dims_ > 0) {
293  error_msgs << "Parameters in truncated distributions must be univariate."
294  << std::endl
295  << " Found parameter expression: ";
296  generate_expression(s.dist_.args_[i],error_msgs);
297  error_msgs << std::endl
298  << " with non-univariate type: "
299  << s.dist_.args_[i].expression_type()
300  << std::endl;
301  return false;
302  }
303  }
304  if (s.truncation_.has_low()
306  error_msgs << "Lower boundsin truncated distributions must be univariate."
307  << std::endl
308  << " Found lower bound expression: ";
309  generate_expression(s.truncation_.low_,error_msgs);
310  error_msgs << std::endl
311  << " with non-univariate type: "
313  << std::endl;
314  return false;
315  }
316  if (s.truncation_.has_high()
318  error_msgs << "Upper bounds in truncated distributions must be univariate."
319  << std::endl
320  << " Found upper bound expression: ";
321  generate_expression(s.truncation_.high_,error_msgs);
322  error_msgs << std::endl
323  << " with non-univariate type: "
325  << std::endl;
326  return false;
327  }
328 
329  if (s.truncation_.has_low()) {
330  std::vector<expr_type> arg_types_trunc(arg_types);
331  arg_types_trunc[0] = s.truncation_.low_.expression_type();
332  std::string function_name_cdf(s.dist_.family_);
333  function_name_cdf += "_cdf_log";
334  if (!is_double_return(function_name_cdf,arg_types_trunc,error_msgs)) {
335  error_msgs << "lower truncation not defined for specified arguments to "
336  << s.dist_.family_ << std::endl;
337  return false;
338  }
339  if (!is_double_return(function_name_cdf,arg_types,error_msgs)) {
340  error_msgs << "lower bound in truncation type does not match"
341  << " sampled variate in distribution's type"
342  << std::endl;
343  return false;
344  }
345  }
346  if (s.truncation_.has_high()) {
347  std::vector<expr_type> arg_types_trunc(arg_types);
348  arg_types_trunc[0] = s.truncation_.high_.expression_type();
349  std::string function_name_cdf(s.dist_.family_);
350  function_name_cdf += "_cdf_log";
351  if (!is_double_return(function_name_cdf,arg_types_trunc,error_msgs)) {
352  error_msgs << "upper truncation not defined for specified arguments to "
353  << s.dist_.family_ << std::endl;
354  return false;
355  }
356  if (!is_double_return(function_name_cdf,arg_types,error_msgs)) {
357  error_msgs << "upper bound in truncation type does not match"
358  << " sampled variate in distribution's type"
359  << std::endl;
360  return false;
361  }
362  }
363  return true;
364 
365  }
366  };
367  boost::phoenix::function<validate_sample> validate_sample_f;
368 
370  template <typename T1, typename T2, typename T3>
371  struct result { typedef void type; };
372  void operator()(bool& pass,
373  const stan::gm::expression& expr,
374  std::stringstream& error_msgs) const {
375  if (expr.expression_type() != VOID_T) {
376  error_msgs << "Illegal statement beginning with non-void expression parsed as"
377  << std::endl << " ";
378  generate_expression(expr.expr_,error_msgs);
379  error_msgs << std::endl
380  << "Not a legal assignment, sampling, or function statement. Note that"
381  << std::endl
382  << " * Assignment statements only allow variables (with optional indexes) on the left;"
383  << std::endl
384  << " if you see an outer function logical_lt (<) with negated (-) second argument,"
385  << std::endl
386  << " it indicates an assignment statement A <- B with illegal left"
387  << std::endl
388  << " side A parsed as expression (A < (-B))."
389  << std::endl
390  << " * Sampling statements allow arbitrary value-denoting expressions on the left."
391  << std::endl
392  << " * Functions used as statements must be declared to have void returns"
393  << std::endl << std::endl;
394  pass = false;
395  return;
396  }
397  pass = true;
398  }
399  };
400  boost::phoenix::function<expression_as_statement> expression_as_statement_f;
401 
402  struct unscope_locals {
403  template <typename T1, typename T2>
404  struct result { typedef void type; };
405  void operator()(const std::vector<var_decl>& var_decls,
406  variable_map& vm) const {
407  for (size_t i = 0; i < var_decls.size(); ++i)
408  vm.remove(var_decls[i].name());
409  }
410  };
411  boost::phoenix::function<unscope_locals> unscope_locals_f;
412 
414  template <typename T1, typename T2, typename T3>
415  struct result { typedef bool type; };
417  const expression& e,
418  std::stringstream& error_msgs) const {
419  if (!e.expression_type().is_primitive()) {
420  error_msgs << "conditions in while statement must be primitive int or real;"
421  << " found type=" << e.expression_type() << std::endl;
422  return false;
423  }
424  ws.condition_ = e;
425  return true;
426  }
427  };
428  boost::phoenix::function<add_while_condition> add_while_condition_f;
429 
430  struct add_while_body {
431  template <typename T1, typename T2>
432  struct result { typedef void type; };
434  const statement& s) const {
435  ws.body_ = s;
436  }
437  };
438  boost::phoenix::function<add_while_body> add_while_body_f;
439 
441  template <typename T1, typename T2, typename T3, typename T4>
442  struct result { typedef bool type; };
443  bool operator()(const std::string& name,
444  std::string& name_local,
445  variable_map& vm,
446  std::stringstream& error_msgs) const {
447  name_local = name;
448  if (vm.exists(name)) {
449  error_msgs << "ERROR: loop variable already declared."
450  << " variable name=\"" << name << "\"" << std::endl;
451  return false; // variable exists
452  }
453  vm.add(name,
454  base_var_decl(name,std::vector<expression>(),
455  INT_T),
456  local_origin); // loop var acts like local
457  return true;
458  }
459  };
460  boost::phoenix::function<add_loop_identifier> add_loop_identifier_f;
461 
463  template <typename T1, typename T2>
464  struct result { typedef void type; };
465  void operator()(const std::string& name,
466  variable_map& vm) const {
467  vm.remove(name);
468  }
469  };
470  boost::phoenix::function<remove_loop_identifier> remove_loop_identifier_f;
471 
473  template <typename T1, typename T2, typename T3>
474  struct result { typedef void type; };
475 
476  void operator()(const expression& expr,
477  bool& pass,
478  std::stringstream& error_msgs) const {
479  if (!expr.expression_type().is_primitive_int()) {
480  error_msgs << "expression denoting integer required; found type="
481  << expr.expression_type() << std::endl;
482  pass = false;
483  return;
484  }
485  pass = true;
486  return;
487  }
488  };
489  boost::phoenix::function<validate_int_expr2> validate_int_expr2_f;
490 
492  template <typename T1, typename T2, typename T3>
493  struct result { typedef void type; };
494 
495  void operator()(const bool& allow_sample,
496  bool& pass,
497  std::stringstream& error_msgs) const {
498  if (!allow_sample) {
499  error_msgs << "sampling only allowed in model."
500  << std::endl;
501  pass = false;
502  return;
503  }
504  pass = true;
505  return;
506  }
507  };
508  boost::phoenix::function<validate_allow_sample> validate_allow_sample_f;
509 
511  template <typename T1, typename T2, typename T3>
512  struct result { typedef void type; };
513 
514  void operator()(const expression& e,
515  bool& pass,
516  std::ostream& error_msgs) const {
517  pass = !e.expression_type().is_void();
518  if (!pass) {
519  error_msgs << "attempt to increment log prob with void expression" << std::endl;
520  }
521  }
522  };
523  boost::phoenix::function<validate_non_void_expression> validate_non_void_expression_f;
524 
525 
526  template <typename Iterator>
528  std::stringstream& error_msgs)
529  : statement_grammar::base_type(statement_r),
530  var_map_(var_map),
531  error_msgs_(error_msgs),
532  expression_g(var_map,error_msgs),
533  var_decls_g(var_map,error_msgs),
534  statement_2_g(var_map,error_msgs,*this)
535  {
536  using boost::spirit::qi::_1;
537  using boost::spirit::qi::char_;
538  using boost::spirit::qi::eps;
539  using boost::spirit::qi::lexeme;
540  using boost::spirit::qi::lit;
541  using boost::spirit::qi::no_skip;
542  using boost::spirit::qi::_pass;
543  using boost::spirit::qi::_val;
544 
545  using boost::spirit::qi::labels::_a;
546  using boost::spirit::qi::labels::_r1;
547  using boost::spirit::qi::labels::_r2;
548  using boost::spirit::qi::labels::_r3;
549 
550  // inherited features
551  // _r1 true if sample_r allowed
552  // _r2 source of variables allowed for assignments
553  // _r3 true if return_r allowed
554  statement_r.name("statement");
556  %= no_op_statement_r // key ";"
557  | statement_seq_r(_r1,_r2,_r3) // key "{"
558  | increment_log_prob_statement_r(_r1,_r2) // key "increment_log_prob"
559  | for_statement_r(_r1,_r2,_r3) // key "for"
560  | while_statement_r(_r1,_r2,_r3) // key "while"
561  | statement_2_g(_r1,_r2,_r3) // key "if"
562  | print_statement_r(_r2) // key "print"
563  | reject_statement_r(_r2) // key "reject"
564  | return_statement_r(_r2) // key "return"
565  | void_return_statement_r(_r2) // key "return"
566  | assignment_r(_r2) // lvalue "<-"
567  | sample_r(_r1,_r2) // expression "~"
568  | expression_g(_r2) // expression
569  [expression_as_statement_f(_pass,_1,boost::phoenix::ref(error_msgs_))]
570  ;
571 
572  // _r1, _r2, _r3 same as statement_r
573  statement_seq_r.name("sequence of statements");
575  %= lit('{')
576  > local_var_decls_r[_a = _1]
577  > *statement_r(_r1,_r2,_r3)
578  > lit('}')
579  > eps[unscope_locals_f(_a,boost::phoenix::ref(var_map_))]
580  ;
581 
583  %= var_decls_g(false,local_origin); // - constants
584 
585  // inherited _r1 = true if samples allowed as statements
586  increment_log_prob_statement_r.name("increment log prob statement");
588  %= lit("increment_log_prob")
589  > eps[ validate_allow_sample_f(_r1,_pass,
590  boost::phoenix::ref(error_msgs_)) ]
591  > lit('(')
593  boost::phoenix::ref(error_msgs_)) ]
594  > lit(')')
595  > lit(';')
596  ;
597 
598  // _r1, _r2, _r3 same as statement_r
599  while_statement_r.name("while statement");
601  = lit("while")
602  > lit('(')
603  > expression_g(_r2)
604  [_pass = add_while_condition_f(_val,_1,
605  boost::phoenix::ref(error_msgs_))]
606  > lit(')')
607  > statement_r(_r1,_r2,_r3)
608  [add_while_body_f(_val,_1)]
609  ;
610 
611 
612  // _r1, _r2, _r3 same as statement_r
613  for_statement_r.name("for statement");
615  %= lit("for")
616  > lit('(')
617  > identifier_r [_pass
618  = add_loop_identifier_f(_1,_a,
619  boost::phoenix::ref(var_map_),
620  boost::phoenix::ref(error_msgs_))]
621  > lit("in")
622  > range_r(_r2)
623  > lit(')')
624  > statement_r(_r1,_r2,_r3)
625  > eps
626  [remove_loop_identifier_f(_a,boost::phoenix::ref(var_map_))];
627  ;
628 
629  print_statement_r.name("print statement");
631  %= lit("print")
632  > lit('(')
633  > (printable_r(_r1) % ',')
634  > lit(')');
635 
636  // reject
637  reject_statement_r.name("reject statement");
639  %= lit("reject")
640  > lit('(')
641  > (printable_r(_r1) % ',')
642  > lit(')');
643 
644  printable_r.name("printable");
647  | expression_g(_r1);
648 
649  printable_string_r.name("printable quoted string");
651  %= lit('"')
652  > no_skip[*char_("a-zA-Z0-9/~!@#$%^&*()`_+-={}|[]:;'<>?,./ ")]
653  > lit('"');
654 
655  identifier_r.name("identifier");
657  %= (lexeme[char_("a-zA-Z")
658  >> *char_("a-zA-Z0-9_.")]);
659 
660  range_r.name("range expression pair, colon");
661  range_r
662  %= expression_g(_r1)
663  [validate_int_expr2_f(_1,_pass,boost::phoenix::ref(error_msgs_))]
664  >> lit(':')
665  >> expression_g(_r1)
666  [validate_int_expr2_f(_1,_pass,boost::phoenix::ref(error_msgs_))];
667 
668  assignment_r.name("variable assignment by expression");
670  %= ( var_lhs_r(_r1)
671  >> lit("<-") )
672  > expression_g(_r1)
673  > lit(';')
674  [_pass = validate_assignment_f(_val,_r1,boost::phoenix::ref(var_map_),
675  boost::phoenix::ref(error_msgs_))]
676  ;
677 
678  var_lhs_r.name("variable and array dimensions");
679  var_lhs_r
680  %= identifier_r
681  >> opt_dims_r(_r1);
682 
683  opt_dims_r.name("array dimensions (optional)");
684  opt_dims_r
685  %= * dims_r(_r1);
686 
687  dims_r.name("array dimensions");
688  dims_r
689  %= lit('[')
690  > (expression_g(_r1)
691  [validate_int_expr2_f(_1,_pass,boost::phoenix::ref(error_msgs_))]
692  % ',')
693  > lit(']')
694  ;
695 
696  // inherited _r1 = true if samples allowed as statements
697  sample_r.name("distribution of expression");
698  sample_r
699  %= ( expression_g(_r2)
700  >> lit('~') )
701  > eps
702  [validate_allow_sample_f(_r1,_pass,
703  boost::phoenix::ref(error_msgs_))]
704  > distribution_r(_r2)
705  > -truncation_range_r(_r2)
706  > lit(';')
707  > eps
708  [_pass = validate_sample_f(_val,
709  boost::phoenix::ref(var_map_),
710  boost::phoenix::ref(error_msgs_))]
711  ;
712 
713  distribution_r.name("distribution and parameters");
715  %= ( identifier_r
716  >> lit('(')
717  >> -(expression_g(_r1) % ',') )
718  > lit(')')
719  ;
720 
721  truncation_range_r.name("range pair");
723  %= lit('T')
724  > lit('[')
725  > -expression_g(_r1)
726  > lit(',')
727  > -expression_g(_r1)
728  > lit(']')
729  ;
730 
731  // _r1 = allow sampling, _r2 = var origin
732  return_statement_r.name("return statement");
734  %= lit("return")
735  >> expression_g(_r1)
736  >> lit(';') [ validate_return_allowed_f(_r1,_pass,
737  boost::phoenix::ref(error_msgs_)) ]
738  ;
739 
740  // _r1 = var origin
741  void_return_statement_r.name("void return statement");
743  = lit("return")[_val = expression()]
744  >> lit(';') [ validate_void_return_allowed_f(_r1,_pass,
745  boost::phoenix::ref(error_msgs_)) ]
746  ;
747 
748  no_op_statement_r.name("no op statement");
750  %= lit(';') [_val = no_op_statement()]; // ok to re-use instance
751 
752  using boost::spirit::qi::on_error;
753  using boost::spirit::qi::fail;
754  using boost::spirit::qi::rethrow;
755  using namespace boost::spirit::qi::labels;
756 
757  }
758 
759  }
760 }
761 #endif
std::string family_
Definition: ast.hpp:195
void operator()(while_statement &ws, const statement &s) const
boost::phoenix::function< validate_assignment > validate_assignment_f
void generate_expression(const expression &e, std::ostream &o)
Definition: generator.hpp:249
boost::spirit::qi::rule< Iterator, printable(var_origin), whitespace_grammar< Iterator > > printable_r
void operator()(const expression &e, bool &pass, std::ostream &error_msgs) const
void operator()(const bool &allow_sample, bool &pass, std::stringstream &error_msgs) const
std::vector< expression > dims_
Definition: ast.hpp:430
base_expr_type base_type_
Definition: ast.hpp:75
void operator()(const std::vector< var_decl > &var_decls, variable_map &vm) const
variable_dims var_dims_
Definition: ast.hpp:829
boost::spirit::qi::rule< Iterator, range(var_origin), whitespace_grammar< Iterator > > range_r
void add(const std::string &name, const base_var_decl &base_decl, const var_origin &vo)
Definition: ast_def.cpp:1007
const int DOUBLE_T
Definition: ast.hpp:66
static function_signatures & instance()
Definition: ast_def.cpp:143
const int local_origin
Definition: ast.hpp:418
expression expr_
Definition: ast.hpp:830
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< std::string >, for_statement(bool, var_origin, bool), whitespace_grammar< Iterator > > for_statement_r
boost::phoenix::function< validate_allow_sample > validate_allow_sample_f
bool operator()(const sample &s, const variable_map &var_map, std::ostream &error_msgs) const
bool is_primitive_int() const
Definition: ast_def.cpp:97
boost::spirit::qi::rule< Iterator, std::vector< var_decl >), whitespace_grammar< Iterator > > local_var_decls_r
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > identifier_r
bool has_low() const
Definition: ast_def.cpp:937
expression high_
Definition: ast.hpp:403
bool is_primitive_double() const
Definition: ast_def.cpp:101
void operator()(bool &pass, const stan::gm::expression &expr, std::stringstream &error_msgs) const
void print_var_origin(std::ostream &o, const var_origin &vo)
Definition: ast_def.cpp:944
const int function_argument_origin
Definition: ast.hpp:419
boost::spirit::qi::rule< Iterator, reject_statement(var_origin), whitespace_grammar< Iterator > > reject_statement_r
boost::phoenix::function< unscope_locals > unscope_locals_f
boost::spirit::qi::rule< Iterator, range(var_origin), whitespace_grammar< Iterator > > truncation_range_r
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > printable_string_r
bool operator()(while_statement &ws, const expression &e, std::stringstream &error_msgs) const
const int void_function_argument_origin_rng
Definition: ast.hpp:424
statement_2_grammar< Iterator > statement_2_g
const int function_argument_origin_rng
Definition: ast.hpp:421
boost::spirit::qi::rule< Iterator, statement(bool, var_origin, bool), whitespace_grammar< Iterator > > statement_r
expression expr_
Definition: ast.hpp:819
base_expr_type base_type_
Definition: ast.hpp:431
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< std::vector< var_decl > >, statements(bool, var_origin, bool), whitespace_grammar< Iterator > > statement_seq_r
expression_t expr_
Definition: ast.hpp:252
size_t num_dims_
Definition: ast.hpp:76
bool has_non_param_var(const expression &e, const variable_map &var_map)
Definition: ast_def.cpp:748
std::stringstream & error_msgs_
expression condition_
Definition: ast.hpp:738
static bool is_univariate(const expr_type &et)
boost::spirit::qi::rule< Iterator, print_statement(var_origin), whitespace_grammar< Iterator > > print_statement_r
expression low_
Definition: ast.hpp:402
std::vector< expression > dims_
Definition: ast.hpp:290
const int void_function_argument_origin_lp
Definition: ast.hpp:423
std::string name_
Definition: ast.hpp:289
boost::spirit::qi::rule< Iterator, while_statement(bool, var_origin, bool), whitespace_grammar< Iterator > > while_statement_r
void operator()(var_origin origin, bool &pass, std::ostream &error_msgs) const
const int void_function_argument_origin
Definition: ast.hpp:422
var_decls_grammar< Iterator > var_decls_g
expression_grammar< Iterator > expression_g
void operator()(const std::string &name, variable_map &vm) const
boost::spirit::qi::rule< Iterator, variable_dims(var_origin), whitespace_grammar< Iterator > > var_lhs_r
void operator()(var_origin origin, bool &pass, std::ostream &error_msgs) const
boost::spirit::qi::rule< Iterator, return_statement(var_origin), whitespace_grammar< Iterator > > void_return_statement_r
boost::spirit::qi::rule< Iterator, std::vector< expression >var_origin), whitespace_grammar< Iterator > > dims_r
int base_expr_type
Definition: ast.hpp:60
boost::phoenix::function< add_while_condition > add_while_condition_f
boost::spirit::qi::rule< Iterator, no_op_statement(), whitespace_grammar< Iterator > > no_op_statement_r
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:86
bool operator()(const std::string &name, std::string &name_local, variable_map &vm, std::stringstream &error_msgs) const
range truncation_
Definition: ast.hpp:821
bool is_ill_formed() const
Definition: ast_def.cpp:105
void remove(const std::string &name)
Definition: ast_def.cpp:1012
void operator()(const expression &expr, bool &pass, std::stringstream &error_msgs) const
boost::spirit::qi::rule< Iterator, increment_log_prob_statement(bool, var_origin), whitespace_grammar< Iterator > > increment_log_prob_statement_r
boost::spirit::qi::rule< Iterator, assignment(var_origin), whitespace_grammar< Iterator > > assignment_r
bool has_high() const
Definition: ast_def.cpp:940
expr_type infer_type_indexing(const base_expr_type &expr_base_type, size_t num_expr_dims, size_t num_index_dims)
Definition: ast_def.cpp:873
boost::phoenix::function< validate_int_expr2 > validate_int_expr2_f
boost::phoenix::function< validate_sample > validate_sample_f
const int function_argument_origin_lp
Definition: ast.hpp:420
const int INT_T
Definition: ast.hpp:65
boost::spirit::qi::rule< Iterator, sample(bool, var_origin), whitespace_grammar< Iterator > > sample_r
base_var_decl var_type_
Definition: ast.hpp:831
boost::phoenix::function< validate_non_void_expression > validate_non_void_expression_f
bool operator()(assignment &a, const var_origin &origin_allowed, variable_map &vm, std::ostream &error_msgs) const
std::vector< expression > args_
Definition: ast.hpp:196
boost::spirit::qi::rule< Iterator, std::vector< expression >var_origin), whitespace_grammar< Iterator > > opt_dims_r
boost::phoenix::function< add_while_body > add_while_body_f
BOOST_FUSION_ADAPT_STRUCT(stan::gm::assignment,(stan::gm::variable_dims, var_dims_)(stan::gm::expression, expr_))
distribution dist_
Definition: ast.hpp:820
expr_type get_result_type(const std::string &name, const std::vector< expr_type > &args, std::ostream &error_msgs)
Definition: ast_def.cpp:329
boost::phoenix::function< remove_loop_identifier > remove_loop_identifier_f
boost::phoenix::function< validate_void_return_allowed > validate_void_return_allowed_f
bool exists(const std::string &name) const
Definition: ast_def.cpp:988
std::ostream & write_base_expr_type(std::ostream &o, base_expr_type type)
Definition: ast_def.cpp:23
expr_type expression_type() const
Definition: ast_def.cpp:570
boost::phoenix::function< expression_as_statement > expression_as_statement_f
base_var_decl get(const std::string &name) const
Definition: ast_def.cpp:991
boost::spirit::qi::rule< Iterator, distribution(var_origin), whitespace_grammar< Iterator > > distribution_r
boost::phoenix::function< add_loop_identifier > add_loop_identifier_f
bool is_double_return(const std::string &function_name, const std::vector< expr_type > &arg_types, std::ostream &error_msgs) const
int var_origin
Definition: ast.hpp:411
bool is_primitive() const
Definition: ast_def.cpp:93
boost::phoenix::function< validate_return_allowed > validate_return_allowed_f
var_origin get_origin(const std::string &name) const
Definition: ast_def.cpp:1002
bool is_void() const
Definition: ast_def.cpp:108
const int VOID_T
Definition: ast.hpp:64
boost::spirit::qi::rule< Iterator, return_statement(var_origin), whitespace_grammar< Iterator > > return_statement_r
statement_grammar(variable_map &var_map, std::stringstream &error_msgs)

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