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/classic_position_iterator.hpp>
11 #include <boost/spirit/include/phoenix_core.hpp>
12 #include <boost/spirit/include/phoenix_function.hpp>
13 #include <boost/spirit/include/phoenix_fusion.hpp>
14 #include <boost/spirit/include/phoenix_object.hpp>
15 #include <boost/spirit/include/phoenix_operator.hpp>
16 #include <boost/spirit/include/phoenix_stl.hpp>
17 #include <boost/spirit/include/support_multi_pass.hpp>
18 #include <boost/tuple/tuple.hpp>
19 #include <boost/variant/apply_visitor.hpp>
20 #include <boost/variant/recursive_variant.hpp>
47 return c ==
' ' || c ==
'\n' || c ==
'\r' || c ==
'\t';
51 for (
size_t i = 0; i < s.size(); ++i)
62 inline bool parse(std::ostream* output_stream,
64 const std::string& filename,
66 namespace classic = boost::spirit::classic;
68 using boost::spirit::classic::position_iterator2;
69 using boost::spirit::multi_pass;
70 using boost::spirit::make_default_multi_pass;
71 using std::istreambuf_iterator;
73 using boost::spirit::qi::expectation_failure;
74 using boost::spirit::classic::file_position_base;
75 using boost::spirit::qi::phrase_parse;
79 typedef istreambuf_iterator<char> base_iterator_type;
80 typedef multi_pass<base_iterator_type> forward_iterator_type;
81 typedef position_iterator2<forward_iterator_type> pos_iterator_type;
83 base_iterator_type in_begin(input);
85 forward_iterator_type fwd_begin = make_default_multi_pass(in_begin);
86 forward_iterator_type fwd_end;
88 pos_iterator_type position_begin(fwd_begin, fwd_end, filename);
89 pos_iterator_type position_end;
94 bool parse_succeeded =
false;
96 parse_succeeded = phrase_parse(position_begin,
101 std::string diagnostics = prog_grammar.
error_msgs_.str();
103 *output_stream <<
"DIAGNOSTIC(S) FROM PARSER:"
108 }
catch (
const expectation_failure<pos_iterator_type>&
e) {
109 const file_position_base<std::string>& pos =
e.first.get_position();
110 std::stringstream msg;
111 msg <<
"EXPECTATION FAILURE LOCATION: file=" << pos.file
112 <<
"; line=" << pos.line
113 <<
", column=" << pos.column
115 msg << std::endl <<
e.first.get_currentline()
117 for (
int i = 2; i < pos.column; ++i)
120 << std::endl << std::endl;
121 std::string diagnostics = prog_grammar.
error_msgs_.str();
124 <<
"DIAGNOSTIC(S) FROM PARSER:"
128 throw std::invalid_argument(msg.str());
130 }
catch (
const std::runtime_error&
e) {
131 std::stringstream msg;
132 msg <<
"LOCATION: unknown" << std::endl;
134 msg <<
"DIAGNOSTICS FROM PARSER:" << std::endl;
135 msg << prog_grammar.
error_msgs_.str() << std::endl << std::endl;
136 throw std::invalid_argument(msg.str());
139 bool consumed_all_input = (position_begin == position_end);
140 bool success = parse_succeeded && consumed_all_input;
143 std::stringstream msg;
144 if (!parse_succeeded)
145 msg <<
"PARSE DID NOT SUCCEED." << std::endl;
146 if (!consumed_all_input)
147 msg <<
"ERROR: non-whitespace beyond end of program:" << std::endl;
149 const file_position_base<std::string>& pos
150 = position_begin.get_position();
151 msg <<
"LOCATION: file=" << pos.file
152 <<
"; line=" << pos.line
153 <<
", column=" << pos.column
155 msg << position_begin.get_currentline()
157 for (
int i = 2; i < pos.column; ++i)
159 msg <<
" ^-- starting here"
160 << std::endl << std::endl;
162 msg <<
"DIAGNOSTICS FROM PARSER:" << std::endl;
163 msg << prog_grammar.
error_msgs_.str() << std::endl << std::endl;
165 throw std::invalid_argument(msg.str());
bool is_nonempty(std::string &s)
bool parse(std::ostream *output_stream, std::istream &input, const std::string &filename, program &result)
double e()
Return the base of the natural logarithm.
Probability, optimization and sampling library.
std::stringstream error_msgs_