2011-07-27 7 views
1

Unixのファイルパスをフォルダのペア(キーと値のペア - アプリケーションに必要なもの)に解析しようとしています。問題は、qi :: ruleを正しく使用してパーサーを定義できないことです。私は完全に理解できないコンパイラエラーのページを手に入れます(質問は単純ですが、本当に固まって進行することができない場合は申し訳ありません)Spirit :: Qiでルールを定義できません

以下はプログラムスニペットです。

更新:Nicolとildjarnの提案に従ってプログラムを修正しましたが、問題は解決しません。

namespace client 
{ 
    namespace qi = boost::spirit::qi; 
    namespace ascii = boost::spirit::ascii; 
    namespace phoenix = boost::phoenix; 

    template <typename Iterator> 
    bool parse_data(Iterator first, Iterator last, std::vector< std::pair<std::string, std::string> >& v) 
    { 
     using qi::double_; 
     using qi::char_; 
     using qi::phrase_parse; 
     using qi::_1; 
     using ascii::space_type; 
     using phoenix::ref; 
     using phoenix::push_back; 

     std::pair<std::string, std::string> p; 

     qi::rule<Iterator, std::string()> key = '/' >> *char_("a-zA-Z0-9"); 
     qi::rule<Iterator, std::string()> val = '/' >> *char_("a-zA-Z0-9"); 
     qi::rule<Iterator, std::pair<std::string, std::string>()> ppair = key >> val ; 

     //bool r = phrase_parse(
     bool r = parse(
      first, 
      last, 
      (
       +ppair[push_back(ref(v), _1)] 
      ) 
      ); 

     if (first != last) 
      return false; 
     return r; 
    } 
} 

int 
main() 
{ 
    std::string str; 

    while (getline(std::cin, str)) 
    { 
     if (str.empty()) 
      break; 

     std::vector< std::pair<std::string, std::string> > vec_pair; 
     if(client::parse_data(str.begin(), str.end(), vec_pair)) 
     { 
      std::cout << std::endl << "Parsing done" << std::endl; 
      std::cout << "Strings are " ; 

      std::pair<std::string, std::string> temp; 
      for(std::vector< std::pair<std::string, std::string> >::iterator i = vec_pair.begin(); i < vec_pair.end(); i++) 
      { 
       temp = *i; 
       std::cout << temp.first <<"|" << temp.second; 
      } 
      std::cout << std::endl; 
     } 
     else 
     { 
      std::cout << "Parsing Failed" << std::endl; 
     } 
    } 

    return 0; 
} 

エラー:

/usr/local/include/boost_1_46_1/boost/spirit/home/qi/detail/assign_to.hpp:109: error: no matching function for call to 
‘std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::pair(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)’ 
/usr/lib/gcc/x86_64-redhat-linux/4.3.2/../../../../include/c++/4.3.2/bits/stl_pair.h:88: note: candidates are: 
std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _T2 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >] 
/usr/lib/gcc/x86_64-redhat-linux/4.3.2/../../../../include/c++/4.3.2/bits/stl_pair.h:84: note:     std::pair<_T1, _T2>::pair() [with _T1 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _T2 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >] 
/usr/lib/gcc/x86_64-redhat-linux/4.3.2/../../../../include/c++/4.3.2/bits/stl_pair.h:73: note:     std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::pair(const std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&) 

は、あなたは私がこの問題を解決する助けてくださいことはできますか?

おかげ

+0

最初に飛び出すのは、あなたが 'phrase_parse'を使っていることですが、' rule'sにスキッパーの種類を指定していません。 – ildjarn

+0

@ildjarn私は何もスキップしようとしていません。私はスラッシュの間のすべてをキャプチャしたい。 – Nik

+0

次に、 'phrase_parse'ではなく' parse'を使うべきです。 : - ] – ildjarn

答えて

2

は(ブーストV1.47)私のために罰金をコンパイルします。

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix.hpp> 
#include <boost/fusion/include/std_pair.hpp> 

れ、この(最新)バージョンでの精神にかなりの実装の変更が行われていることに注意してくださいなぜあなたがここでコンパイルするのかを説明するかもしれませんが(あなたが古いバージョンを使用しているのであれば)あなたのためではありません。

+0

はい、私はブースト1.46を使用しています。私は1.47を使用してコンパイルするかどうか試します。ありがとう – Nik

+0

ブースト1.47を使用した後に問題が解決されました!再度、感謝します。 – Nik

3

スピリットは、ユーザー定義のデータ構造にデータを解析するために、あなたは、アダプタを用意する必要があります。これはBoost.Fusionで行われ、shown in the documentationとなります。このグローバルスコープ(あなたがclient名前空間を終了する必要があり、これを定義し、その後、再入力client名前空間)を定義しなければならないことを

BOOST_FUSION_ADAPT_STRUCT(
    client::pair, 
    (std::string, key) 
    (std::string, val) 

注:あなたはこれを行う必要があります。

しかし、このような狭いケースでは、解析をオフにしてstd::pair<std::string, std::string>にする方がよいでしょう。スピリットは、そのようなことをどのように処理するかを知っています。

また、これはildjarnが指摘したparseparse_phraseの問題に加えてあります。どちらも修正する必要があります。

もう1つ。パースするルールを再定義する必要があります。これは:

ppair >> *(ppair) 

生の属性タイプがboost.tuple<client::pair, std::vector<client::pair> >です。これを行う場合:

+ppair 

その後、きれいになるstd::vector<client::pair>。これらの#は、上記のプログラムを含んで追加した後

+0

ありがとう!あなたの提案に従ってプログラムを修正しましたが、まだコンパイルされません。 (上記のUPDATEを参照) – Nik

関連する問題