2015-09-28 51 views
2

我試圖解析單獨的形式「A + C」或「A」的附加表達式。一些測試後,我意識到,這個問題顯然是我使用可選的解析器,所以爲了舉例:在靈氣中使用可選的解析器qi

qi::rule<string::iterator, string()> Test; 

Test = 
(
    qi::string("A")[qi::_val= qi::_1] 
    >> -(
      qi::string("B")[qi::_val += qi::_1] 
      >> qi::string("C")[qi::_val += qi::_1] 
     ) 
) 
; 

string s1, s2; 
s1 = "AB"; 
bool a= qi::parse(s1.begin(), s1.end(), Test, s2); 

的想法是解析「A」或「ABC」,但如果S1值是「AB 「沒有'C',a的值是真的。我相信儘管我在運算符' - '之後放了括號,然後我使用了「>>」運算符,但'C'部分被認爲是可選的,而不是整個B >> C.有任何想法嗎?

回答

2

容器屬性不回溯。

這是一個性能選擇。您需要使用例如顯式控制傳播。 qi::hold

Live On Coliru

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

namespace qi = boost::spirit::qi; 

int main() { 
    using It = std::string::const_iterator; 
    qi::rule<It, std::string()> Test; 

    Test = 
     (
     qi::char_('A') 
     >> -qi::hold [ 
       qi::char_('B') 
      >> qi::char_('C') 
     ] 
     ) 
     ; 

    for (std::string const input : { "A", "AB", "ABC" }) 
    { 
     std::cout << "-------------------------\nTesting '" << input << "'\n"; 
     It f = input.begin(), l = input.end(); 

     std::string parsed; 
     bool ok = qi::parse(f, l, Test, parsed); 
     if (ok) 
      std::cout << "Parsed success: " << parsed << "\n"; 
     else 
      std::cout << "Parsed failed\n"; 

     if (f != l) 
      std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n"; 
    } 
} 

打印:

------------------------- 
Testing 'A' 
Parsed success: A 
------------------------- 
Testing 'AB' 
Parsed success: A 
Remaining unparsed: 'B' 
------------------------- 
Testing 'ABC' 
Parsed success: ABC 

注意我已經做了一些簡化。

參見: