C++ 部分跳过

C++ 部分跳过,c++,boost-spirit,boost-spirit-qi,C++,Boost Spirit,Boost Spirit Qi,考虑以下解析器: #include <assert.h> #include <iostream> #include <boost/spirit/include/qi.hpp> namespace qi = boost::spirit::qi; struct command_toten_parser : qi::grammar<const char *, std::string()> { command_toten_parser() :

考虑以下解析器:

#include <assert.h>
#include <iostream>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

struct command_toten_parser : qi::grammar<const char *, std::string()> {
    command_toten_parser() : command_toten_parser::base_type(r) {
        r = *qi::blank >> *qi::graph >> *qi::blank;
    }
    qi::rule<const char *, std::string()> r;
};

int main(int argc, char *argv[]) {
    command_toten_parser p;
    std::string c, s(" asdf a1 a2 ");
    const char *b = &*s.begin();
    const char *e = &*s.end();

    assert(qi::parse(b, e, p, c));
    std::string rest(b, e);

    assert(c == std::string("asdf"));
    assert(rest == std::string("a1 a2 "));

    return 0;
}
#包括
#包括
#包括
名称空间qi=boost::spirit::qi;
struct command_toten_解析器:qi::grammar{
command_toten_parser():command_toten_parser::base_type(r){
r=*qi::blank>>*qi::graph>>*qi::blank;
}
qi:规则r;
};
int main(int argc,char*argv[]){
命令_toten_parser p;
标准:字符串c,s(“asdf a1 a2”);
常量char*b=&*s.begin();
常量char*e=&*s.end();
assert(qi::parse(b,e,p,c));
std::字符串rest(b,e);
断言(c==std::string(“asdf”);
断言(rest==std::string(“a1a2”);
返回0;
}

如何更改解析器,以使由
*qi::blank
匹配的部分不会被捕获(并且我的断言会通过)

您通常会使用跳过程序:

qi::phrase_parse(b, e, +qi::graph, qi::blank, c);
将解析为
c==“asdfa1a2”
。显然,您不希望跳过标记的“内部”,让我们调用
qi::lexeme

qi::phrase_parse(b, e, qi::lexeme [+qi::graph], qi::blank, c);
它解析
“asdf”
并使
“a1 a2”
未解析

完全调整的示例显示了如何在语法结构中使用可配置的skipper:

#include <assert.h>
#include <iostream>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

template <typename Skipper = qi::blank_type>
struct command_toten_parser : qi::grammar<const char *, std::string(), Skipper> {
    command_toten_parser() : command_toten_parser::base_type(r) {
        r = qi::lexeme [ +qi::graph ];
    }
    qi::rule<const char *, std::string(), Skipper> r;
};

int main(int argc, char *argv[]) {
    command_toten_parser<> p;
    std::string c, s(" asdf a1 a2 ");
    const char *b = &s[0];
    const char *e = b + s.size();

    assert(qi::phrase_parse(b, e, p, qi::blank, c));
    std::string rest(b, e);

    assert(c == std::string("asdf"));
    assert(rest == std::string("a1 a2 "));

    return 0;
}

#include

谢谢,我刚刚发现
qi::omit[*qi::blank]
也能起作用。@Allan我以前写过更多关于Skipper的文章:答案包括
omit
raw
lexeme
skip
no\u skip