2010-03-11 56 views
9

不應該有一個簡單的eol這樣做嗎?如何用boost :: spirit :: qi解析行尾?

#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); 
} 

輸出:

"foo": 
    - success! 
"foo\n": 
    - parse failed; r=0 
"foo\r\n": 
    - parse failed; r=0

爲什麼後兩個失敗?


相關問題:

Using boost::spirit, how do I require part of a record to be on its own line?

回答

13

您使用space作爲隊長爲您來電phrase_parse。此解析器匹配std::isspace返回true的任何字符(假設您正在執行基於ascii的解析)。出於這個原因,輸入中的\r\n被您的隊長吃掉,然後您的eol解析器可以看到它們。

+1

使用'phrase_parse(it,end,p,space - eol)'允許'eol'成功。謝謝! – 2010-03-12 16:21:24

+1

@GregBacon當我輸入'space-eol'時,我得到了非常奇怪而長的錯誤信息。 – Dilawar 2011-12-26 19:55:24

+1

@Dilawar看到這個答案http://stackoverflow.com/a/10469726/85371]的相關提示和技術來改變船長的行爲 – sehe 2012-05-06 10:24:11

相關問題