考虑以下解析器:
#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::blank
匹配的部分(并且我的断言通过)
答案 0 :(得分:2)
您通常使用船长:
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 "
未分析。
完全调整的样本,展示了如何使用可配置的语料结构的队列:
#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;
}