2013-08-16 54 views
3

當我嘗試解析簡單帶引號的字符串時遇到了一些奇怪的事情。 所以我寫了這個簡單的解析器,可以成功解析帶引號的字符串,如"string"""解析帶引號的字符串只適用於某些情況

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

namespace qi  = boost::spirit::qi; 
namespace iso8859 = boost::spirit::iso8859_1; 


int main(int argc, char* argv[]) 
{ 
    using namespace qi; 

    std::string input = "\"\""; 

    std::string::const_iterator front = input.cbegin(); 
    std::string::const_iterator end = input.cend(); 
    bool parseSuccess = phrase_parse(front, end, 
             '\"' >> *~char_('\"') >> '\"', 
             iso8859::space); 

    if (front != end) 
    { 
     std::string trail(front, end); 
     std::cout << "String parsing trail: " << trail << std::endl; 
    } 

    if (!parseSuccess) 
     std::cout << "Error parsing input string" << std::endl; 

    std::cout << "Press enter to exit" << std::endl; 
    std::cin.get(); 
    return 0; 
} 

這一切工作完全正常,但是當我伸出的解析規則的引號的字符串之前也分析的東西,它突然打破..

因此,例如,這種成功解析:

std::string input = "normalString 10.0 1.5 1.0 1.0 1.0 1.0" 隨着解析規則:

*char_ >> *double_

現在,如果我結合這個規則與引號的字符串規則:

std::string input = "normalString 10.0 1.5 1.0 1.0 1.0 1.0 \"quotedString\""

隨着解析規則:

*char_ >> *double_ >> '\"' >> *~char_('\"') >> '\"'

它突然不工作了,和解析失敗。我不知道爲什麼。任何人都可以解釋嗎?

編輯:萬一它很重要,我使用Boost 1.53

回答

2

由於cv_and_he前面提到的 - 你*char_吃的一切,從「更新」解析器序列可以推測它爲什麼沒有工作:-)

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

namespace qi  = boost::spirit::qi; 
namespace iso8859 = boost::spirit::iso8859_1; 

int main(int argc, char* argv[]) 
{ 
    using namespace qi; 

    std::vector<std::string> inputVec{ 
     "normalString 10.0 1.5 1.0 1.0 1.0 1.0 \"quotedString\"", 
     "normalString \"quotedString\"", 
     "10.0 1.5 1.0 1.0 1.0 1.0 \"quotedString\"", 
     "10.0 1.5 1.0 1.0 1.0 1.0 \"\"", 
     "\"\""}; 

    for(const auto &input : inputVec) 
    { 
     std::string::const_iterator front = input.cbegin(); 
     std::string::const_iterator end = input.cend(); 
     bool parseSuccess = phrase_parse(front, end, 
      no_skip [ *(char_ - space - double_ - '\"') ] 
      >> *double_ >> '\"' >> *~char_('\"') >> '\"', 
      iso8859::space);  
     if (parseSuccess && front == end) 
      std::cout << "success:"; 
     else 
      std::cout << "failure:"; 
     std::cout << "`" << input << "`" << std::endl; 
    } 
    return 0; 
} 
+2

[這裏](http://coliru.stacked-crooked.com/view?id=837d43cf612b8f47a3a05698056ffc5c-e7fd08290543cba3074dbc20a​​85c5c10)是使用BOOST_SPIRIT_DEBUG問題中提到的兩種情況。你可以清楚地看到'* char_'消耗整個字符串。在第一種情況下,'* double_'由一個空屬性結束,因爲它匹配0個雙打。在第二種情況下,一切工作都一樣,直到文字「'」失敗。 – llonesmiz

+0

假設你想要解析的字符串是一個標準的標識符,我認爲解決這個問題的最簡潔的方法是:'lexeme [alpha >> * alnum] >> * double_ >>'''>> *〜char_(''')>>''';'。如果您使用的規則如上面鏈接的示例中所示,如果您從規則中刪除隊長,甚至可以省略'lexeme':rule string_rule = alpha >> * alnum;'。 – llonesmiz

+0

@cv_and_he - 至於添加額外的規則 - 完全同意。我認爲這兩種方式都很好。 –

相關問題