c++ - 为什么我不能解析这个double_?

标签 c++ boost-spirit boost-spirit-qi

当我将输入解析为 std::string 时,我得到了字符串,但是当我将其解析为 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()

最佳答案

你错过了属性中的 ():

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

应该是

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

因为 qi::rule 中的参数顺序可以是任意的(Iterator 除外),lib 在内部使用一些特征来识别哪个是 attr,哪个是 skipper,...等等。 attr字段必须是function-sig的形式,即synthesized(inherited),如果你写double,它不会被识别为attr,所以您的 timestamp 规则实际上将 unused_type 而不是 double 作为其属性,这意味着 record.timestamp 不会t 由解析器填充,它未初始化。

关于c++ - 为什么我不能解析这个double_?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26791314/

相关文章:

c++ - 使用模板链接错误

c++ - Boost Spirit 和 Lex 解析器问题

c++ - 使用 boost::phoenix::bind 和 boost::spirit::qi::symbols::add

c++ - 使用 sscanf 解析字符串好吗

c++ - Windows中的虚拟地址空间

c++ - Boost Spirit Qi 验证输入解析器

c++ - Boost::spirit 从非终结符获取值(value)

boost - 在 boost::spirit 语法中翻转规则内的子规则顺序会导致段错误

c++ - 如何解析后跟分号或换行符的条目(boost::spirit)?

c++ - Qt progressBar 获取未处理的异常如何检测父小部件何时完成加载