2016-12-30 3 views
3

다음 코드를 실행하면 충돌이 발생합니다. 왜? boost :: spirit :: multi_pass가 술어와 대안으로 충돌합니다.

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

using namespace boost::spirit; 
typedef multi_pass< 
      std::string::const_iterator, 
      iterator_policies::default_policy< 
       iterator_policies::first_owner, 
       iterator_policies::no_check, 
       iterator_policies::buffering_input_iterator, 
       iterator_policies::split_std_deque>> 
     string_mp_iterator; 

int main() { 
    std::string input = "234"; 
    string_mp_iterator input_begin(input.begin()), 
      input_end((string_mp_iterator())); 
    qi::rule<string_mp_iterator, boost::variant<int, double>()> r = 
      &qi::lit('1') >> qi::int_ | qi::double_; 
    qi::parse(input_begin, input_end, r); 
    return 0; 
} 

내가 multi_pass 반복자를 사용하는 것으로, 술어 및 후속 대안 모두가 필요 보인다 충돌을 재현하고, 입력을 할 수있는 조건을 만족하지합니다.

내가 여기 어떻게 든 multi_pass을 잘못 사용하고 있다는 느낌이 들지만 문제가 정확히 무엇인지 알 수 없습니다.

+2

2 진수와 정수를 신뢰할 수있는 구문 분석하려고합니까? https://stackoverflow.com/search?q=strict_real_policies – sehe

+0

을 찾으십시오. 이것은 가능한 한 간단하게 유지하려고하는 예제입니다. 그럼에도 불구하고 이것은 다른 곳에서도 유용 할 것입니다. 감사! –

+0

이것이 정의되지 않은 행동의 본질입니다. 결과가 정의되어 있지 않기 때문에 추론 할 수 없습니다. – sehe

답변

2

는 간단하게 끝 반복자에 대한 초기화를 수정.

string_mp_iterator input_end(input.end()); 

입력 반복기가 아니기 때문에 기본 생성 반복기를 사용할 수 없습니다.

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

using namespace boost::spirit; 
typedef multi_pass< 
    std::string::const_iterator, 
    iterator_policies::default_policy< 
     iterator_policies::first_owner, iterator_policies::no_check, 
     iterator_policies::buffering_input_iterator, 
     iterator_policies::split_std_deque>> 
    string_mp_iterator; 

int main() { 
    std::string input = "234"; 
    string_mp_iterator input_begin(input.begin()), 
         input_end(input.end()); 
    qi::rule<string_mp_iterator, boost::variant<int, double>()> r = &qi::lit('1') >> qi::int_ | qi::double_; 
    qi::parse(input_begin, input_end, r); 
} 
+0

이것은 분명히 코드를 수정하지만 충돌을 일으키는 데 술어와 대체 조합이 필요한 이유는 여전히 수수께끼입니다. 내 실제 사용 사례에서 문자열 반복자를'multi_pass'로 래핑하지 않습니다. 그럼에도 불구하고,'multi_pass '의 사용이 올바르지 않다는 나의 의구심을 확인한다. –

2

iterator_policies::buffering_input_iterator std :: string에는 포인터가 end이 아니라 null이 아닌 multi_pass 반복기로 std :: string을 감쌀 수 없습니다. 이것이 반복기가 호환되지 않는 이유입니다. std::string을 구문 분석하려면 iterator를 multi_pass 요구 사항을 충족 할 때 직접 사용하십시오. 당신이 스트림 (code sorta from here)로 변경하려는 경우 :

typedef std::istreambuf_iterator<char> base_iterator_type; 
typedef boost::spirit::multi_pass<base_iterator_type> forward_iterator_type; 

main() 
{ 
    std::istringstream input("234"); 

    base_iterator_type in_begin(input); 
    base_iterator_type in_end; 
    forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); 
    forward_iterator_type fwd_end = boost::spirit::make_default_multi_pass(in_end); 

    qi::rule<forward_iterator_type, boost::variant<int, double>()> r = 
     &qi::lit('1') >> qi::int_ | qi::double_; 
    qi::parse(fwd_begin, fwd_end, r); 
    return 0; 
}