我正在尝试使用boost::spirit::x3
创建一个简单的解析器,它使用两个可能的字符之一。问题是x3::char_('#') | x3::char_('.')
似乎有boost::variant<char, ?>
类型的属性。这意味着我必须在boost::get<char>
上使用_attr
,而应该可以直接转换为char
。
http://ciere.com/cppnow15/x3_docs/spirit/quick_reference/compound_attribute_rules.html,它说A | A -> A
如果使用已注释的mapChars
版本,那么它可以转换为char
,但不能转换为|
。
我在升级版本1.63.0和Linux上。代码无法使用-std=c++14
在g ++和clang ++上进行编译。
我做错了什么?
#include <iostream>
#include <string>
#include <boost/spirit/home/x3.hpp>
int main() {
std::string s("#");
namespace x3 = boost::spirit::x3;
auto f = [](auto & ctx) {
auto & attr = x3::_attr(ctx);
//char c = attr; // doesn't work
char c = boost::get<char>(attr); // does work
};
auto mapChar = x3::char_('#') | x3::char_('.'); // _attr not convertible to char, is a variant
//auto mapChar = x3::char_('#'); // _attr convertible to char, isn't a variant
auto p = mapChar[f];
auto b = s.begin();
bool success = x3::parse(b, s.end(), p);
std::cout << "Success: " << success << ' ' << (b == s.end()) << '\n';
}
答案 0 :(得分:1)
你是对的,应该兼容,实际上它已经是:
auto const& attr = x3::_attr(ctx);
char c;
x3::traits::move_to(attr, c);
Spirit的属性兼容性规则(加上自定义点)是携带此类语义的工具。
我同意你的看法,如果属性类型可以直接简化为char
,那么这可能是一个很好的可用性改进,但我认为这会产生进一步的影响。
答案 1 :(得分:0)
如果您的语义操作按值获取属性,则它应该起作用:
char result = 0;
auto f = [&result](char c){ result = c; };
auto mapChar = x3::char_('#') | x3::char_('.');
auto p = mapChar[f];
auto b = s.begin();
bool success = x3::parse(b, s.end(), p);