2014-09-21 3 views
1

다음 간단한 코드에서 "액세스 위반"예외가 발생합니다. 왜 그렇게됩니까? 나는 그 이유를 알 수 없다.boost :: spirit :: qi 및 액세스 위반 예외

#define BOOST_SPIRIT_DEBUG 
#include <boost/fusion/adapted/struct.hpp> 
#include <boost/spirit/include/qi.hpp> 

namespace qi = boost::spirit::qi; 
typedef boost::spirit::ascii::space_type TSkipper; 

struct MyField 
{ 
    bool isConst; 
    std::string mtype; 
    std::string name; 
}; 

BOOST_FUSION_ADAPT_STRUCT 
    (
    MyField, 
    (bool, isConst) 
    (std::string, mtype) 
    (std::string, name) 
    ) 

template<typename Iterator, typename TSkipper = boost::spirit::ascii::space_type> 
struct field_grammar : qi::grammar < Iterator, Field(), TSkipper > 
{ 
    field_grammar() : field_grammar::base_type(field, "field_grammar") 
    { 
     // must parse values such as: int, list, i, j9_ 
     valid_symbols %= lexeme[qi::char_("a-zA-Z") > *(qi::char_("a-zA-Z0-9_"))]; 
     valid_symbols.name("valid_symbols"); 

     field %= qi::matches["const"] >> valid_symbols >> valid_symbols; 
     field.name("field"); 

     BOOST_SPIRIT_DEBUG_NODES((valid_symbols)(field)); 
    } 

    boost::spirit::qi::rule<Iterator, std::string(), TSkipper> valid_symbols; 
    boost::spirit::qi::rule<Iterator, Field(), TSkipper> field; 
}; 

는 그리고 난 다음 방법으로이 문법을 사용하십시오 "제나라 :: phrase_parse"기능을 실행하면

void SpiritTestSimple() 
{ 
    std::string mdata = "int destroyWindow"; 

    std::string::const_iterator first = mdata.begin(), last = mdata.end(); 
    field_grammar<std::string::const_iterator> test_grammar; 

    Field parsed; 
    bool is_parsed; 
    try 
    { 
     is_parsed = qi::phrase_parse(first, last, test_grammar, 
            boost::spirit::ascii::space, parsed); 
    } 
    catch (const qi::expectation_failure<std::string::const_iterator>& e) 
    { 
     std::string frag(e.first, e.last); 
     std::cout << e.what() << "'" << frag << "'" << std::endl; 
    } 

    BOOST_ASSERT(is_parsed && "the example not parsed"); 
} 

나는 예외를받을 수 있습니다. 왜 그런가? 그리고 그것을 고치는 방법? msvs2013을 사용합니다.

답변

1

또한 VS2013을 사용합니다. 괜찮아 작동하고, 나는 장거리 슛을 제외하고 그것으로 많은 잘못 볼 수 없습니다 :

  • 당신이 아마 필요 Field 참조가 (컴파일 오류가 나와 함께 그 리드를)
  • qi::lexeme을 평가해야 MyField (이 역시 컴파일 오류가 발생합니다)
  • 기술적으로 is_parsed이 ASSERT 매크로에서 초기화되지 않았기 때문에 프로그램의 동작이 정의되지 않았습니다.

다음과 같은 버전을 시도 할 수 있습니다 : 그것은하지 WorksForYou (TM)를 수행하면 모든 패치 수준, 라이브러리 버전, 건축, 최적화 플래그 및보고 시간 Live On Coliru

#define BOOST_SPIRIT_DEBUG 
#include <boost/fusion/adapted/struct.hpp> 
#include <boost/spirit/include/qi.hpp> 

namespace qi = boost::spirit::qi; 

struct MyField 
{ 
    bool  isConst = false; 
    std::string mtype = ""; 
    std::string name = ""; 

    friend std::ostream& operator<<(std::ostream& os, MyField const& mf) 
    { 
     return os << "MyField[" 
         << "isConst:" << std::boolalpha << mf.isConst 
         << "\nmtype:" << mf.mtype 
         << "\nname: " << mf.name << "]"; 
    } 
}; 

BOOST_FUSION_ADAPT_STRUCT 
    (
    MyField, 
    (bool, isConst) 
    (std::string, mtype) 
    (std::string, name) 
    ) 

template<typename Iterator, typename TSkipper = boost::spirit::ascii::space_type> 
struct field_grammar : qi::grammar <Iterator, MyField(), TSkipper> 
{ 
    field_grammar() : field_grammar::base_type(field, "field_grammar") 
    { 
     // must parse values such as: int, list, i, j9_ 
     valid_symbols = qi::char_("a-zA-Z") >> *(qi::char_("a-zA-Z0-9_")); 
     field   = qi::matches["const"] >> valid_symbols >> valid_symbols; 

     BOOST_SPIRIT_DEBUG_NODES((valid_symbols)(field)); 
    } 

    boost::spirit::qi::rule<Iterator, std::string()> valid_symbols; 
    boost::spirit::qi::rule<Iterator, MyField(), TSkipper> field; 
}; 

void SpiritTestSimple() 
{ 
    std::string const mdata = "int destroyWindow"; 

    std::string::const_iterator first = mdata.begin(), last = mdata.end(); 
    field_grammar<std::string::const_iterator> test_grammar; 

    try 
    { 
     MyField parsed; 
     if (qi::phrase_parse(first, last, test_grammar, 
            boost::spirit::ascii::space, parsed)) 
     { 
      std::cout << "Parsed: " << parsed << "\n"; 
     } else 
     { 
      std::cout << "Failed to parse '" << std::string(first, last) << "'\n"; 
     } 
    } 
    catch (const qi::expectation_failure<std::string::const_iterator>& e) 
    { 
     std::string frag(e.first, e.last); 
     std::cout << e.what() << "'" << frag << "'" << std::endl; 
    } 

} 

int main() 
{ 
    SpiritTestSimple(); 
} 

을 그 재즈.

+0

내 샘플 코드에서 실수를해서 죄송합니다. 몇 개의 큰 코드 부분에서 잘라 냈습니다. 나는 명확한 프로젝트를 다시 만들고 코드와 모든 작업을 복사하여 붙여 넣습니다. 도와 주셔서 감사합니다. 나는 내 문제가 정말로 깃발에 달려 있다고 생각한다. 좋아, 예외적으로 내 측에서 제기 한 프로젝트에 영향을 미칠 수있는 것을 검색하도록하겠습니다. – AeroSun

+0

@AeroSun 또는 일관성없는 빌드로 인해 단순히 정의되지 않은 동작. 전체 재구성이 필요할 수도 있습니다. – sehe

관련 문제