【发布时间】:2014-02-02 14:31:47
【问题描述】:
我正在尝试将字符串解析为自定义类型symbol 的属性,其中包含std::string 成员。我以为我可以在这里使用BOOST_FUSION_ADAPT_STRUCT,但这不起作用。
如果我将规则声明为rule<It, std::string(), space_type>,它会起作用。如果我将它定义为rule<It, symbol(), space_type>,它会失败并显示错误“symbol 中没有类型名称value_type”。我认为 Spirit 正在尝试将值字符逐字符附加到属性,但按预期失败。但是有没有办法让这项工作不添加一个额外的中间规则来捕获std::string 属性?
这是完整的 MWE:
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
struct symbol
{
std::string repr;
};
BOOST_FUSION_ADAPT_STRUCT(symbol, (std::string, repr))
namespace qi = boost::spirit::qi;
template <typename Iterator>
struct test_grammar : qi::grammar<Iterator, symbol(), qi::ascii::space_type> {
test_grammar() : test_grammar::base_type{start} {
start = qi::lexeme[+qi::char_("a-z")];
}
qi::rule<Iterator, symbol(), qi::ascii::space_type> start;
};
#include <iostream>
auto main() -> int {
test_grammar<std::string::iterator> grammar{};
auto input = std::string{"test"};
auto output = symbol{};
auto e = end(input);
if (qi::phrase_parse(begin(input), e, grammar, qi::ascii::space, output))
std::cout << output.repr;
}
【问题讨论】:
-
这是 Spirit 中的一个已知限制/错误。我相信当您调整具有单个元素并且该元素是“容器”的结构时会发生这种情况。通常的解决方法是
start %= eps >> lexeme[+char_('a', 'z')];,显然这会强制右侧的属性为tuple<std::string>,并且适用于您调整的结构。我会尝试找到一个重复的。 -
@cv_and_he 是的,works 使用该解决方法
-
@cv_and_he 请将其复制到答案中,以便我接受。
-
@sehe 你的“修复”是狡猾的。为什么要删除
string包含?!为什么要重新排序标题? (事实上,现在我看它,为什么任何这些变化?) -
如果您不感兴趣,请回滚。其中我也将避免花更多时间回答...?
标签: c++ boost-spirit boost-fusion