2

"my/file.hpp"以下のプログラムは、やなどの C++ ヘッダー インクルード文字列を解析しようとします<my/file.hpp>。理由がわかりませんが、私のコードは"ヘッダーを解析できません。これはスピリットのバグですか、それとも明らかな何かが欠けていますか?

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>
#include <cassert>

using namespace boost::spirit::x3;

int main() {

    auto header_name_brackets = '<' >> *(~char_('>')) >> '>';
    auto header_name_quotes   = '"' >> *(~char_('>')) >> '"'; 

    {
        auto s = std::string{"<my/file.hpp>"};
        std::string parsed;
        assert(phrase_parse(s.begin(), s.end(), header_name_brackets, space, parsed));
    }

    {
        auto s = std::string{"\"my/file.hpp\""};
        std::string parsed;
        // this assert fails, but I don't know why.
        assert(phrase_parse(s.begin(), s.end(), header_name_quotes, space, parsed));
    }
}
4

3 に答える 3

4

受け入れることができるよりも多くの回答が既にあるので (:)) ここに私の 0.02 ドルがあります:

template <typename Prefix, typename Postfix>
static auto quoted_(Prefix const& prefix, Postfix const& postfix) {
    using namespace boost::spirit::x3;
    return rule<struct _, std::string, true> {} = omit[prefix] >> *(char_ - postfix) >> omit[postfix];
}

今、あなたは書くことができます

auto header_name_brackets = quoted_('<', '>');
auto header_name_quotes   = quoted_('"');

2 番目は、明らかな便利な過負荷を想定しています。

別のバグ

実際、区切り文字内の空白をスキップするバグがあると思います。追加して修正しlexeme[]ます:

template <typename Prefix, typename Postfix>
static auto quoted_(Prefix const& prefix, Postfix const& postfix) {
    using namespace boost::spirit::x3;
    return rule<struct _, std::string, true> {} = lexeme [ 
        omit[prefix] >> *(char_ - postfix) >> omit[postfix] 
    ];
}

完全なデモを見る:

Live On Coliru

#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <cassert>

template <typename Prefix, typename Postfix>
static auto quoted_(Prefix const& prefix, Postfix const& postfix) {
    using namespace boost::spirit::x3;
    return rule<struct _, std::string, true> {} = lexeme [ 
        omit[prefix] >> *(char_ - postfix) >> omit[postfix] 
    ];
}

template <typename Prefix>
static auto quoted_(Prefix const& prefix) { return quoted_(prefix, prefix); }

int main() {
    using boost::spirit::x3::space;

    auto header_name_brackets = quoted_('<', '>');
    auto header_name_quotes   = quoted_('"');

    {
        auto s = std::string{"<my/file.hpp>"};
        std::string parsed;
        assert(phrase_parse(s.begin(), s.end(), header_name_brackets, space, parsed));
    }

    {
        auto s = std::string{"\"my/file.hpp\""};
        std::string parsed;
        assert(phrase_parse(s.begin(), s.end(), header_name_quotes, space, parsed));
    }

    std::cout << "Bye\n";
}
于 2016-08-20T20:07:06.630 に答える
2

このルールを変更する必要があります:

auto header_name_quotes   = '"' >> *(~char_('>')) >> '"'; 

auto header_name_quotes   = '"' >> *(~char_('\"')) >> '"'; 
于 2016-08-20T17:48:14.123 に答える
2

これは私にとってはうまくいきます:

#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>
#include <cassert>

using namespace boost::spirit::x3;

int main() {

    auto header_name_brackets = '<' >> *(~char_('>')) >> '>';
    auto header_name_quotes   = '"' >> *(~char_('"')) >> '"'; 

    {
        auto s = std::string{"<my/file.hpp>"};
        std::string parsed;
        assert(phrase_parse(s.begin(), s.end(), header_name_brackets, space, parsed));
    }

    {
        auto s = std::string{"\"my/file.hpp\""};
        std::string parsed;
        // this assert fails, but I don't know why.
        assert(phrase_parse(s.begin(), s.end(), header_name_quotes, space, parsed));
    }
}

"最初の場合と同様に、2 番目のケースを除いてすべての文字を一致させる必要があることに注意してください>

于 2016-08-20T17:48:30.230 に答える