Stan  1.0
probability, sampling & optimization
expression_grammar_def.hpp
Go to the documentation of this file.
1 #ifndef __STAN__GM__PARSER__EXPRESSION_GRAMMAR_DEF__HPP__
2 #define __STAN__GM__PARSER__EXPRESSION_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 #include <boost/spirit/include/qi.hpp>
17 // FIXME: get rid of unused include
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>
24 
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>
29 #include <boost/spirit/include/qi.hpp>
30 #include <boost/spirit/include/qi_numeric.hpp>
31 #include <boost/spirit/include/classic_position_iterator.hpp>
32 #include <boost/spirit/include/phoenix_core.hpp>
33 #include <boost/spirit/include/phoenix_function.hpp>
34 #include <boost/spirit/include/phoenix_fusion.hpp>
35 #include <boost/spirit/include/phoenix_object.hpp>
36 #include <boost/spirit/include/phoenix_operator.hpp>
37 #include <boost/spirit/include/phoenix_stl.hpp>
38 #include <boost/spirit/include/support_multi_pass.hpp>
39 #include <boost/tuple/tuple.hpp>
40 #include <boost/variant/apply_visitor.hpp>
41 #include <boost/variant/recursive_variant.hpp>
42 
43 #include <stan/gm/ast.hpp>
47 
48 
49 namespace stan {
50 
51  namespace gm {
52 
53  // FIXME: cut and paste from term grammar, having trouble w. includes
55  template <typename T1, typename T2>
56  struct result { typedef bool type; };
57 
58  bool operator()(const expression& expr,
59  std::ostream& error_msgs) const {
60  if (expr.expression_type().is_ill_formed()) {
61  error_msgs << "expression is ill formed" << std::endl;
62  return false;
63  }
64  return true;
65  }
66  };
67  boost::phoenix::function<validate_expr_type2> validate_expr_type2_f;
68 
69  // FIXME: cut and paste from term grammar, having trouble w. includes
70  struct set_fun_type2 {
71  template <typename T1, typename T2>
72  struct result { typedef fun type; };
73 
75  std::ostream& error_msgs) const {
76  std::vector<expr_type> arg_types;
77  for (size_t i = 0; i < fun.args_.size(); ++i)
78  arg_types.push_back(fun.args_[i].expression_type());
80  arg_types,
81  error_msgs);
82  return fun;
83  }
84  };
85  boost::phoenix::function<set_fun_type2> set_fun_type2_f;
86 
87  struct binary_op_expr {
88  template <typename T1, typename T2, typename T3, typename T4, typename T5>
89  struct result { typedef expression type; };
90 
92  const expression& expr2,
93  const std::string& op,
94  const std::string& fun_name,
95  std::ostream& error_msgs) const {
96  if (!expr1.expression_type().is_primitive()
97  || !expr2.expression_type().is_primitive()) {
98  error_msgs << "binary infix operator "
99  << op
100  << " with functional interpretation "
101  << fun_name
102  << " requires arguments or primitive type (int or real)"
103  << ", found left type=" << expr1.expression_type()
104  << ", right arg type=" << expr2.expression_type()
105  << "; ";
106  }
107  std::vector<expression> args;
108  args.push_back(expr1);
109  args.push_back(expr2);
110  set_fun_type2 sft;
111  fun f(fun_name,args);
112  sft(f,error_msgs);
113  return expression(f);
114  }
115  };
116  boost::phoenix::function<binary_op_expr> binary_op_f;
117 
118 
119  struct addition_expr {
120  template <typename T1, typename T2, typename T3>
121  struct result { typedef expression type; };
122 
124  const expression& expr2,
125  std::ostream& error_msgs) const {
126  if (expr1.expression_type().is_primitive()
127  && expr2.expression_type().is_primitive()) {
128  return expr1 += expr2;
129  }
130  std::vector<expression> args;
131  args.push_back(expr1);
132  args.push_back(expr2);
133  set_fun_type2 sft;
134  fun f("add",args);
135  sft(f,error_msgs);
136  return expression(f);
137  return expr1 += expr2;
138  }
139  };
140  boost::phoenix::function<addition_expr> addition;
141 
142 
144  template <typename T1, typename T2, typename T3>
145  struct result { typedef expression type; };
146 
148  const expression& expr2,
149  std::ostream& error_msgs) const {
150  if (expr1.expression_type().is_primitive()
151  && expr2.expression_type().is_primitive()) {
152  return expr1 -= expr2;
153  }
154  std::vector<expression> args;
155  args.push_back(expr1);
156  args.push_back(expr2);
157  set_fun_type2 sft;
158  fun f("subtract",args);
159  sft(f,error_msgs);
160  return expression(f);
161  }
162  };
163  boost::phoenix::function<subtraction_expr> subtraction;
164 
165 
166 
167  template <typename Iterator>
169  std::stringstream& error_msgs,
170  bool allow_lte)
171  : expression_grammar::base_type(allow_lte ? expression_r : expression07_r),
172  var_map_(var_map),
173  error_msgs_(error_msgs),
174  term_g(var_map,error_msgs,*this)
175  {
176  using boost::spirit::qi::_1;
177  using boost::spirit::qi::char_;
178  using boost::spirit::qi::double_;
179  using boost::spirit::qi::eps;
180  using boost::spirit::qi::int_;
181  using boost::spirit::qi::lexeme;
182  using boost::spirit::qi::lit;
183  using boost::spirit::qi::_pass;
184  using boost::spirit::qi::_val;
185 
186 
187 
188  expression_r.name("expression (top level, precedence 15, binary ||");
190  = expression14_r [_val = _1]
191  > *( lit("||")
192  > expression14_r [_val = binary_op_f(_val,_1,"||","logical_or",
193  boost::phoenix::ref(error_msgs))]
194  );
195 
196  expression14_r.name("expression, precedence 14, binary &&");
198  = expression10_r [_val = _1]
199  > *( lit("&&")
200  > expression10_r [_val = binary_op_f(_val,_1,"&&","logical_and",
201  boost::phoenix::ref(error_msgs))]
202  );
203 
204  expression10_r.name("expression, precedence 10, binary ==, !=");
206  = expression09_r [_val = _1]
207  > *( ( lit("==")
208  > expression09_r [_val = binary_op_f(_val,_1,"==","logical_eq",
209  boost::phoenix::ref(error_msgs))] )
210  |
211  ( lit("!=")
212  > expression09_r [_val = binary_op_f(_val,_1,"!=","logical_neq",
213  boost::phoenix::ref(error_msgs))] )
214  );
215 
216  expression09_r.name("expression, precedence 9, binary <, <=, >, >=");
218  = expression07_r [_val = _1]
219  > *( ( lit("<=")
220  > expression07_r [_val = binary_op_f(_val,_1,"<","logical_lt",
221  boost::phoenix::ref(error_msgs))] )
222  |
223  ( lit("<")
224  > expression07_r [_val = binary_op_f(_val,_1,"<=","logical_lte",
225  boost::phoenix::ref(error_msgs))] )
226  |
227  ( lit(">=")
228  > expression07_r [_val = binary_op_f(_val,_1,">","logical_gt",
229  boost::phoenix::ref(error_msgs))] )
230  |
231  ( lit(">")
232  > expression07_r [_val = binary_op_f(_val,_1,">=","logical_gte",
233  boost::phoenix::ref(error_msgs))] )
234  );
235 
236  expression07_r.name("expression, precedence 7, binary +, -");
238  = term_g
239  [_val = _1]
240  > *( ( lit('+')
241  > term_g // expression07_r
242  [_val = addition(_val,_1,boost::phoenix::ref(error_msgs))] )
243  |
244  ( lit('-')
245  > term_g // expression07_r
246  [_val = subtraction(_val,_1,boost::phoenix::ref(error_msgs))] )
247  )
248  > eps[_pass = validate_expr_type2_f(_val,boost::phoenix::ref(error_msgs_))]
249  ;
250 
251 
252  }
253  }
254 }
255 
256 #endif
static function_signatures & instance()
Definition: ast_def.cpp:112
expr_type get_result_type(const std::string &name, const std::vector< expr_type > &args, std::ostream &error_msgs)
Definition: ast_def.cpp:218
boost::phoenix::function< set_fun_type2 > set_fun_type2_f
boost::phoenix::function< validate_expr_type2 > validate_expr_type2_f
boost::phoenix::function< addition_expr > addition
boost::phoenix::function< subtraction_expr > subtraction
boost::phoenix::function< binary_op_expr > binary_op_f
Probability, optimization and sampling library.
Definition: agrad.cpp:6
expression operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
expression operator()(expression &expr1, const expression &expr2, const std::string &op, const std::string &fun_name, std::ostream &error_msgs) const
bool is_primitive() const
Definition: ast_def.cpp:70
bool is_ill_formed() const
Definition: ast_def.cpp:82
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > expression07_r
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > expression_r
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > expression09_r
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > expression14_r
boost::spirit::qi::rule< Iterator, expression(), whitespace_grammar< Iterator > > expression10_r
expression_grammar(variable_map &var_map, std::stringstream &error_msgs, bool allow_lte=true)
term_grammar< Iterator > term_g
expr_type expression_type() const
Definition: ast_def.cpp:306
std::string name_
Definition: ast.hpp:298
std::vector< expression > args_
Definition: ast.hpp:299
expr_type type_
Definition: ast.hpp:300
fun operator()(fun &fun, std::ostream &error_msgs) const
expression operator()(expression &expr1, const expression &expr2, std::ostream &error_msgs) const
bool operator()(const expression &expr, std::ostream &error_msgs) const

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