2017-02-10 6 views
2

boost::spirit::x3を使用して2つの可能な文字のうちの1つを取る簡単なパーサーを作成しようとしています。問題は、x3::char_('#') | x3::char_('.')の属性がboost::variant<char, ?>であるようです。つまり、私はboost::get<char>_attrに使用する必要がありますが、それは直接charに変換する必要があります。boost spirit x3(A | A)の属性タイプは、Aの代わりに<A, ?>です

http://ciere.com/cppnow15/x3_docs/spirit/quick_reference/compound_attribute_rules.html、それはmapCharsのコメントアウトバージョンが使用されている場合、それは|charに変換可能だが、ないA | A -> A

を言います。

私はブーストバージョン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-> variant 'の問題を解決しません。 – llonesmiz

+0

このサンプルでは、​​これは非常に相当のものです – sehe

答えて

1

あなたは正しい、それは互換であるべきであり、実際にそれが既にある:

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

スピリットの属性互換性規則(プラスカスタマイズポイント)は、そのような意味を運ぶための車両です。

アトリビュートタイプをcharに簡略化することができれば便利だと私は同意しますが、これはさらに深刻な結果につながります。

+0

私はこれを試みましたが、基本的に同じエラー( '互換性のない型からのcharへの代入... >)を与えています。この場合、 'x3 :: traits :: move_to'は単に何も変更しない' dest = std :: move(src); 'を実行しているようです。 – aeubanks

+2

@aeubanks Mmm。あなたは大丈夫です。私は間違ったことをしたに違いない。一方、ルールの強制([demo](http://coliru.stacked-crooked.com/a/a7f8df9f67ac3a7b))を使うと、より便利になる[ヘルパー機能付き](http://stackoverflow.com/質問/ 33816662 /理解 - リスト - オペレーター - イン - ブースト - スピリット/ 33817135#33817135):http://coliru.stacked-crooked.com/a/1f5788a7eeaf872b – sehe

+0

これが改善のために議論されるべきであると感じたら開発者に[spirit-general]メーリングリストで連絡する – 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); 
関連する問題