2011-12-13 145 views
0

我對boost :: spirit/fusion很新穎。有人可以向我解釋爲什麼以下內容不能編譯?如果我將m_namem_settings變量直接放置在配置結構中,但編譯並工作正常,但在將它們分隔爲兩個不同的結構時無法編譯。我錯過了什麼?boost :: spirit編譯問題BOOST_FUSION_ADAPT_STRUCT

順便說一句,該行代碼,使編譯器噴出的極大數boost::spirit errors is: cfg = section >> node;

#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_fusion.hpp> 
#include <boost/spirit/include/phoenix_stl.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 

#include <iostream> 
#include <string> 
#include <vector> 

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

struct config_section 
{ 
    std::string m_name; 
    std::string m_settings; 
}; 

struct config 
{ 
    config_section m_sections; 
}; 

BOOST_FUSION_ADAPT_STRUCT(
    config_section, 
    (std::string, m_name) 
    (std::string, m_settings) 
) 

BOOST_FUSION_ADAPT_STRUCT(
    config, 
    (config_section, m_sections) 
) 

template <typename Iterator> 
struct config_grammar : qi::grammar<Iterator, config(), ascii::space_type> 
{ 
    config_grammar() : config_grammar::base_type(cfg) 
    { 
    using qi::lexeme; 
    using qi::lit; 
    using ascii::string; 
    using ascii::char_; 
    using namespace qi::labels; 

    section %= '[' >> lexeme[+(char_ - ']')] >> ']'; 

    node %= !lit('[') >> lexeme[+(char_ - '\n')]; 

    cfg %= section >> node; 
    } 

    qi::rule<Iterator, config(), ascii::space_type> cfg; 
    qi::rule<Iterator, std::string(), ascii::space_type> node; 
    qi::rule<Iterator, std::string(), ascii::space_type> section; 
}; 

template <typename Iterator> 
bool parse_config(Iterator first, Iterator last) 
{ 
    using qi::double_; 
    using qi::phrase_parse; 
    using ascii::space; 
    using boost::phoenix::ref; 

    config result; 
    config_grammar<Iterator> config_parser; 

    bool r = phrase_parse(first, last, config_parser, space, result); 
    if (first != last) // fail if we did not get a full match 
    return false; 

    return r; 
} 

int main() 
{ 
    std::string input = "[section]\nstuff"; 

    bool b = parse_config(input.begin(), input.end()); 

    if (b) 
    std::cout << "Success" << std::endl; 
    else 
    std::cout << "Failure" << std::endl; 

    return 0; 
} 

謝謝!

回答

1

問題似乎是,你沒有指定如何從config_section轉換爲配置。你告訴精神,一個config_section由2個字符串組成,但是嘗試解析一個沒有規則的配置來鏈接config和config_section之間的轉換。這似乎編譯。

template <typename Iterator> 
struct config_grammar : qi::grammar<Iterator, config(), ascii::space_type> 
{ 
    config_grammar() : config_grammar::base_type(cfg) 
    { 
    using qi::lexeme; 
    using qi::lit; 
    using ascii::string; 
    using ascii::char_; 
    using namespace qi::labels; 

    section %= '[' >> lexeme[+(char_ - ']')] >> ']'; 

    node %= !lit('[') >> lexeme[+(char_ - '\n')]; 

    //create a rule to specify conversion of a config_section to a config 
    cfg %= cfg_sec; 
    //this a now a cfg_sec (which is what you declared to be composed of 2 
    // strings) 
    cfg_sec %= section >> node; 
    } 

    qi::rule<Iterator, config(), ascii::space_type> cfg; 
    //add new declaration here for cfg_sec 
    qi::rule<Iterator, config_section(), ascii::space_type> cfg_sec; 
    qi::rule<Iterator, std::string(), ascii::space_type> node; 
    qi::rule<Iterator, std::string(), ascii::space_type> section; 
}; 
0

的問題是,你的cfg規則和語法config_grammar屬性不config,但(據我瞭解 - 因爲它是兩個相繼字符串)config_section。此替換後:

struct config_grammar : qi::grammar<Iterator, config_section(), ascii::space_type> 
.... 
qi::rule<Iterator, config_section(), ascii::space_type> cfg; 

它編譯。

我建議您瞭解更多關於規則的屬性及其工作方式 - 否則您會一直迷路。

+0

我在OP,當我不做嵌套的結構(這是找您做什麼)提到的 - 它的工作原理 – eddi 2012-01-05 21:18:59

+0

在我的原代碼,我想配置有config_sections的載體,我把剛上面簡單的config_section 在我的代碼上面config配置了1個config_section(這又是一對字符串),並且我認爲這應該是可以從兩個後續字符串屬性中構造出來的。 – eddi 2012-01-05 21:24:40