2017-02-10 57 views
2

我試圖創建一個簡單的解析器,需要使用boost::spirit::x3兩種可能的角色之一。問題是x3::char_('#') | x3::char_('.')似乎有一個boost::variant<char, ?>類型的屬性。這意味着我必須在_attr上使用boost::get<char>,而應該直接轉換爲char提振精神X3(A | A)屬性類型是變種<A, ?>,而不是一個

http://ciere.com/cppnow15/x3_docs/spirit/quick_reference/compound_attribute_rules.html,它說:A | A -> A

如果mapChars註釋掉版本則使用它轉化爲char,但不是|

我在升壓版本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'; 
} 
+1

我想'X3 ::字符_( 「#」)'應該做你想要什麼。當然這並不能解決'A | A->變體'的問題。 – llonesmiz

+0

對於這個示例,這是非常相當的 – sehe

回答

1

你是正確的,它應該是兼容,實際上它已經是:

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

精神的屬性兼容性規則(加上定製點)攜帶這種語義的車輛。

我同意你的看法,如果直接將屬性類型簡化爲char,它可能是一個很好的可用性改進,但我認爲這會進一步影響進一步的後果。

+0

我試過,並且基本上給出了相同的錯誤('從不兼容類型...指定給字符... > ...)。看起來在這種情況下,'x3 :: traits :: move_to'只是在執行'dest = std :: move(src);'它不會改變任何東西。 – aeubanks

+2

@aeubanks嗯。你說得很對。我一定做錯了什麼。同時,你可以使用規則強制([demo](http://coliru.stacked-crooked.com/a/a7f8df9f67ac3a7b)),這會變得更加方便[帶有輔助函數](http://stackoverflow.com/ 33816662/understanding-the-list-operator-in-boost-spirit/33817135#33817135):http://coliru.stacked-crooked.com/a/1f5788a7eeaf872b – sehe

+0

如果你覺得這應該討論改進,你可以在[精神通用]郵件列表中與開發人員聯繫 – sehe

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);