2011-07-01 15 views
3

Boost Spiritの新機能で、Boost Spirit 2.4.2を使用してJSONパーサーを作成しようとしました(Boost 1.46.1 )。セマンティックアクション/属性を実行しようとすると、以下のコードの場合、私はエラーを取得:Boost Spirit:エラーC2664、 'const boost :: phoenix :: actor <Eval>'を 'char'に変換できません

Error 1 error C2664: 'void (char)' : cannot convert parameter 1 from 'const boost::phoenix::actor<Eval>' to 'char' 

私はいくつかの質問を見ましたが、彼らは本当に私の場合には適用されません。親切にお手伝いください。ありがとうございました!

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

#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_stl.hpp> 
#include <boost/spirit/include/phoenix_object.hpp> 
#include <boost/spirit/include/phoenix_container.hpp> 
#include <boost/spirit/include/phoenix_function.hpp> 
#include <boost/spirit/include/phoenix_fusion.hpp> 
#include <boost/fusion/include/adapt_assoc_struct.hpp> 
#include <boost/fusion/include/io.hpp> 
#include <boost/bind.hpp> 
#include <boost/function.hpp> 

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

void print_char(char c) 
{ 
    std::cout << c; 
} 

template <typename Iterator> 
struct json_grammar : qi::grammar<Iterator, ascii::space_type> 
{ 
    json_grammar() : json_grammar::base_type(start) 
    { 
     using ascii::alpha; 
     using ascii::alnum; 
     using qi::long_long; 
     using qi::long_double; 
     using qi::lit; 
     using qi::char_; 
     using qi::lexeme; 
     typedef boost::function<void(char)> char_action_t; 

     //char_action_t beginObj (boost::bind(&print_char, qi::_1)); 

     // 
     start = 
      char_('{')   [boost::bind(&print_char, qi::_1)] 
      >> -(js_member % ',') 
      >> char_('}') 
     ; 
     // 
     js_member = 
      js_key 
      >> ':' >> js_value 
     ; 
     // 
     js_key = (alpha >> *alnum) | js_string 
     ; 
     // 
     js_string = js_single_quoted_str | js_double_quoted_str 
     ; 
     // 
     js_array = lit('[') >> -(js_value % ',') >> lit(']') 
     ; 
     // 
     js_bool = lit("true") | lit("false") 
     ; 
     // 
     js_null = lit("null") 
     ; 
     // 
     js_value = js_string | js_num | js_array | start | js_bool | js_null | js_empty_str; 
     // 
     js_single_quoted_str = (lexeme["'" >> +((char_ | ' ' | "\t") - "'") >> "'"]); 
     // 
     js_double_quoted_str = (lexeme['"' >> +((char_ | ' ' | "\t") - '"') >> '"']); 
     // 
     js_empty_str = lit("''") | lit("\"\""); 
     // 
     js_num = long_long | long_double; 
    } 

    qi::rule<Iterator, ascii::space_type> start; 
    qi::rule<Iterator, ascii::space_type> js_member; 
    qi::rule<Iterator, ascii::space_type> js_key; 
    qi::rule<Iterator, ascii::space_type> js_value; 
    qi::rule<Iterator, ascii::space_type> js_string; 
    qi::rule<Iterator, ascii::space_type> js_single_quoted_str; 
    qi::rule<Iterator, ascii::space_type> js_double_quoted_str; 
    qi::rule<Iterator, ascii::space_type> js_empty_str; 
    qi::rule<Iterator, ascii::space_type> js_array; 
    qi::rule<Iterator, ascii::space_type> js_num; 
    qi::rule<Iterator, ascii::space_type> js_null; 
    qi::rule<Iterator, ascii::space_type> js_bool; 
}; 

int main() 
{ 
    std::string inputStr; 
    json_grammar<std::string::const_iterator> jsonParser; 
    bool parseOK = false; 

    while(std::getline(std::cin, inputStr)) { 
     if(inputStr.empty() || inputStr[0] == 'q' || inputStr[0] == 'Q') 
      break; 

     std::string::const_iterator iter = inputStr.begin(); 
     std::string::const_iterator iterEnd = inputStr.end(); 

     parseOK = qi::phrase_parse(iter, iterEnd, jsonParser, ascii::space); 

     if(parseOK && iter == iterEnd) { 
      std::cout << "Successfully parsed the input as JSON!" << std::endl; 
     } else { 
      std::cout << "Cannot parse the input as JSON!" << std::endl; 
     } 
    } 

    return 0; 
} 
+0

あなたはjson spirit(たとえばhttps://launchpad.net/ubuntu/+source/json-spirit/4.04-1)を認識していますか? – sehe

+0

ありがとうございました。私はバージョン2.4.2(最新のものと最高のもの)を使用していますが、古典的なスピリットを使用しています。重要な違いがある、IMHO。さらに、コードは私のような精神の初心者にとっては複雑すぎる。ポインタありがとうございました。 – Viet

+1

コンパイラがC++ 0xをサポートしている場合は、AXXパーサジェネレータを見て、JSONの解析を単純化することはできません。実際には、バージョン1.0.10.99にJSONパーサの例があります。 –

答えて

3

その他のアップデート:

のKostyaは良い点を持っていると '半分' のベースに触れる:ちょうど別のプレースホルダを使用し、boost::bindが実際に罰金です:

[ boost::bind(&print_char, ::_1) ] 
[ phoenix::bind(&print_char, qi::_1) ] 
[ print_char ] 

すべての3つは動作しますが、べきではありません混在:)

+0

実際には[boost :: bind(&print_char、:: _ 1)] 'であり、' _1'はグローバル名前空間にあります。 – hkaiser

+0

固定、tyvm Hartmut(私は多少疑問がありました。私はそこに何か変わったことがあることを知っていました::バインド - 私は覚えています。 – sehe

+0

そうです、私は同じ結論に達しました。 @hkaiserにも感謝します。 – Viet

1

と思われます。boost::bindは精神とあまりよく使用されません。代わりにphoenixを使用することが推奨されたことを覚えています。私は考慮してラインを交換しました:

char_('{') [std::cout << boost::phoenix::arg_names::arg1] 

コンパイルします。それが実際に動作するかどうかを確認する時間がありません。

関連する問題