2013-08-16 3 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; 
} 

이 모두 완벽하게 잘 작동하지만 나 또한 인용 된 문자열 전에 일을 구문 분석 구문 분석 규칙을 확장 할 때, 갑자기 고장 ..

따라서, 예를의이 성공적으로 구문 분석 :

*char_ >> *double_

: 구문 분석 규칙과

std::string input = "normalString 10.0 1.5 1.0 1.0 1.0 1.0" 그리고이 인용 된 문자열의 규칙과이 규칙을 결합 지금 경우 :

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

구문 분석 규칙 :

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

그것은 갑자기 더 이상 작동하지 않고 구문 분석에 실패합니다. 나는 이유를 모른다. 아무도 이것을 설명 할 수 있습니까?

편집 : 그것은 중요한 다만 경우에, 나는 앞서 언급 한 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-e7fd08290543cba3074dbc20a85c5c10) :-) 작업 BOOST_SPIRIT_DEBUG을 사용하여 질문 한 두 경우이다. '* char_'가 전체 문자열을 소비한다는 것을 분명히 볼 수 있습니다. 첫 번째 경우'* double_'은 0 개의 double과 매치하기 때문에 빈 속성으로 성공합니다. 두 번째 경우에서 모든 문자가 똑같이 작동합니다. – llonesmiz

+0

구문 분석하려는 문자열이 표준 식별자라고 가정하면이 문제를 해결하는 가장 깨끗한 방법은 다음과 같을 것이라고 생각합니다 :'lexeme [alpha >> * alnum] >> * double_ >> ' ">> >> ~ char_ ('" ') >>' " ';'. 위에서 링크 된 예제에서와 같이 규칙을 사용하고 있다면 규칙에서 스킵퍼를 제거하면'lexeme'도 생략 할 수 있습니다 :'rule string_rule = alpha >> * alnum;'. – llonesmiz

+0

@cv_and_he - 추가 규칙 추가시 - 완전히 동의 함. 두 가지 방법을 모두 아는 것이 좋습니다. –