2

我正在尝试创建一个简单的解析器,它使用boost::spirit::x3. 问题是它x3::char_('#') | x3::char_('.')似乎有一个 type 的属性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那么它可以转换为 a char,但不能转换为|.

我在 boost 版本 1.63.0 和 Linux 上。该代码无法在 g++ 和 clang++ 上使用-std=c++14.

我究竟做错了什么?

#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';
}
4

2 回答 2

1

你是对的,它应该是compatible,事实上它已经是:

auto const& attr = x3::_attr(ctx);
char c;
x3::traits::move_to(attr, c);

Spirit 的属性兼容规则(加上定制点)是承载这种语义的载体。

我同意你的观点,如果属性类型可以简化为char直接,这可能是一个很好的可用性改进,但我认为这会在未来产生更深远的影响。

于 2017-02-10T13:25:04.680 回答
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);
于 2017-02-15T22:20:49.897 回答