我想解析文本文件中的 float 并将其插入符号表中;解析器和符号表由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()>
请注意括号,以使 double 成为仿函数声明而不是普通 double ,以进行惰性求值。
接下来,您需要将上面的语法用于您的语义操作。
[ boost::phoenix::bind(floatDecs.add, boost::phoenix::val(some), _1) ];
老实说,我不确定为什么这会起作用,因为我不是凤凰专家,但上面“sehe”评论中的链接提供了答案。另外,您使用 cref
吠叫了错误的树,add()
的声明没有表明需要引用。 val
是将 some
变量转换为 phoenix-happy 惰性参数所需的。
最后,您只需要提供一些合理的测试数据即可。
上面的代码现在应该适合您了。
关于c++ - 使用 boost::phoenix::bind 和 boost::spirit::qi::symbols::add,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14310152/