2014-11-06 38 views
2

當我將輸入解析爲std :: string時,我得到了字符串,但是當我將它解析爲double_時,融合結構包含一些非常小的數字,而不是預期的數字。爲什麼我不能解析這個double_?

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

#include <string> 

// http://www.boost.org/doc/libs/1_57_0/libs/spirit/example/qi/employee.cpp 

namespace FormatConverter { 
    namespace qi = boost::spirit::qi; 
    namespace ascii = boost::spirit::ascii; 
    // TODO: should this have an initializer? 
    struct asc { 
     double timestamp; 
    }; 
} 

BOOST_FUSION_ADAPT_STRUCT(
    FormatConverter::asc, 
     (double, timestamp) 
) 

namespace FormatConverter { 

    template <typename Iterator> 
    struct asc_parser : qi::grammar< Iterator, asc(), ascii::space_type > 
    { 
     asc_parser() 
      : asc_parser::base_type(start) { 
       timestamp %= qi::double_ ; 
       start %= timestamp ; 
       ; 
     } 
     qi::rule< Iterator, double, ascii::space_type > timestamp; 
     qi::rule< Iterator, asc(), ascii::space_type > start; 
    }; 
} 

而且我有測試此:

#define BOOST_TEST_MODULE parser 
#include <boost/test/included/unit_test.hpp> 

#include "../FormatConverter/FormatConverter.h" 

#include <string> 

BOOST_AUTO_TEST_SUITE(TestSuite1) 
BOOST_AUTO_TEST_CASE(timestamp) { 
    namespace qi = boost::spirit::qi; 
    namespace ascii = boost::spirit::ascii; 
    using iterator_type = std::string::iterator; 
    using parser_type = FormatConverter::asc_parser<iterator_type>; 

    parser_type grammar; 
    FormatConverter::asc record; 

    std::string str("161.096841 "); 
    auto beg = str.begin(); 
    auto end = str.end(); 

    auto success = qi::phrase_parse(beg, end, grammar, ascii::space, record); 
    BOOST_REQUIRE(success); 
    BOOST_REQUIRE(beg==end); 

    std::cout << "timestamp: " << boost::fusion::as_vector(record) << std::endl; 
} 
BOOST_AUTO_TEST_SUITE_END() 
+0

每次,我發誓我不能正確書寫它。我知道這一點,但這一直是我輸入它的方式 – user2240431 2014-11-06 23:33:56

回答

6

你錯過了在屬性()

qi::rule< Iterator, double, ascii::space_type > timestamp; 

應該

qi::rule< Iterator, double(), ascii::space_type > timestamp; 

因爲PARAMS順序qi::rule可以是任意的(Iterator除外),lib在內部使用一些特徵來識別哪些是attr,哪些是隊長,等等。 attr字段必須採用函數sig的形式,即synthesized(inherited),如果您編寫double,則它不會被識別爲attr,因此您的timestamp規則實際上將具有unused_type而不是double作爲其屬性,解析器不會填充record.timestamp,它是未初始化的。

+1

作者決定最近支持簡單形式'T'除了'T()'[[1](https://github.com/boostorg/spirit/)提交/ e34a955f2fbbf374870dee3329f89805cd775e6c)],所以前者將在未來的版本中工作。 – Jamboree 2014-11-13 02:32:38

+0

謝謝。我已經假定()內建類型不需要。對我來說,編寫double()似乎有點違反直覺 – user2240431 2014-11-13 07:03:34

相關問題