2014-10-16 53 views
1

我正在學習使用boost :: spirit庫。我拿這個例子http://www.boost.org/doc/libs/1_56_0/libs/spirit/example/qi/num_list1.cpp,並在我的電腦上編譯它 - 它工作正常。未定義的行爲在boost :: spirit :: qi :: phrase_parse中的某處

但是如果我修改了一點 - 如果我初始化解析器本身

auto parser = qi::double_ >> *(',' >> qi::double_); 

地方作爲全局變量,並通過它來phrase_parse,一切都瘋了。下面是完整的修改後的代碼(只有1行修改,加1) - http://pastebin.com/5rWS3pMt

如果我運行的原代碼,並通過「3.14 3.15」,以標準輸入,它說,解析成功,但我的修改後的版本失敗。我嘗試了很多相同類型的修改 - 將分析器分配給全局變量 - 在某些編譯器中的某些變體上它會出現段錯誤。

我不明白爲什麼以及它是如何。 這裏是另一個,更簡單的版本,它打印正確,然後出現segfaults上鐺++,只是出現segfaults在G ++

#include <boost/spirit/include/qi.hpp> 

#include <iostream> 
#include <string> 

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

const auto doubles_parser_global = qi::double_ >> *(',' >> qi::double_); 

int main() { 
    const auto doubles_parser_local = qi::double_ >> *(',' >> qi::double_); 

    const std::string nums {"3.14, 3.15, 3.1415926"}; 

    std::cout << std::boolalpha; 

    std::cout 
     << qi::phrase_parse(
      nums.cbegin(), nums.cend(), doubles_parser_local, ascii::space 
     ) 
     << std::endl;        // works fine 

    std::cout 
     << qi::phrase_parse(
      nums.cbegin(), nums.cend(), doubles_parser_global, ascii::space 
     )           // this segfaults 
     << std::endl; 
} 

回答

2

不能使用auto解析器expressions¹

要麼你需要從臨時表達式計算直接,或需要分配到規則/語法:

const qi::rule<std::string::const_iterator, qi::space_type> doubles_parser_local = qi::double_ >> *(',' >> qi::double_); 

你可以有你的蛋糕,吃它也對最近的升壓VERSI附件(可能是Dev分支)應該有宏觀

這已成爲一個有點FAQ項的BOOST_SPIRIT_AUTO:

¹我認爲這實際上是底層Proto庫的限制。在github上有一個Proto-0x lib版本(由Eric Niebler提供),它承諾通過完全重新設計來解決這些問題,以瞭解引用。我認爲這需要Boost Proto目前無法使用的一些C++ 11功能。

相關問題