2016-11-01 1 views
2

저는 Boost.Qi 초보자입니다. 그래서 간단한 예제를 사용하여 주위를 둘러 보려고 노력하고 있습니다. 다음과 같은 문자열을 파싱하려고합니다.선택 파서가있는 Boost.Qi 컴파일러 오류

A:1  B:2   C:3 

문자열의 각 구성 요소 사이에 임의의 양의 공백이 있습니다. A: 부분 등이 고정되어 있으며 정수 값을 파싱하고 싶습니다. 위의 예에서 문자열의 세 번째 구성 요소 인 C:3은 선택 사항입니다. 나는이 응용 프로그램에 대한 Boost.Qi을 테스트하기 위해 다음과 같은 간단한 예를 내놓았다 :

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

namespace qi = boost::spirit::qi; 

int main() 
{ 
    std::string s = "A:1 B:2   C:3"; 

    int a, b; 
    boost::optional<int> c; 

    if (!qi::parse(s.begin(), s.end(), 
     qi::lit("A:") >> qi::int_ >> +qi::space >> "B:" >> qi::int_ >> 
      -(+qi::space >> "C:" >> qi::int_), a, b, c)) 
    { 
     std::cout << "failed to parse" << std::endl; 
    } 

    std::cout << a << ' ' << b << ' ' << c.value_or(-1) << std::endl; 
} 

그러나,이 (부스트 v1.58와 g ++ 5.4.0 C++ (11) 모드에서 사용) 컴파일에 실패.

spirit.cc:15:55: required from here 
/usr/include/boost/spirit/home/support/container.hpp:130:12: error: ‘int’ is not a class, struct, or union type 
    struct container_value 

spirit.cc:15:55: required from here 
/usr/include/boost/spirit/home/qi/detail/pass_container.hpp:316:66: error: no type named ‘type’ in ‘struct boost::spirit::traits::container_value<int, void>’ 
      typedef typename traits::container_value<Attr>::type value_type; 
                   ^
/usr/include/boost/spirit/home/qi/detail/pass_container.hpp:329:15: error: no type named ‘type’ in ‘struct boost::spirit::traits::container_value<int, void>’ 

내가 잘못 여기서 뭘하는지 누구에게도 분명 그 것이다 : C++ 템플릿 오류 메시지의 전형적인 바다에서 나는 다음과 같은 발견?

+0

난 당신이 http://www.boost.org/doc/libs/1_60_0/libs/spirit/doc (명시 적으로 [생략]에 필요가 있다고 생각 /html/spirit/qi/reference/directive/omit.html) 두 속성 모두에 관심이 없기 때문에'+ qi :: space'가 발생합니다. –

답변

3

원래 문법 (일부 서식) 다음과 같습니다

qi::lit("A:") 
>> qi::int_ 
>> +qi::space 
>> qi::lit("B:") 
>> qi::int_ 
>> -( +qi::space 
    >> qi::lit("C:") 
    >> qi::int_ 
    ) 

이 속성을주의하는 것이 중요합니다 각 단말기 유형은 다음을 생성한다 :

생성 compound attributes위한 관련 규칙을 참고 특성 생성 어떤 속성을 생성하지 않는다. 그 바탕으로

, 당신은 실제로 있습니다

  • 정수
  • 문자 벡터 (때문에 +에)
  • 정수
  • 옵션 (인해 -에) 튜플 (때문에 >>에)는
    • 문자 벡터 (+)
    • 정수

이것은 당신이 parse을 부르는 일치하지 않습니다.

핵심은 사용자가 신경 쓰지 않는 속성을 억제하기 위해 omit 지시문을 사용하는 것입니다.

이 경우에 올바른 문법은 다음과 같습니다

qi::lit("A:") 
>> qi::int_ 
>> qi::omit[+qi::space] 
>> qi::lit("B:") 
>> qi::int_ 
>> -( qi::omit[+qi::space] 
    >> qi::lit("C:") 
    >> qi::int_ 
    ) 
+0

우수한 설명; 감사. 필자는 실수로'qi :: space'가 (qi :: lit'와 같은) 연관 속성이없는 파서 유형 중 하나라고 생각했습니다. 당신의 대답은 그것을 분명하게합니다. –

4

phrase_parseqi::space를 사용하여 할 수있는이 문제를 해결하는 방법 선장 :

if (!qi::phrase_parse(s.begin(), s.end(), 
     qi::lit("A:") >> qi::int_ >> "B:" >> qi::int_ >> -("C:" >> qi::int_), qi::space, a, b, c)) 
+1

이것은 또한 작동합니다 (실제로는 더 간단한 구현입니다). 내 대답이 왜 잘못되었는지 자세히 설명했기 때문에 나는 다른 대답을 받아 들였다. 이 입력에 감사드립니다. –

+0

@JasonR 네, 어쨌든 공백을 건너 뛰고 싶다면이 방법이 될 것이라고 말하고 싶습니다. –