使用boost::phoenix::bind结合boost::spirit::qi::symbols::add

Using boost::phoenix::bind together with boost::spirit::qi::symbols::add

本文关键字:boost qi symbols add spirit bind phoenix 使用 结合      更新时间:2023-10-16

我想解析文本文件中的浮点数,并将其插入符号表中;解析器和符号表由spirit::qi.

提供。下面是我的代码:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <stdint.h>
#include <iostream>
#include <string>
template<typename VTYPE>
struct VTable : boost::spirit::qi::symbols<char, VTYPE> {
    VTable() {} // empty
};
int main() {
using boost::spirit::qi::_1;
using boost::spirit::qi::eps;
using boost::spirit::qi::rule;
using boost::spirit::qi::ascii::space;
using boost::spirit::qi::space_type;
using boost::spirit::qi::real_parser;
using boost::spirit::qi::int_parser;
using boost::spirit::qi::strict_real_policies;
    VTable<double> floatDecs;
    floatDecs.add("hallo", 15.26)("duDa", 18.5);
const std::string some = "some";
    rule<std::string::iterator, double> value = real_parser<double, strict_real_policies<double>>() [ boost::phoenix::bind(&VTable<double>::add, floatDecs, boost::phoenix::cref(some), _1) ];
    std::cout << boost::spirit::qi::phrase_parse(test.begin(), test.end(), value, space);
    return 0;
}

这里的问题在于boost::phoenix::bind,但我不知道如何解决这个问题(我对这个库相当陌生)。

这是一个工作版本。之后,我会列出你的问题。

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <stdint.h>
#include <iostream>
#include <string>
template<typename VTYPE>
struct VTable : boost::spirit::qi::symbols<char, VTYPE> {
    VTable() {} // empty
};
int main() {
using boost::spirit::qi::_1;
using boost::spirit::qi::eps;
using boost::spirit::qi::rule;
using boost::spirit::qi::ascii::space;
using boost::spirit::qi::space_type;
using boost::spirit::qi::real_parser;
using boost::spirit::qi::int_parser;
using boost::spirit::qi::strict_real_policies;
    VTable<double> floatDecs;
    floatDecs.add("hallo", 15.26)("duDa", 18.5);
    const char some[] = "some";
    rule<std::string::iterator, double()> value =
            real_parser<double, strict_real_policies<double> >()
            [ boost::phoenix::bind(floatDecs.add, boost::phoenix::val(some), _1) ];
    std::string test("10.6");
    std::string::iterator b(test.begin()), e(test.end());
    std::cout << boost::spirit::qi::phrase_parse(b, e, value, space);
    return 0;
}

首先,需要固定要用作add()参数的变量。

const char some[] = "some";
接下来,您需要在规则模板参数中修改语法:
rule<std::string::iterator, double()>

请注意括号,为了使双精度型声明为函数函数而不是普通的双精度型,用于延迟求值。

接下来,您需要为您的语义操作使用上面的语法。

[ boost::phoenix::bind(floatDecs.add, boost::phoenix::val(some), _1) ];

老实说,我不知道为什么这个工作,因为我不是一个凤凰专家,但上面的"她"评论中的链接提供了答案。此外,您对cref进行了错误的搜索,从add()的声明中没有迹象表明需要引用。val是您需要将some变量转换为凤凰快乐的懒惰参数。

最后,您只需要提供一些合理的测试数据。

上面的代码现在应该可以工作了