1 #ifndef STAN__GM__PARSER__PARSER__HPP
2 #define STAN__GM__PARSER__PARSER__HPP
4 #include <boost/lexical_cast.hpp>
5 #include <boost/fusion/include/adapt_struct.hpp>
6 #include <boost/fusion/include/std_pair.hpp>
7 #include <boost/config/warning_disable.hpp>
8 #include <boost/spirit/include/qi.hpp>
9 #include <boost/spirit/include/qi_numeric.hpp>
10 #include <boost/spirit/include/phoenix_core.hpp>
11 #include <boost/spirit/include/phoenix_function.hpp>
12 #include <boost/spirit/include/phoenix_fusion.hpp>
13 #include <boost/spirit/include/phoenix_object.hpp>
14 #include <boost/spirit/include/phoenix_operator.hpp>
15 #include <boost/spirit/include/phoenix_stl.hpp>
16 #include <boost/spirit/include/support_multi_pass.hpp>
17 #include <boost/tuple/tuple.hpp>
18 #include <boost/variant/apply_visitor.hpp>
19 #include <boost/variant/recursive_variant.hpp>
21 #include <boost/spirit/include/version.hpp>
22 #include <boost/spirit/home/support/iterators/line_pos_iterator.hpp>
51 return c ==
' ' || c ==
'\n' || c ==
'\r' || c ==
'\t';
55 for (
size_t i = 0; i < s.size(); ++i)
61 inline bool parse(std::ostream* output_stream,
63 const std::string& filename,
64 const std::string& model_name,
67 using boost::spirit::multi_pass;
68 using boost::spirit::make_default_multi_pass;
69 using std::istreambuf_iterator;
71 using boost::spirit::qi::expectation_failure;
72 using boost::spirit::qi::phrase_parse;
74 using boost::phoenix::construct;
75 using boost::phoenix::val;
79 std::ostringstream buf;
81 std::string stan_string = buf.str();
83 typedef std::string::const_iterator input_iterator;
84 typedef boost::spirit::line_pos_iterator<input_iterator> lp_iterator;
86 lp_iterator fwd_begin = lp_iterator (stan_string.begin());
87 lp_iterator fwd_end = lp_iterator (stan_string.end());
92 bool parse_succeeded =
false;
94 parse_succeeded = phrase_parse(fwd_begin,
99 std::string diagnostics = prog_grammar.error_msgs_.str();
101 *output_stream <<
"DIAGNOSTIC(S) FROM PARSER:"
106 }
catch (
const expectation_failure<lp_iterator>&
e) {
108 std::stringstream msg;
109 std::string diagnostics = prog_grammar.error_msgs_.str();
111 msg <<
"SYNTAX ERROR, MESSAGE(S) FROM PARSER:"
117 throw std::invalid_argument(msg.str());
119 }
catch (
const std::runtime_error& e) {
120 std::stringstream msg;
121 msg <<
"PROGRAM ERROR, MESSAGE(S) FROM PARSER:"
123 << prog_grammar.error_msgs_.str()
126 throw std::invalid_argument(msg.str());
129 bool consumed_all_input = (fwd_begin == fwd_end);
130 bool success = parse_succeeded && consumed_all_input;
134 std::stringstream msg;
135 if (!parse_succeeded)
136 msg <<
"PARSE FAILED." << std::endl;
137 if (!consumed_all_input) {
139 std::basic_stringstream<char> unparsed_non_ws;
140 unparsed_non_ws << boost::make_iterator_range(fwd_begin, fwd_end);
142 msg <<
"PARSING HALTED AT LINE "
143 << get_line(fwd_begin)
145 <<
"UNPARSED STAN PROGRAM: "
147 << unparsed_non_ws.str()
150 msg << std::endl << prog_grammar.error_msgs_.str() << std::endl;
151 throw std::invalid_argument(msg.str());
bool parse(std::ostream *output_stream, std::istream &input, const std::string &filename, const std::string &model_name, program &result)
double e()
Return the base of the natural logarithm.
bool is_nonempty(std::string &s)