2011-07-01 87 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

謝謝sehe。它使用經典的精神,而我使用的版本2.4.2(最新和最偉大的)。有顯着差異,恕我直言。而且,對於像我這樣的Spirit初學者來說,代碼太複雜了。謝謝你的指針。 – Viet

+1

如果您的編譯器支持C++ 0x,請查看AX分析器生成器,解析JSON不會更簡單。實際上它有一個版本爲1.0.10.99的JSON解析器。 –

回答

3

更多更新:

克斯特亞好點和「半壁江山」倒是基地:boost::bind其實很好,只是使用不同的佔位符:

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

所有這三個應該工作,但不混合:)

+0

它實際上是'[boost :: bind(&print_char,:: _ 1)]',並且是'_1'在全局命名空間中。 – hkaiser

+0

修正了tyvm Hartmut(我有點疑問;我知道boost :: bind有一些奇怪的地方 - 我記得現在我很驚訝前段時間在那裏得到虛假的模糊標識符)。 – sehe

+0

對,我得出了同樣的結論,@sehe。也感謝@hkaiser。 – Viet

1

似乎boost::bind是不是很好用的精神。我記得建議使用phoenix代替。我已考慮替換該行:

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

它編譯。沒有時間檢查它是否真的有效。

相關問題