2011-11-04 1 views
3

시끄러운 입력을 구문 분석하려고하는데, 절이 규칙과 일치하는지, 그리고 내가 필요한 데이터를 얻었고 나머지는 버려야하는지 알 수 있습니다.부스트 영혼 문법이 시끄러운 입력과 일치합니다.

원하는 데이터는 다음과 같습니다.

Event: Newstate 
Channel: SIP/104-000001bb 
ChannelState: 6 
ChannelStateDesc: Up 

새로운 상태의 이벤트 인 if를 확인하고 싶습니다.

그리고 채널 상태가 필요합니다. 나머지는 내가 신경 쓰지 않아도되므로 무시하고 싶다. 나는 유연하고 오래 가지 못하는 것을 받아 들여야한다. 중요한 것은이 줄을 무시하고 싶지는 않지만 무시하는 것이다. 이벤트와 채널 상태의 끝 사이의 모든 것. 값을 캡처합니다.

vect v; 
bool r=qi::parse(it, str.end(), rule_, v); 

편집 : 부스트 버전 1.42 컴파일러 나는이 작업을 수행 할 때, 나는 항상 false를 다시 얻을

typedef boost::fusion::vector2<std::string, std::string> vect; 
qi::rule<std::string::iterator, vect(), space> rule_ = 
      lit("Event: ")  >> *char_("a-zA-Z") >> 
      qi::omit[ *char_ ] >> 
      "ChannelState: " >> *char_("0-9") >> 
      qi::omit[ *char_ ]; 

하지만 어떤 이유로 작동하지 않습니다 :

은 지금까지 나는 가지고있다 g ++ 4.4 Spirit 0x2020

답변

6

기억하십시오 : Spirit의 파서는 욕심이 있습니다. 즉, qi::omit[ <something> ]을 수행하면 <something>이 더 이상 충족되지 않을 때까지 문자가 생략됩니다. <something>은 문자 그대로 이므로 문자는 (char_은 모든 문자와 일치하므로 *char_은 모든 문자와 일치 함) 전체 문자열을 먹습니다. 그러면 "ChannelState :"에 도달하지 못하므로 오류가 발생합니다.

귀하의 방식대로 작동하지 않습니다. *char_이 모든 것을 먹는 것을 막기 위해서는 차단 스위치가 있어야합니다.

왜 조각화하지 않고 모두 std::map으로 구문 분석하지 않는지 알 수 없습니다. 그런 다음 원하는 요소를 골라 낼 수 있습니다. 당신은 당신이 아직 몇 가지 요소를 원하지 않는다고 말하면, 그냥 무시하십시오. 이 부스트 1.47에서 작동

//Includes 
#include <boost/spirit/include/qi.hpp> 
#include <boost/fusion/adapted/std_pair.hpp> 

//Code 
using namespace boost::spirit; 
using ascii::char_; 
using ascii::string; 

qi::rule<std::string::iterator, std::pair<std::string, std::string>() > pair_rule = 
    *(char_ - ':') >> ':' >> 
    qi::omit[*ascii::space] >> 
    *(char_ - eol) >> (eol || eoi); 

qi::rule<std::string::iterator, std::map<std::string, std::string>() > map_rule = 
    +pair_rule; 

std::map<std::string, std::string> v; 
bool r = qi::parse(test.begin(), test.end(), map_rule, v); 

참고 : 다음과 같이

이 완료 될 것이다. 나는 그것이 이전 버전에서 실패 할 것이라고 의심 할 것이다.

부스트 버전 1.42 컴파일러 g ++ 4.4 성령은 0x2020

사람들은 오히려 나이. 업그레이드를 고려해야합니다. 부스트는 현재 1.47입니다.

+0

답장을 보내 주셔서 감사합니다. 나는 내일 일할 때 다시 소용돌이 칠할 것입니다. 나는 그 버전이 오래된 것을 알고 있지만, 나는 영원히 과거에 살고있는 현재의 debian 버전 (squeeze)에서 컴파일되도록해야한다 : ( – 111111

+0

@ 111111 :'std :: pair'와'std :: map' stuff가 이전 버전에서 작동하지 않는다면 항상 두 개의'std :: string'을 담는 구조체의'std :: vector'를 저장하기 위해 속성을 변경할 수 있습니다. –

+0

그래, 어쨌든, 가장 드물게 더 많은 요소가 15 개가 될 것이므로 std :: map의 오버 헤드가 낭비 적이라고 생각했을 것입니다. – 111111

관련 문제