2015-02-17 2 views
1

Я пытаюсь создать грамматику духовной кармы, состоящую из нескольких правил. Эта грамматика предназначена для создания строки формата «(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11)». Правило для печати каждой отдельной структуры, которую я называю RowData, использует BOOST_FUSION_ADAPT_STRUCT для распечатки всех полей этой структуры. Если грамматика включает только это правило, грамматика отлично работает. Однако я использую эту структуру как значение std :: map. Ключ целого числа, но я не забочусь об этом значении и хочу его отбросить. Я создал правила для разбора std :: map, но правило, которое обрабатывает std :: пар, не может скомпилироваться для BOOST_SPIRIT_ASSERT_MATCH. Я создал небольшой код, который генерирует эту проблему. Линия pairRule = bs::karma::omit << rowDataRule; Если у кого-то есть идея, в чем проблема или как я могу сделать это по-другому, я был бы признателен за помощь.Проблема грамматики духовной кармы, когда в одном правиле используется BOOST_FUSION_ADAPT_STRUCT

Редактировать: Я использую gcc 4.8.3 на OpenSUSE 13.2, но получаю ту же ошибку с gcc 4.8.2 на Ubuntu 14.04 LTS. сообщение

main.cpp

#include <iostream> 
#include <map> 

#include <boost/cstdint.hpp> 
#include <boost/fusion/adapted/struct/adapt_struct.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 
#include <boost/fusion/include/make_tuple.hpp> 
#include <boost/fusion/include/std_pair.hpp> 
#include <boost/spirit/include/karma.hpp> 

namespace bs = boost::spirit; 

struct RowData 
{ 
    RowData() : 
     field0(0), 
     field1(0), 
     field2(0), 
     field3(0) 
    { 
    } 

    boost::uint64_t field0; 
    boost::uint64_t field1; 
    boost::uint64_t field2; 
    boost::uint64_t field3; 
}; 

BOOST_FUSION_ADAPT_STRUCT(
    RowData, 
    (boost::uint64_t, field0) 
    (boost::uint64_t, field1) 
    (boost::uint64_t, field2) 
    (boost::uint64_t, field3) 
) 

template <typename OutputIterator> 
struct RowDataGrammar : 
    bs::karma::grammar< OutputIterator, std::map<boost::uint64_t, RowData>() > 
{ 
    RowDataGrammar() : RowDataGrammar::base_type(allRowsRule) 
    { 
     rowDataRule = 
      bs::karma::lit("(") << 
      bs::karma::ulong_ << 
      bs::karma::lit(", ") << 
      bs::karma::ulong_ << 
      bs::karma::lit(", ") << 
      bs::karma::ulong_ << 
      bs::karma::lit(", ") << 
      bs::karma::ulong_ << 
      bs::karma::lit(")"); 

     // I only want the value from the map. The key is dropped. 
     pairRule = bs::karma::omit << rowDataRule; 

     allRowsRule = pairRule % ", "; 
    } 

private: 
    bs::karma::rule< OutputIterator, RowData() > rowDataRule; 
    bs::karma::rule< OutputIterator, std::pair<boost::uint64_t, RowData>() > pairRule; 
    bs::karma::rule< OutputIterator, std::map<boost::uint64_t, RowData>() > allRowsRule; 
}; 

int main(int argc, char** argv) 
{ 
    std::map<boost::uint64_t, RowData> rowMap; 

    RowData rowData; 
    rowData.field0 = 0; 
    rowData.field1 = 1; 
    rowData.field2 = 2; 
    rowData.field3 = 3; 
    rowMap.insert(std::make_pair(10, rowData)); 

    rowData.field0 = 6; 
    rowData.field1 = 7; 
    rowData.field2 = 8; 
    rowData.field3 = 9; 
    rowMap.insert(std::make_pair(20, rowData)); 

    std::string generatedString; 
    std::back_insert_iterator<std::string> sink(generatedString); 
    RowDataGrammar< std::back_insert_iterator<std::string> > grammar; 

    bs::karma::generate(sink, grammar, rowMap); 

    std::cout << "output :" << generatedString << std::endl; 
} 

Ошибка:

In file included from /usr/include/boost/fusion/support/tag_of.hpp:16:0, 
       from /usr/include/boost/fusion/support/category_of.hpp:11, 
       from /usr/include/boost/fusion/adapted/struct/detail/extension.hpp:13, 
       from /usr/include/boost/fusion/adapted/struct/adapt_struct.hpp:19, 
       from karmaTest.cpp:5: 
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp: In instantiation of ‘static void boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::false_ = mpl_::bool_<false>]’: 
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:229:19: required from ‘boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>& boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::operator=(const Expr&) [with Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]’ 
karmaTest.cpp:54:18: required from ‘RowDataGrammar<OutputIterator>::RowDataGrammar() [with OutputIterator = std::back_insert_iterator<std::basic_string<char> >]’ 
karmaTest.cpp:84:62: required from here 
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:185:13: error: no matching function for call to ‘assertion_failed(mpl_::failed************ (boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::false_ = mpl_::bool_<false>]::error_invalid_expression::************)(boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>))’ 
      BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr); 
      ^
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:185:13: note: candidate is: 
/usr/include/boost/mpl/assert.hpp:82:5: note: template<bool C> int mpl_::assertion_failed(typename mpl_::assert<C>::type) 
int assertion_failed(typename assert<C>::type); 
    ^
