32#define BOOST_SPIRIT_USE_PHOENIX_V3 1
34#include <boost/fusion/adapted.hpp>
35#include <boost/fusion/include/adapted.hpp>
37#include <boost/spirit/include/qi.hpp>
38#include <boost/phoenix.hpp>
41#include <boost/spirit/include/qi.hpp>
42#include <boost/spirit/include/qi_core.hpp>
43#include <boost/phoenix/core.hpp>
44#include <boost/phoenix/operator.hpp>
45#include <boost/fusion/include/std_pair.hpp>
47#include <boost/phoenix/bind/bind_function.hpp>
48#include <boost/phoenix/object/construct.hpp>
49#include <boost/bind/bind.hpp>
51#include <boost/fusion/adapted/adt/adapt_adt.hpp>
52#include <boost/fusion/include/adapt_adt.hpp>
54#include <boost/spirit/include/support_istream_iterator.hpp>
77 static_cast<unsigned char>(s[0]) == 0xEF &&
78 static_cast<unsigned char>(s[1]) == 0xBB &&
79 static_cast<unsigned char>(s[2]) == 0xBF)
94 out.reserve(s.size());
95 bool in_comment =
false;
127 auto skip_ws = [](std::string
const& t,
size_t i) {
128 while (i < t.size() && std::isspace(
static_cast<unsigned char>(t[i]))) ++i;
132 auto keyword_at = [](std::string
const& t,
size_t i,
char const* word) {
133 size_t n = std::strlen(word);
134 if (i + n > t.size())
return false;
135 for (
size_t k = 0; k < n; ++k)
136 if (std::toupper(
static_cast<unsigned char>(t[i+k])) != word[k])
return false;
137 if (i + n < t.size())
139 unsigned char c =
static_cast<unsigned char>(t[i+n]);
140 if (std::isalnum(c) || c==
'_')
return false;
145 size_t i = skip_ws(s, 0);
148 if (keyword_at(s, i,
"CONFIG"))
150 size_t e = s.find(
"END;", i);
151 if (e == std::string::npos)
153 i = skip_ws(s, e + 4);
157 if (keyword_at(s, i,
"INPUT"))
159 size_t body = skip_ws(s, i + 5);
160 size_t e = s.rfind(
"END;");
161 if (e == std::string::npos || e < body)
163 s = s.substr(body, e - body);
173 std::string::const_iterator begin,
174 std::string::const_iterator end,
175 std::string::const_iterator err_pos,
176 boost::spirit::info
const& what,
177 std::string
const& parser_name)
179 int line = 1 + (int)std::count(begin, err_pos,
'\n');
180 auto rev = std::find(std::make_reverse_iterator(err_pos),
181 std::make_reverse_iterator(begin),
'\n');
182 int col = 1 + (int)std::distance(rev.base(), err_pos);
184 std::string remaining(err_pos, end);
185 if (remaining.size() > 60)
186 remaining = remaining.substr(0, 60) +
"...";
187 if (remaining.empty())
188 remaining =
"<end of input>";
190 std::ostringstream oss;
191 oss <<
"[" << parser_name <<
"] parse error at line " << line
192 <<
", col " << col <<
":\n"
193 <<
" expected: " << what <<
"\n"
194 <<
" found: \"" << remaining <<
"\"\n";
200 std::string::const_iterator begin,
201 std::string::const_iterator end,
202 std::string::const_iterator err_pos,
203 boost::spirit::info
const& what,
204 std::string
const& parser_name)
208 throw std::runtime_error(msg);
void ReportParseError(std::string::const_iterator begin, std::string::const_iterator end, std::string::const_iterator err_pos, boost::spirit::info const &what, std::string const &parser_name)
Report a parse error (via FormatParseError) to the log, for use in a Spirit on_error handler.
Definition qi_files.hpp:199
std::string FormatParseError(std::string::const_iterator begin, std::string::const_iterator end, std::string::const_iterator err_pos, boost::spirit::info const &what, std::string const &parser_name)
Format a human-readable parse-error message (line, column, expected, and found text).
Definition qi_files.hpp:172
void StripUTF8BOM(std::string &s)
Strip a leading UTF-8 byte-order mark (EF BB BF) from s in place, if present.
Definition qi_files.hpp:74
void StripClassicComments(std::string &s)
Remove Bertini 1 comments from s in place: everything from a % to the end of its line.
Definition qi_files.hpp:91
void StripClassicFileWrappers(std::string &s)
Unwrap a Bertini 1 classic input FILE down to the declarations the grammar reads.
Definition qi_files.hpp:125
Definition algorithm_builder.hpp:36
UTF-8-aware identifier building blocks for the classic (Bertini 1) Qi grammar.