2

私は boost::spirit を使用して、テキストを固定サイズの配列を含む構造体に解析しています。の例に従いながら

qi/boost_array.cpp

std::array (またはboost::array) を含む構造体に解析するためにそれを使用しようとすると、BOOST_FUSION_ADAPT_STRUCTがどのように機能するかのために、ヘルパーresult_of::adapt_array< some_array_type >::typeを構造体も。

BOOST_FUSION_ADAPT_ADTを使用してラッパーを作成することは可能だと思いますが、構造体の小さなアダプター オーバーヘッドを取り除くだけではやり過ぎのようです。私はそれの多くのインスタンスを持っていないので、メモリの観点からそれと一緒に暮らすことができますが、ノイズも発生します.

また、ノイズの一部を隠すために配列型をカプセル化するのではなく、配列型から派生するアダプターを作成することも可能だと思いますが、既存のすべての構造体を変更する必要があり、パーサーのオーバーヘッドが外部に漏れます。いい解決策。

私が間違っていることは明らかですか、それともパーサーにカプセル化できるようにバックグラウンドでオーバーヘッドをルーティングする新しいヘルパーが存在しますか?

Boost::spirit::x3 の属性として std::array を使用することを認識して います。

実際の例

これが私の現在のコードです:

#include <string>
#include <array>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

// ...code from http://www.boost.org/doc/libs/1_60_0/libs/spirit/example/qi/boost_array.cpp here

typedef result_of::adapt_array<std::array<double, 6> >::type AdaptedArrayType;

struct StructWithArray
{
    StructWithArray()
        : adaptedAry_(ary_)
    {}

    double dummy_; // see https://stackoverflow.com/questions/19823413/spirit-qi-attribute-propagation-issue-with-single-member-struct
    std::array<double, 6> ary_;
    AdaptedArrayType adaptedAry_;
};

BOOST_FUSION_ADAPT_STRUCT(
    StructWithArray
    ,
    (double, dummy_)
    (AdaptedArrayType, adaptedAry_)
    )

template <typename Iterator, typename Skipper>
struct StructWithArrayParser
    : qi::grammar<Iterator, StructWithArray(), Skipper>
{
    StructWithArrayParser() : StructWithArrayParser::base_type(start)
    {
        using qi::double_;

        arrayLine %= double_ > double_ > double_ > double_ > double_ > double_;
        start %= double_ > arrayLine;
    }

    qi::rule<Iterator, AdaptedArrayType(), Skipper> arrayLine;
    qi::rule<Iterator, StructWithArray(), Skipper> start;
};

int main() {
    std::string arrayStr = "0 1 2 3 4 5 6";
    std::string::const_iterator it = arrayStr.begin();
    std::string::const_iterator endIt = arrayStr.end();
    StructWithArrayParser<std::string::const_iterator, ascii::space_type> grammar;
    StructWithArray structWithArray;
    bool ret = phrase_parse(it, endIt, grammar, ascii::space, structWithArray);
    return 0;
}
4

1 に答える 1

2

あなたはどこかへ行っています :) あなたはすぐにスピリットでワープ速度に達したようです.

編集済み質問を詳しく読んだ後、あなたがより短く、邪魔にならない方法を求めていることに気付きました。

邪魔にならない修正方法はわかりませんが、それboost::arrayを専門とする場合は使用できますis_container

それはかなり控えめですが、それでもあなたのタイプを変更します。

Live On Coliru

#include <boost/fusion/include/tuple.hpp>
#include <boost/fusion/adapted/boost_array.hpp>
#include <boost/spirit/include/qi.hpp>
#include <string>

namespace boost { namespace spirit { namespace traits {
    template <typename T, size_t N>
        struct is_container<boost::array<T, N>, void> : mpl::false_ { };
} } }

namespace qi    = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

struct StructWithArray
{
    double dummy_; // see http://stackoverflow.com/questions/19823413/spirit-qi-attribute-propagation-issue-with-single-member-struct
    boost::array<double, 6> ary_;
};

BOOST_FUSION_ADAPT_STRUCT(StructWithArray, dummy_, ary_)

template <typename Iterator, typename Skipper>
struct StructWithArrayParser
    : qi::grammar<Iterator, StructWithArray(), Skipper>
{
    StructWithArrayParser() : StructWithArrayParser::base_type(start)
    {
        using qi::double_;

        arrayLine = double_ > double_ > double_ > double_ > double_ > double_;
        start     = double_ > arrayLine;
    }

  private:
    qi::rule<Iterator, boost::array<double, 6>(), Skipper> arrayLine;
    qi::rule<Iterator, StructWithArray(), Skipper> start;
};

int main() {
    std::string arrayStr = "0 1 2 3 4 5 6";
    using It = std::string::const_iterator;
    It it = arrayStr.begin(), endIt = arrayStr.end();
    StructWithArrayParser<It, ascii::space_type> grammar;

    StructWithArray structWithArray;
    bool ret = phrase_parse(it, endIt, grammar, ascii::space, structWithArray);
    std::cout << std::boolalpha << ret << "\n";

    for (double v : structWithArray.ary_)
        std::cout << v << " ";
}

版画:

true
1 2 3 4 5 6 
于 2015-12-23T19:35:01.020 に答える