【发布时间】:2018-10-15 10:25:12
【问题描述】:
以下代码编译时出错:
/usr/include/boost/spirit/home/qi/detail/assign_to.hpp:153:20: error: no matching conversion for static_cast from 'const char' to 'boost::fusion::vector<char,
std::vector<double, std::allocator<double> > >'
attr = static_cast<Attribute>(val);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
我不知道为什么,因为更改为 auto grammar = boost::spirit::no_skip[drawto_commands]; 后它按预期工作。
moveto 和 lineto 解析的类型相同。
Qi 运算符 >> 具有类型规则 a: A, b: vector<A> --> (a >> b): vector<A>,这应该使 drawto_commands 和 moveto_drawto_command_group 解析的类型相同。
我错过了什么?
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
typedef boost::fusion::vector<char, std::vector<double>> Arc;
template <typename P, typename T>
bool test_phrase_parser_attr(const std::string &string, P const& grammar, T& attr, bool full_match = true)
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::ascii::space;
auto f = string.begin();
auto l = string.end();
bool match = phrase_parse(f, l, grammar, space, attr);
return match && (!full_match || (f == l));
}
int main()
{
using boost::spirit::omit;
using boost::spirit::qi::ascii::char_;
using boost::spirit::qi::ascii::space;
using boost::spirit::qi::attr;
using boost::spirit::qi::double_;
using boost::spirit::qi::copy;
auto wsp = copy(omit[boost::spirit::ascii::space]);
auto comma_wsp = copy(omit[(char_(',') >> *wsp) | (+wsp >> -char_(',') >> *wsp)]);
auto coordinate = copy(double_);
auto coordinate_pair = copy(coordinate >> -comma_wsp >> coordinate);
auto closepath = copy(char_("Zz") >> attr(std::vector<double>()));
auto vertical_lineto = copy(char_("Vv") >> *wsp >> (coordinate % -comma_wsp));
auto lineto = copy(char_("Ll") >> *wsp >> (coordinate_pair % -comma_wsp));
auto moveto = copy(char_("Mm") >> *wsp >> (coordinate_pair % -comma_wsp));
auto drawto_command = copy(closepath | vertical_lineto | lineto);
auto drawto_commands = copy(*(*wsp >> drawto_command >> *wsp));
auto moveto_drawto_command_group = copy(moveto >> drawto_commands);
auto grammar = boost::spirit::no_skip[moveto_drawto_command_group];
std::vector<Arc> attribute;
std::string str;
std::cout << "*\n";
while (getline(std::cin, str))
{
if (str.empty())
break;
attribute = {};
bool r = test_phrase_parser_attr(str, grammar, attribute, true);
if (r)
{
std::cout << "Parsing succeeded, got: " << std::endl;
for (auto &command: attribute){
char line_type = boost::fusion::at_c<0>(command);
std::cout << line_type;
const std::vector<double> arguments = boost::fusion::at_c<1>(command);
for (size_t i = 0; i < arguments.size(); ++i)
{
std::cout << ' ' << arguments[i];
}
std::cout << std::endl;
}
}
else
{
std::cout << "Parsing failed\n";
}
}
}
`
【问题讨论】:
-
你想解析什么?你有例子吗?我想你可能正在实施§ 9.3.9. The grammar for path data
标签: c++ parsing boost boost-spirit-qi