2016-01-15 53 views
2

我試圖用boost::spirit::qi::symbols解析枚舉值。我的代碼如下:使用boost ::精神::齊::符號

#include <boost/spirit/include/qi.hpp> 
#include <string> 
#include <iostream> 

using namespace std; 
namespace qi = boost::spirit::qi; 

enum class Foo { None, Bar = 42, Baz = 43 }; 

struct FooValues: qi::symbols<char, Foo> 
{ 
    FooValues() { add("Bar", Foo::Bar)("Baz", Foo::Baz); } 
}; 

int main() 
{ 
    typedef std::string::iterator Iterator; 
    typedef qi::space_type Skipper; 
    using qi::rule; 

    rule<Iterator, Foo(), Skipper> foo = qi::lit("Foo") >> '.' >> FooValues(); 
    rule<Iterator, Foo(), Skipper> root = foo | ('\"' >> foo >> '\"'); 

    std::string input = "Foo.Bar"; 
    Foo output; 
    if (qi::phrase_parse(input.begin(), input.end(), root, Skipper(), output)) 
     cout << "output: " << static_cast<int>(output) << endl; 
    else 
     cout << "failed" << endl; 
} 

但是,它解析輸入失敗。如果我更換了由它的工作原理如下解析枚舉值的規則。

rule<Iterator, Foo(), Skipper> foo = qi::lit("Foo") >> '.' >> 
    ((qi::lit("Bar") >> qi::attr(Foo::Bar)) | (qi::lit("Baz") >> qi::attr(Foo::Baz))); 

我在做什麼錯?我寧願使用qi::symbols解析器,因爲這將讓我在一個循環中添加值,而不是手工編寫他們入規則。

通過類似下面的作品的局部變量的更換FooValues()暫時的,但我寧願如果沒有必要不要徒增變數。那可能嗎?

FooValues fooValues; 
rule<Iterator, Foo(), Skipper> foo = qi::lit("Foo") >> '.' >> fooValues; 

回答

2

精神規則參照保持其成分,所以你必須確保引用成分留在範圍,而被引用它不會破壞。看代碼

rule<Iterator, Foo(), Skipper> foo = qi::lit("Foo") >> '.' >> FooValues(); 

FooValues的實例在使用規則之前超出範圍。你可以這樣修復它

FooValues values; 
rule<Iterator, Foo(), Skipper> foo = qi::lit("Foo") >> '.' >> values; 
+0

我看到臨時是一個問題。但是我不知道'qi :: lit'是如何工作的?它看起來也是暫時的。 –