/usr/include/boost/mpl/assert.hpp:82:5: note: template argument deduction/substitution failed: 
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:185:13: note: cannot convert ‘boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_)::error_invalid_expression185::assert_arg<mpl_::bool_<false>, boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l> >()’ (type ‘mpl_::failed************ (boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::false_ = mpl_::bool_<false>]::error_invalid_expression::************)(boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>)’) to type ‘mpl_::assert<false>::type {aka mpl_::assert<false>}’ 
      BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr); 
+0

'не в compile'. И что такое сообщение об ошибке? Компилятор, который вы используете? – Kamiccolo

+0

Я добавил сообщение об ошибке, и я использую gcc 4.8.3. –

+0

Вы не можете использовать [omit] (http://www.boost.org/libs/spirit/doc/html/spirit/karma/reference/directive/omit.html), то вам нужно указать генератор, который вы хочу опустить. [Быстрый пример] (http://coliru.stacked-crooked.com/a/142cd68037689b00) (Возможно, вы должны использовать другой, более подходящий генератор вместо 'int_'). – llonesmiz

ответ

1

Как cv_and_he сказал, я использовал опускаем неправильно. Старый коллега, которого я протянул, сказал мне то же самое. Скорректированный код приведен ниже.

main.cpp

#include <iostream> 
#include <map> 

#include <boost/cstdint.hpp> 
#include <boost/fusion/adapted/struct/adapt_struct.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 
#include <boost/fusion/include/make_tuple.hpp> 
#include <boost/fusion/include/std_pair.hpp> 
#include <boost/spirit/include/karma.hpp> 

namespace bs = boost::spirit; 

struct RowData 
{ 
    RowData() : 
     field0(0), 
     field1(0), 
     field2(0), 
     field3(0) 
    { 
    } 

    boost::uint64_t field0; 
    boost::uint64_t field1; 
    boost::uint64_t field2; 
    boost::uint64_t field3; 
}; 

BOOST_FUSION_ADAPT_STRUCT(
    RowData, 
    (boost::uint64_t, field0) 
    (boost::uint64_t, field1) 
    (boost::uint64_t, field2) 
    (boost::uint64_t, field3) 
) 

template <typename OutputIterator> 
struct RowDataGrammar : 
    bs::karma::grammar< OutputIterator, std::map<boost::uint64_t, RowData>() > 
{ 
    RowDataGrammar() : RowDataGrammar::base_type(allRowsRule) 
    { 
     rowDataRule = 
      bs::karma::lit("(") << 
      bs::karma::ulong_ << 
      bs::karma::lit(", ") << 
      bs::karma::ulong_ << 
      bs::karma::lit(", ") << 
      bs::karma::ulong_ << 
      bs::karma::lit(", ") << 
      bs::karma::ulong_ << 
      bs::karma::lit(")"); 

     // I only want the value from the map. The key is dropped. 
     pairRule = bs::karma::omit[bs::karma::ulong_] << rowDataRule; 

     allRowsRule = pairRule % ", "; 
    } 

private: 
    bs::karma::rule< OutputIterator, RowData() > rowDataRule; 
    bs::karma::rule< OutputIterator, std::pair<boost::uint64_t, RowData>() > pairRule; 
    bs::karma::rule< OutputIterator, std::map<boost::uint64_t, RowData>() > allRowsRule; 
}; 

int main(int argc, char** argv) 
{ 
    std::map<boost::uint64_t, RowData> rowMap; 

    RowData rowData; 
    rowData.field0 = 0; 
    rowData.field1 = 1; 
    rowData.field2 = 2; 
    rowData.field3 = 3; 
    rowMap.insert(std::make_pair(10, rowData)); 

    rowData.field0 = 6; 
    rowData.field1 = 7; 
    rowData.field2 = 8; 
    rowData.field3 = 9; 
    rowMap.insert(std::make_pair(20, rowData)); 

    std::string generatedString; 
    std::back_insert_iterator<std::string> sink(generatedString); 
    RowDataGrammar< std::back_insert_iterator<std::string> > grammar; 

    bs::karma::generate(sink, grammar, rowMap); 

    std::cout << "output :" << generatedString << std::endl; 
} 
Смежные вопросы