Shouldn't a simple eol
do the trick?
#include <algorithm>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
using boost::spirit::ascii::space;
using boost::spirit::lit;
using boost::spirit::qi::eol;
using boost::spirit::qi::phrase_parse;
struct fix : std::unary_function<char, void> {
fix(std::string &result) : result(result) {}
void operator() (char c) {
if (c == '\n') result += "\\n";
else if (c == '\r') result += "\\r";
else result += c;
}
std::string &result;
};
template <typename Parser>
void parse(const std::string &s, const Parser &p) {
std::string::const_iterator it = s.begin(), end = s.end();
bool r = phrase_parse(it, end, p, space);
std::string label;
fix f(label);
std::for_each(s.begin(), s.end(), f);
std::cout << '"' << label << "\":\n" << " - ";
if (r && it == end) std::cout << "success!\n";
else std::cout << "parse failed; r=" << r << '\n';
}
int main() {
parse("foo", lit("foo"));
parse("foo\n", lit("foo") >> eol);
parse("foo\r\n", lit("foo") >> eol);
}
Output:
"foo": - success! "foo\n": - parse failed; r=0 "foo\r\n": - parse failed; r=0
Why do the latter two fail?
Related question:
Using boost::spirit, how do I require part of a record to be on its own line?
You are using space
as the skipper for your calls to phrase_parse. This parser matches any character for which std::isspace
returns true (assuming you're doing ascii based parsing). For this reason the \r\n
in the input are eaten by your skipper before they can be seen by your eol
parser.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With