【问题标题】:Using boost::phoenix::bind together with boost::spirit::qi::symbols::add使用 boost::phoenix::bind 和 boost::spirit::qi::symbols::add
【发布时间】:2013-01-14 01:09:07
【问题描述】:

我想解析文本文件中的浮点数并将其插入符号表中;解析器和符号表由 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,但我不知道如何解决这个问题(我对这个库还很陌生)。

【问题讨论】:

  • @sehe 该答案中的绑定表达式比我的要少得多:p。
  • 你真的是说 some[] 是一个数组吗?在我看来它不会编译
  • 我已经快速从 const char[] 更改为 std::string,看看是否可以更好地使用 boost。我只是不够小心

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


【解决方案1】:

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

#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) ];

老实说,由于我不是凤凰专家,所以我不确定为什么会这样,但上面“sehe”评论中的链接提供了答案。另外,你用cref 叫错了树,add() 的声明中没有任何迹象表明需要引用。 val 是将 some 变量转换为 phoenix-happy 惰性参数所需要的。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多