我正在尝试将字符串解析为自定义类型symbol
的属性,该属性包含std::string
成员。我以为我可以在这里使用BOOST_FUSION_ADAPT_STRUCT
,但这不起作用。
如果我将规则声明为rule<It, std::string(), space_type>
则可行。如果我将其定义为rule<It, symbol(), space_type>
,则会失败并显示错误“value_type
中没有类型名称symbol
”。我认为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;
}
答案 0 :(得分:2)
正如你从链接的欺骗中看到的那样,你可以通过一个位置很好的qi::eps
来解决这个问题。
start = qi::eps >> qi::lexeme[+qi::char_("a-z")];
但是,有些情况qi::eps
无法保存。 (稍后会尝试查找链接)。因此,我开始支持属性兼容性的“老式方法”:
#include <boost/spirit/include/qi.hpp>
struct symbol
{
std::string repr;
symbol(std::string repr = std::string()) : repr(std::move(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) {
using namespace qi;
start = as_string[ lexeme[ +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;
}
这在编译器上也可能稍微轻一点。同时查看 Live on Coliru 。
如果所有其他方法都失败了,你可以吃蛋糕并吃掉它,因为属性转换/分配是库中的自定义点。