How do I parse end-of-line with boost::spirit::qi?

匆匆过客 提交于 2019-12-05 18:21:30

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/2429485/how-do-i-parse-end-of-line-with-boostspiritqi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!