2011-12-13 6 views
0

私はboost :: spirit/fusionの新機能です。誰かが私に次のことがコンパイルされていない理由を説明してもらえますか? m_namem_settings変数をconfig構造体に直接置くとコンパイルと正常に動作しますが、2つの異なる構造体に分割するとコンパイルが失敗します。私は何が欠けていますか?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に変換する方法を指定していないようです。 config_sectionは2つの文字列で構成されていますが、configとconfig_sectionの間で変換をリンクするルールなしにconfigを解析しようとしました。これはコンパイルされているようだ。

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

ありがとう!それは理にかなっている – eddi

0

問題は(私が理解限り - それは2つの後件の文字列であるため)あなたの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で述べたように - それは私が設定をconfig_sectionsのベクトルを持つようにしたいと私はちょうど置く私の元のコードで – eddi

+0

の作品単純化のため上記の単一のconfig_section上記のコード内の はconfig_section(これは文字列のペアです)を持っています。これは2つの連続した文字列から構成可能であるはずです。 – eddi

+0

(少なくとも私のために)あなたに従うのは少し難しいです。私は提案をしてみましょう:この構造で新しい質問をしてみましょう: "私はこのようなファイルを持っています...私はそれを次のC構造にブースト・スピリットで解析したいです...それを行う最良の方法は何ですか? " – Kostya

関連する問題