1 #ifndef STAN__GM__PARSER__FUNCTIONS__GRAMMAR_DEF__HPP__
2 #define STAN__GM__PARSER__FUNCTIONS__GRAMMAR_DEF__HPP__
8 #include <boost/spirit/include/qi.hpp>
9 #include <boost/lexical_cast.hpp>
10 #include <boost/fusion/include/adapt_struct.hpp>
11 #include <boost/fusion/include/std_pair.hpp>
12 #include <boost/config/warning_disable.hpp>
13 #include <boost/spirit/include/qi_numeric.hpp>
14 #include <boost/spirit/include/phoenix_core.hpp>
15 #include <boost/spirit/include/phoenix_function.hpp>
16 #include <boost/spirit/include/phoenix_fusion.hpp>
17 #include <boost/spirit/include/phoenix_object.hpp>
18 #include <boost/spirit/include/phoenix_operator.hpp>
19 #include <boost/spirit/include/phoenix_stl.hpp>
20 #include <boost/spirit/include/support_multi_pass.hpp>
21 #include <boost/tuple/tuple.hpp>
22 #include <boost/variant/apply_visitor.hpp>
23 #include <boost/variant/recursive_variant.hpp>
25 #include <boost/spirit/include/version.hpp>
26 #include <boost/spirit/include/support_line_pos_iterator.hpp>
37 (std::vector<stan::gm::arg_decl>, arg_decls_)
50 template <
typename T1,
typename T2,
typename T3>
54 std::ostream& error_msgs)
const {
57 error_msgs <<
"Functions cannot contain void argument types; "
58 <<
"found void argument."
65 template <
typename T1,
typename T2,
typename T3,
typename T4>
70 std::ostream& error_msgs)
const {
72 error_msgs <<
"Void return type may not have dimensions declared."
85 template <
typename T1,
typename T2,
typename T3>
92 allow_sampling =
true;
93 origin = is_void_function_origin
96 }
else if (
ends_with(
"_rng", identifier)) {
97 allow_sampling =
false;
98 origin = is_void_function_origin
102 allow_sampling =
false;
103 origin = is_void_function_origin
112 template <
typename T1,
typename T2,
typename T3,
typename T4>
115 std::set<std::pair<std::string,
117 std::set<std::pair<std::string,
119 std::ostream& error_msgs)
const {
123 typedef set<pair<string, function_signature_t> >::iterator iterator_t;
124 for (iterator_t it = declared.begin(); it != declared.end(); ++it) {
125 if (defined.find(*it) == defined.end()) {
126 error_msgs <<
"Function declared, but not defined."
127 <<
" Function name=" << (*it).first
139 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
143 const std::pair<std::string,function_signature_t>& name_sig) {
144 for (std::set<std::pair<std::string, function_signature_t> >::const_iterator it
146 it != existing.end();
148 if (name_sig.first == (*it).first
149 && name_sig.second.second == (*it).second.second)
155 std::set<std::pair<std::string,
157 std::set<std::pair<std::string,
159 std::ostream& error_msgs)
const {
164 std::vector<expr_type> arg_types;
165 for (
size_t i = 0; i < decl.
arg_decls_.size(); ++i)
169 std::pair<std::string, function_signature_t> name_sig(decl.
name_, sig);
174 error_msgs <<
"Parse Error. Function already declared, name=" << decl.
name_;
180 if (
fun_exists(functions_defined, name_sig)) {
181 error_msgs <<
"Parse Error. Function already defined, name=" << decl.
name_;
189 error_msgs <<
"Parse Error. Function system defined, name=" << decl.
name_;
195 if (functions_declared.find(name_sig) == functions_declared.end()) {
196 functions_declared.insert(name_sig);
199 result_type,arg_types);
206 functions_defined.insert(name_sig);
213 template <
typename T1,
typename T2,
typename T3>
217 std::ostream& error_msgs)
const {
222 error_msgs <<
"Improper return in body of function.";
229 error_msgs <<
"Require real return type for functions ending in _log.";
236 template <
typename T1>
246 template <
typename T1,
typename T2>
251 for (
size_t i = 0; i < decl.
arg_decls_.size(); ++i)
259 template <
typename T1,
typename T2,
typename T3,
typename T4>
265 std::ostream& error_msgs)
const {
269 error_msgs <<
"duplicate declaration of variable, name="
272 error_msgs <<
"; attempt to redeclare as function argument";
274 error_msgs <<
"; original declaration as ";
277 error_msgs << std::endl;
289 template <
typename Iterator>
291 std::stringstream& error_msgs)
294 functions_declared_(),
295 functions_defined_(),
296 error_msgs_(error_msgs),
297 statement_g(var_map_,error_msgs_),
298 bare_type_g(var_map_,error_msgs_)
300 using boost::spirit::qi::_1;
301 using boost::spirit::qi::char_;
302 using boost::spirit::qi::eps;
303 using boost::spirit::qi::lexeme;
304 using boost::spirit::qi::lit;
305 using boost::spirit::qi::no_skip;
306 using boost::spirit::qi::_pass;
307 using boost::spirit::qi::_val;
309 using boost::spirit::qi::labels::_a;
310 using boost::spirit::qi::labels::_b;
311 using boost::spirit::qi::labels::_r1;
312 using boost::spirit::qi::labels::_r2;
314 using boost::spirit::qi::on_error;
315 using boost::spirit::qi::fail;
316 using boost::spirit::qi::rethrow;
317 using namespace boost::spirit::qi::labels;
319 functions_r.name(
"function declarations and definitions");
330 function_r.name(
"function declaration or definition");
350 arg_decls_r.name(
"function argument declaration sequence");
356 arg_decl_r.name(
"function argument declaration");
368 %= lexeme[char_(
"a-zA-Z")
369 >> *char_(
"a-zA-Z0-9_.")];
bare_type_grammar< Iterator > bare_type_g
bool is_no_op_statement() const
bool ends_with(const std::string &suffix, const std::string &s)
boost::spirit::qi::rule< Iterator, std::vector< arg_decl >), whitespace_grammar< Iterator > > arg_decls_r
void add(const std::string &name, const expr_type &result_type, const std::vector< expr_type > &arg_types)
base_expr_type base_type_
void add(const std::string &name, const base_var_decl &base_decl, const var_origin &vo)
bool is_defined(const std::string &name, const function_signature_t &sig)
static function_signatures & instance()
void set_user_defined(const std::pair< std::string, function_signature_t > &name_sig)
boost::phoenix::function< validate_declarations > validate_declarations_f
bool is_primitive_double() const
void operator()(function_decl_def &decl, variable_map &vm) const
void print_var_origin(std::ostream &o, const var_origin &vo)
const int function_argument_origin
static bool fun_exists(const std::set< std::pair< std::string, function_signature_t > > &existing, const std::pair< std::string, function_signature_t > &name_sig)
void operator()(bool &pass, std::set< std::pair< std::string, function_signature_t > > &declared, std::set< std::pair< std::string, function_signature_t > > &defined, std::ostream &error_msgs) const
Metaprogram to calculate the base scalar return type resulting from promoting all the scalar types of...
const int void_function_argument_origin_rng
const int function_argument_origin_rng
boost::phoenix::function< set_void_function > set_void_function_f
boost::phoenix::function< add_fun_var > add_fun_var_f
boost::phoenix::function< unscope_variables > unscope_variables_f
boost::spirit::qi::rule< Iterator, arg_decl(), whitespace_grammar< Iterator > > arg_decl_r
void operator()(variable_map &vm) const
boost::phoenix::function< set_allows_sampling_origin > set_allows_sampling_origin_f
void operator()(const function_decl_def &decl, bool &pass, std::set< std::pair< std::string, function_signature_t > > &functions_declared, std::set< std::pair< std::string, function_signature_t > > &functions_defined, std::ostream &error_msgs) const
const int void_function_argument_origin_lp
boost::phoenix::function< validate_return_type > validate_return_type_f
boost::spirit::qi::rule< Iterator, boost::spirit::qi::locals< bool, int >, function_decl_def(), whitespace_grammar< Iterator > > function_r
BOOST_FUSION_ADAPT_STRUCT(stan::gm::function_decl_def,(stan::gm::expr_type, return_type_)(std::string, name_)(std::vector< stan::gm::arg_decl >, arg_decls_)(stan::gm::statement, body_))
void operator()(const expr_type &return_type, var_origin &origin, bool &pass, std::ostream &error_msgs) const
std::vector< arg_decl > arg_decls_
functions_grammar(variable_map &var_map, std::stringstream &error_msgs)
statement_grammar< Iterator > statement_g
const int void_function_argument_origin
std::set< std::pair< std::string, function_signature_t > > functions_declared_
boost::spirit::qi::rule< Iterator, std::vector< function_decl_def >), whitespace_grammar< Iterator > > functions_r
void operator()(arg_decl &decl, bool &pass, variable_map &vm, std::ostream &error_msgs) const
boost::spirit::qi::rule< Iterator, std::string(), whitespace_grammar< Iterator > > identifier_r
boost::phoenix::function< add_function_signature > add_function_signature_f
std::set< std::pair< std::string, function_signature_t > > functions_defined_
void remove(const std::string &name)
base_var_decl base_variable_declaration()
const int function_argument_origin_lp
boost::phoenix::function< scope_lp > scope_lp_f
std::stringstream & error_msgs_
void operator()(const expr_type &arg_type, bool &pass, std::ostream &error_msgs) const
bool exists(const std::string &name) const
void operator()(const std::string &identifier, bool &allow_sampling, int &origin) const
void operator()(function_decl_def &decl, bool &pass, std::ostream &error_msgs) const
boost::phoenix::function< validate_non_void_arg_function > validate_non_void_arg_f
bool returns_type(const expr_type &return_type, const statement &statement, std::ostream &error_msgs)
var_origin get_origin(const std::string &name) const
std::pair< expr_type, std::vector< expr_type > > function_signature_t