【问题标题】:Boost::spirit partial skippingBoost::spirit 部分跳过
【发布时间】:2013-12-29 18:01:44
【问题描述】:

考虑以下解析器:

#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 匹配的部分未被捕获(并且我的断言通过)

【问题讨论】:

    标签: c++ boost-spirit boost-spirit-qi


    【解决方案1】:

    您通常会使用船长:

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

    Live On Coliru

    【讨论】:

    • 谢谢,我刚刚发现qi::omit[*qi::blank] 也可以解决问题。
    • @Allan 我之前写过更多关于船长的文章:Boost spirit skipper issues 的答案包括omitrawlexemeskipno_skip
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多