2011-11-30 41 views
1

[取而代之的是一個完整的程序和版本更新代碼]提升精神:斷言在Windows下失敗,但不在Linux下。爲什麼?

下面的代碼在Windows下失敗,出現以下消息(對不起manualy從
法語翻譯,我不知道如何強制Visual C++中英語爲工作語言)。這是Windows下的 。它在Linux下工作。 gcc LimaTokenizerParser.cpp -o LimaTokenizerPars -lboost_system-mt -lstdc++ 的Windows(失敗):你可以用 的Linux編譯cl LimaTokenizerParser.cpp /Ic:\boost\path\include /EHsc

我用升壓1.50與Windows下的Visual C++ 2010和Boost 1.48 和gcc 4.6.3 Linux下。

升壓grammar.hpp斷言是伴隨着此評論:

// If you see the assertion below failing then the start rule 
// passed to the constructor of the grammar is not compatible with 
// the grammar (i.e. it uses different template parameters). 

,但我不知道如何去了解它在我的情況...

任何想法?

問候,

GAEL

代碼:

LimaTokenizerParser.cpp

#include "SpiritTokenizerParser.hpp" 

#include <iostream> 
#include <fstream> 

void readStream(std::istream &is,std::string &dest) 
{ 
    while (is.good() && !is.eof()) 
    { 
    const int bufferSize = 10240; 
    char buffer[bufferSize]; 
    is.read(buffer,bufferSize); 
    const int size = is.gcount(); 
    if (size>0) 
     dest.insert(dest.end(),buffer,buffer+size); 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    if (argc != 2) 
    { 
    std::cerr << "Needs exactly one argument" << std::endl; 
    return 1; 
    } 
    namespace qi = boost::spirit::qi; 
    namespace ascii = boost::spirit::ascii; 
    using ascii::space; 
    typedef std::string::const_iterator iterator_type; 
    typedef tokenizer<iterator_type> tokenizer; 

    // @ERROR DOES NOT WORK ON WINDOWS PORT 
tokenizer tokenizer_parser; 
    std::string str; 
    std::ifstream file(argv[1]); 
    readStream(file, str); 

    std::string::const_iterator iter = str.begin(); 
    std::string::const_iterator end = str.end(); 

    tokenizer_automaton automaton; 
    bool r = false; 
    // @ERROR DOES NOT WORK ON WINDOWS PORT 
    r = phrase_parse(iter, end, tokenizer_parser, skipper, automaton); 

    if (r && iter == end) 
    { 
     std::cout << "Parsing succeeded: "<<automaton.size()<<" states" << std::endl; 
    } 
    else 
    { 
     std::string rest(iter, end); 
     std::cout << "Parsing failed. Stopped at: \": " << rest << "\"\n"; 
    } 

    return 0; 
} 

SpiritTokenizerParser.hpp

#ifndef SPIRITTOKENIZERPARSER_HPP 
#define SPIRITTOKENIZERPARSER_HPP 

#include <boost/config/warning_disable.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 
#include <boost/spirit/include/phoenix_operator.hpp> 
#include <boost/spirit/include/phoenix_object.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 
#include <boost/fusion/include/io.hpp> 

#include <string> 

namespace qi = boost::spirit::qi; 
namespace ascii = boost::spirit::ascii; 

#define skipper qi::space | ascii::char_('#') >> *(ascii::char_ - qi::eol) >> qi::eol 
typedef BOOST_TYPEOF(skipper) skipper_type; 

enum transitions { 
    STORE, 
    FLUSH, 
    TOKEN, 
    EXIT, 
    LTOKEN 
}; 

typedef std::vector<std::string> tokenizer_precondition; 
typedef std::vector<std::string> tokenizer_postcondition; 
struct tokenizer_transition 
{ 
    std::vector<tokenizer_precondition> preconditions; 
    std::vector<std::string> event; 
    std::vector<tokenizer_postcondition> postconditions; 
    transitions transition; 
    std::string target; 
    std::vector<std::string> statuses; 
}; 

struct tokenizer_state 
{ 
    std::string id; 
    std::vector<tokenizer_transition> transitions; 
}; 

typedef std::vector<tokenizer_state> tokenizer_automaton; 

BOOST_FUSION_ADAPT_STRUCT(
          tokenizer_transition, 
          (std::vector<tokenizer_precondition>, preconditions) 
          (std::vector<std::string>, event) 
          (std::vector<tokenizer_postcondition>, postconditions) 
          (transitions, transition) 
          (std::string, target) 
          (std::vector<std::string>, statuses) 
         ) 

BOOST_FUSION_ADAPT_STRUCT(
          tokenizer_state, 
          (std::string, id) 
          (std::vector<tokenizer_transition>, transitions) 
         ) 

using ascii::space_type; 

template <typename Iterator> 
struct tokenizer : qi::grammar<Iterator, tokenizer_automaton(), skipper_type> 
{ 
    struct transitionsymbol_ : qi::symbols<char, unsigned> 
    { 
    // > is +1 store 
    ///is +1 flush (forget the current token) 
    // = is +1 token 
    //^is exit 

    transitionsymbol_() 
    { 
     add 
     (">", STORE) 
     ("/", FLUSH) 
     ("=", TOKEN) 
     ("^", EXIT) 
     ; 
    } 

    } transitionsymbol; 

    tokenizer() : tokenizer::base_type(start) 
    { 
    using qi::alnum; 
    using qi::lexeme; 
    using ascii::char_; 

    start %= *state ; 
    state %= '(' >> identifier >> ')' >> '{' >> *transition >> '}'; 
    transition %= '-' >> *precondition >> event >> *postcondition >> transitionsymbol >> identifier >> -('(' >> identifier % ',' >> ')'); 
    identifier %= lexeme[+(alnum | char_('_'))]; 
    precondition %= '[' >> (identifier % '|') >> ']'; 
    event %= identifier % '|'; 
    postcondition %= identifier % '|'; 
    } 

    qi::rule<Iterator, tokenizer_automaton(), skipper_type> start; 
    qi::rule<Iterator, tokenizer_state(), skipper_type> state; 
    qi::rule<Iterator, tokenizer_transition(), skipper_type> transition; 
    qi::rule<Iterator, std::string(), skipper_type> identifier; 
    qi::rule<Iterator, std::vector<std::string>(), skipper_type> precondition; 
    qi::rule<Iterator, std::vector<std::string>(), skipper_type> event; 
    qi::rule<Iterator, std::vector<std::string>(), skipper_type> postcondition; 
}; 

//] 

#endif // SPIRITTOKENIZERPARSER_HPP 

消息S:

LimaTokenizerParser.cpp 
c:\Program Files\boost\boost_1_50\include\boost/spirit/home/qi/nonterminal/grammar.hpp(77) : error C2664: 'boost::mpl::assertion_failed'<FF>: can not convert parameter 1 from 'boost::mpl::failed ************(__cdecl boost::spirit::qi::grammar<Iterator,T1,T2>::{ctor}::incompatible_start_rule::* ***********)(boost::spirit::qi::rule<Iterator,T1,boost::spirit::qi::alternative<Elements>>)' en 'boost::mpl::assert<false>::type' 
     with 
     [ 
      Iterator=iterator_type, 
      T1=tokenizer_automaton (void), 
      T2=skipper_type, 
      Elements=boost::fusion::cons<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::standard>>,boost::fusion::cons<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,false,false>,boost::fusion::cons<boost::spirit::qi::kleene<boost::spirit::qi::difference<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::char_,boost::spirit::char_encoding::ascii>>,boost::spirit::qi::eol_parser>>,boost::fusion::cons<boost::spirit::qi::eol_parser,boost::fusion::nil>>>>,boost::fusion::nil>> 
     ] 
     No constructor could take the source type, or the constructor overload resolution was ambiguous 
     e:\projets\amose\sources\lima_linguisticprocessing\src\linguisticprocessing\core\flattokenizer\SpiritTokenizerParser.hpp(89)<FF>: see reference to function template instantiation 'boost::spirit::qi::grammar<Iterator,T1,T2>::grammar<Iterator,tokenizer_automaton(void),boost::spirit::qi::alternative<Elements>,boost::spirit::unused_type,boost::spirit::unused_type>(const boost::spirit::qi::rule<Iterator,T1,boost::spirit::qi::alternative<Elements>> &,const std::string &)' en cours de compilation 
     with 
     [ 
      Iterator=iterator_type, 
      T1=tokenizer_automaton (void), 
      T2=skipper_type, 
      Elements=boost::fusion::cons<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::standard>>,boost::fusion::cons<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,false,false>,boost::fusion::cons<boost::spirit::qi::kleene<boost::spirit::qi::difference<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::char_,boost::spirit::char_encoding::ascii>>,boost::spirit::qi::eol_parser>>,boost::fusion::cons<boost::spirit::qi::eol_parser,boost::fusion::nil>>>>,boost::fusion::nil>> 
     ] 

TokenizerParser.hpp(88)<FF>: during the compilation of the member function ':: tokenizer tokenizer <iterator> (void)' model class 
     with 
     [ 
      Iterator=iterator_type 
     ] 
     LimaTokenizerParser.cpp(33)<FF>: see reference to class template instantiation 'tokenizer <iterator>' being compiled 
     with 
     [ 
      Iterator=iterator_type 
     ] 
+0

你能自己翻譯錯誤信息嗎? –

+0

消息翻譯... – Kleag

回答

3

投遞靈列表(是的,我看到這個貼有),最好能提供的東西很少。做最小的事情會有很大的幫助。它避免了在理解代碼時往往浪費時間的視覺混亂。無論如何,任何要求支持的人都可以做到,這只是一個消除問題。附加是我最小的意思。如果我已經看到類似的東西,那隻需要幾秒鐘,而不是10分鐘就能理解問題。

總之,這裏的蒸餾代碼和最小的,因爲它可以同時仍出現該問題:

#include <boost/config/warning_disable.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 
#include <string> 

namespace qi = boost::spirit::qi; 
typedef qi::space_type skipper_type; 

template <typename Iterator> 
struct tokenizer : qi::grammar<Iterator, skipper_type> 
{ 
    tokenizer() : tokenizer::base_type(start) 
    { 
    } 

    qi::rule<Iterator, skipper_type> start; 
}; 



int main() 
{ 
    typedef std::string::const_iterator iterator_type; 
    typedef tokenizer<iterator_type> tokenizer; 

    // @ERROR DOES NOT WORK ON WINDOWS PORT 
    tokenizer tokenizer_parser; 
    return 0; 
} 

我注意到,如果我重新命名「skipper_type」到「skipper_type_」(注意結尾下劃線)。然後它編譯好!這導致我相信它是一個MSVC錯誤。

解決方案:只需更改名稱skipper_type即可。

+0

非常感謝Joel,您花在我的問題上的時間,因爲我已經在精神一般的郵件列表上回答了。下次我會盡量減少代碼。 – Kleag