2014-09-21 90 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; 
}; 

而且我用這個語法,在未來的方式:

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"); 
} 

我收到異常時執行的「氣:: phrase_parse」功能。 爲什麼會發生?以及如何解決它? 我使用msvs2013。

回答

1

我也使用VS2013。它的工作原理好了,我看不出太多毛病,除了遠射:

  • 你需要(鉛和我一起編譯錯誤)資格qi::lexeme
  • 你有Field參考,可能需要(這也會導致編譯錯誤)
  • 從技術上講,您的程序具有未定義的行爲,因爲is_parsed可能未在ASSERT宏中初始化。

你可以嘗試以下版本: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(); 
} 

如果還是不行WorksForYou(TM)是時候看看補丁級別,庫版本,體系結構,優化標誌和所有那爵士樂。

+0

對不起,我的示例代碼中的錯誤 - 它是從幾個大代碼部分中刪除。我再次創建清晰的項目並複製粘貼代碼和所有作品。感謝幫助。我認爲我的麻煩實際上取決於國旗。好的,讓我搜索一下可能會影響項目的問題,這個問題在我這邊提出。 – AeroSun 2014-09-22 08:22:11

+0

@AeroSun或者由於構建不一致而導致未定義的行爲。可能需要完全重建 – sehe 2014-09-22 08:58:58