Domanda

Non dovrebbe un semplice eol fare il trucco?

#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

Perché questi ultimi due non riescono?


questione connessa:

Uso boost :: spirito, come faccio richiedo parte di un record di essere sulla propria riga?

È stato utile?

Soluzione

Si utilizza space come lo skipper per le chiamate a phrase_parse. Questo parser corrisponde a qualsiasi carattere per il quale std::isspace restituisce true (supponendo che si sta facendo l'analisi basata ascii). Per questo motivo il \r\n nell'input vengono mangiati dal vostro skipper prima che possano essere visti dal parser eol.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top