разобрать строку в структуру с помощью Boost Spirit

У меня есть следующий код, который мне нужен для анализа строки и перемещения ее в структуру, определенную следующим образом:

#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);

Хорошо, проблема в том, что мой код отлично компилируется, когда моя структура имеет 10 полей или меньше, но выдает ошибки, когда у меня больше полей в структуре, поэтому я предположил, что это из-за параметра SPIRIT_ARGUMENTS_LIMIT, потому что его значение по умолчанию равно 10.

Я попытался определить для этого параметра желаемый размер, прежде чем включать файлы заголовков духа, но все равно получаю ошибки компиляции.

Как мне решить эту проблему?


person Shohreh    schedule 19.05.2013    source источник


Ответы (1)


Если вы проверите, на что жалуется компилятор, вы увидите что-то вроде этого:

....
/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, так как контейнер(ы) fusion объединяет совпадающие атрибуты.

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

Я бы использовал эти два определения перед всеми другими включаемыми файлами, чтобы переопределить их значения по умолчанию:

#define FUSION_MAX_VECTOR_SIZE      20
#define SPIRIT_ARGUMENTS_LIMIT      20
person G. Civardi    schedule 19.05.2013