2

文字列を解析し、次のように定義された構造体に移動する必要がある次のコードがあります。

#include "boost\spirit\include\classic.hpp"
#include "boost\spirit\include\qi.hpp"
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
#include <regex>
#include <string>
#include <boost\chrono.hpp>
#include <ctype.h>
#include <iostream>

struct my_struct
{
   std::string s1;
   std::string s2;
   std::string s3;
   std::string s4;
   std::string s5;
   std::string s6;
   std::string s7;
   std::string s8;
   std::string s9;
   std::string s10;
   std::string s11;
};

BOOST_FUSION_ADAPT_STRUCT(
    my_struct,
    (std::string, s1 )
    (std::string, s2 )
    (std::string, s3 )
    (std::string, s4 )
    (std::string, s5 )
    (std::string, s6 )
    (std::string, s7 )
    (std::string, s8 )
    (std::string, s9 )
    (std::string, s10)
    (std::string, s11) 
)

私の文法はこれです:

template <typename Iterator>
struct my_struct_parser : qi::grammar<Iterator, my_struct(), ascii::space_type>
{
    my_struct_parser() : my_struct_parser::base_type(start)
    {
        using ascii::char_;
        using qi::digit;
        using qi::alpha;

        start %=
            qi::alpha>>"-"
            >>qi::repeat(9)[digit]>>"-"
            >>+(digit)>>"-"
            >>+(digit)>>"-"
            >>+(digit)>>"-"
            >>qi::repeat(5)[digit]>>"-"
            >>+char_("a-zA-Z")>>"-"
            >>qi::repeat(2)[digit]>>"-"
            >>+(digit)>>"-"
            >>+(digit)>>"-"
           >>+(qi::alpha)

           >>-('-'>>+(char_("a-zA-Z0-9@$")));
    }
    qi::rule<Iterator, my_struct(), ascii::space_type> start;
};

次に、次のコード行を使用して文字列を解析します。

       my_struct & emp;//this is passed as an argument to a function
       typedef my_struct_parser<iterator_type> my_struct_parser_type;
       my_struct_parser_type parser;
       std::string::const_iterator iter = filename.begin();
       std::string::const_iterator end = filename.end();
       bool r =
       boost::spirit::qi::phrase_parse(iter, end,parser,boost::spirit::ascii::space ,emp);

OK、問題は、構造体のフィールドが 10 個以下の場合はコードが正常にコンパイルされることですが、構造体のフィールドがそれ以上になるとエラーが発生するSPIRIT_ARGUMENTS_LIMITため、デフォルト値が 10 であるため、パラメーターが原因であると推測しました。

スピリット ヘッダー ファイルをインクルードする前に、このパラメーターを必要なサイズに定義しようとしましたが、それでもコンパイル エラーが発生します

この問題を解決するにはどうすればよいですか?

4

1 に答える 1

7

コンパイラが何を訴えているかを確認すると、次のように表示されます。

....
/usr/include/boost/fusion/container/vector/convert.hpp:26:13: error: invalid use of incomplete type ‘struct boost::fusion::detail::as_vector<12>’
....
/usr/include/boost/fusion/container/vector/detail/as_vector.hpp:26:12: error: declaration of ‘struct boost::fusion::detail::as_vector<12>’

私も少し前にこの問題に遭遇しました。構造体に 10 個を超えるフィールドが含まれている場合は、融合コンテナーが一致した属性を集約するため、FUSION_MAX_VECTOR_SIZEも再定義する必要があります。

http://www.boost.org/doc/libs/1_52_0/libs/fusion/doc/html/fusion/container/vector.html http://www.boost.org/doc/libs/1_52_0/libs/spirit /doc/html/spirit/qi/quick_reference/compound_attribute_rules.html

これらの 2 つの定義を他のすべてのインクルード ファイルの前に使用して、デフォルト値をオーバーライドします。

#define FUSION_MAX_VECTOR_SIZE      20
#define SPIRIT_ARGUMENTS_LIMIT      20
于 2013-05-19T06:02:22.620 に答える