2011-12-13 99 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