1 #ifndef STAN__GM__PARSER__PROGRAM_GRAMMAR_DEF__HPP
2 #define STAN__GM__PARSER__PROGRAM_GRAMMAR_DEF__HPP
16 #include <boost/format.hpp>
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>
34 #include <boost/spirit/include/version.hpp>
35 #include <boost/spirit/home/support/iterators/line_pos_iterator.hpp>
48 typedef std::pair<std::vector<stan::gm::var_decl>,
49 std::vector<stan::gm::statement> > type;
55 (std::vector<stan::gm::function_decl_def>, function_decl_defs_)
56 (std::vector<stan::gm::var_decl>, data_decl_)
57 (DUMMY_STRUCT::type, derived_data_decl_)
58 (std::vector<stan::gm::var_decl>, parameter_decl_)
59 (DUMMY_STRUCT::type, derived_decl_)
61 (DUMMY_STRUCT::type, generated_decl_) )
70 struct result {
typedef void type; };
71 void operator()(variable_map& vm)
const {
73 base_var_decl(
"lp__",std::vector<expression>(),
DOUBLE_T),
77 boost::phoenix::function<add_lp_var> add_lp_var_f;
79 struct remove_lp_var {
81 struct result {
typedef void type; };
82 void operator()(variable_map& vm)
const {
86 boost::phoenix::function<remove_lp_var> remove_lp_var_f;
88 struct program_error {
89 template <
typename T1,
typename T2, typename ,
90 typename T4,
typename T5,
typename T6,
typename T7>
91 struct result {
typedef void type; };
93 template <
class Iterator,
class I>
101 std::stringstream& error_msgs)
const {
103 using boost::phoenix::construct;
104 using boost::phoenix::val;
105 using boost::spirit::get_line;
109 error_msgs << msg << std::endl;
111 size_t idx_errline = 0;
112 idx_errline = get_line(_where);
114 if (idx_errline > 0) {
115 error_msgs <<
"ERROR at line " << idx_errline << std::endl;
117 std::basic_stringstream<char> sprogram;
118 sprogram << boost::make_iterator_range (_begin, _end);
121 size_t idx_errcol = 0;
122 idx_errcol = get_column(_begin,_where) - 1;
124 std::string lineno =
"";
125 format fmt_lineno(
"% 3d: ");
127 std::string line_2before =
"";
128 std::string line_before =
"";
129 std::string line_err =
"";
130 std::string line_after =
"";
133 size_t idx_before = idx_errline - 1;
134 if (idx_before > 0) {
136 while (idx_before > idx_line) {
137 line_2before = line_before;
138 std::getline(sprogram,line_before);
141 if (line_2before.length() > 0) {
142 lineno = str(fmt_lineno % (idx_before - 1) );
143 error_msgs << lineno << line_2before << std::endl;
145 lineno = str(fmt_lineno % idx_before);
146 error_msgs << lineno << line_before << std::endl;
149 std::getline(sprogram,line_err);
150 lineno = str(fmt_lineno % idx_errline);
151 error_msgs << lineno << line_err << std::endl
152 << setw(idx_errcol + lineno.length()) <<
"^" << std::endl;
154 if (!sprogram.eof()) {
155 std::getline(sprogram,line_after);
156 lineno = str(fmt_lineno % (idx_errline+1));
157 error_msgs << lineno << line_after << std::endl;
160 error_msgs << std::endl;
163 boost::phoenix::function<program_error> program_error_f;
165 template <
typename Iterator>
166 program_grammar<Iterator>::program_grammar(
const std::string& model_name)
167 : program_grammar::base_type(program_r),
168 model_name_(model_name),
171 expression_g(var_map_,error_msgs_),
172 var_decls_g(var_map_,error_msgs_),
173 statement_g(var_map_,error_msgs_),
174 functions_g(var_map_,error_msgs_) {
176 using boost::spirit::qi::eps;
177 using boost::spirit::qi::lit;
180 var_map_.add(model_name,
184 program_r.name(
"program");
188 > -derived_data_var_decls_r
191 > eps[add_lp_var_f(boost::phoenix::ref(var_map_))]
192 > -derived_var_decls_r
194 > eps[remove_lp_var_f(boost::phoenix::ref(var_map_))]
195 > -generated_var_decls_r
198 model_r.name(
"model declaration");
204 data_var_decls_r.name(
"data variable declarations");
211 derived_data_var_decls_r.name(
"transformed data block");
212 derived_data_var_decls_r
213 %= ( lit(
"transformed")
220 param_var_decls_r.name(
"parameter variable declarations");
227 derived_var_decls_r.name(
"derived variable declarations");
229 %= ( lit(
"transformed")
230 >> lit(
"parameters") )
236 generated_var_decls_r.name(
"generated variable declarations");
237 generated_var_decls_r
245 using boost::spirit::qi::on_error;
246 using boost::spirit::qi::rethrow;
247 using namespace boost::spirit::qi::labels;
254 boost::phoenix::ref(var_map_),
255 boost::phoenix::ref(error_msgs_)
const int parameter_origin
BOOST_FUSION_ADAPT_STRUCT(stan::gm::program,(std::vector< stan::gm::function_decl_def >, function_decl_defs_)(std::vector< stan::gm::var_decl >, data_decl_)(DUMMY_STRUCT::type, derived_data_decl_)(std::vector< stan::gm::var_decl >, parameter_decl_)(DUMMY_STRUCT::type, derived_decl_)(stan::gm::statement, statement_)(DUMMY_STRUCT::type, generated_decl_)) namespace stan
const int model_name_origin
const int transformed_data_origin
const int transformed_parameter_origin