2013-05-13 88 views
2

當我嘗試(從boost\spirit\home\lex\argument.hpp: value_setter使用示例)編譯下面的代碼改變令牌值升壓精神的例子,我得到以下編譯器錯誤:不能編譯使用鳳凰演員

c:\program files (x86)\boost\boost_1_50\boost\range\iterator.hpp(63) : error C2039: 'type' : is not a member of 'boost::mpl::eval_if_c<C,F1,F2>' 
with 
[ 
    C=true, 
    F1=boost::range_const_iterator<const char *>, 
    F2=boost::range_mutable_iterator<const char *const > 
] 
c:\program files (x86)\boost\boost_1_50\boost\range\iterator_range_core.hpp(56) : see reference to class template instantiation 'boost::range_iterator<C>' being compiled 
with 
[ 
    C=const char *const 
] 
... 

沒有語義動作,一切都編譯好。這裏是例子:

#include <boost/spirit/include/lex_lexertl.hpp> 
namespace lex = boost::spirit::lex; 

template <typename Lexer> 
struct my_tokens : lex::lexer<Lexer> 
{ 
    my_tokens() 
    { 
     identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; 
     this->self = identifier [ lex::_val = "identifier" ] // problematic action 
        ; 
    } 
    lex::token_def<> identifier; 
}; 

int main() 
{ 
    typedef std::string::iterator base_iterator_type; 
    typedef 
     lex::lexertl::actor_lexer<lex::lexertl::token<base_iterator_type> > 
     lexer_type; 

    my_tokens<lexer_type> myLexer; 
    std::string str = "id1"; 
    base_iterator_type first = str.begin(); 
    bool r = lex::tokenize(first, str.end(), myLexer); 

    if (!r) { 
     std::string rest(first, str.end()); 
     std::cerr << "Lexical analysis failed\n" << "stopped at: \"" 
        << rest << "\"\n"; 
    } 
} 

什麼問題出在哪裏?我如何設置/更改令牌的值?

回答

3

你token_def應公開的預期屬性類型(編譯錯誤表明您分配一個字符串到iterator_range的):

lex::token_def<std::string> identifier; 

現在,鍵入分配匹配

this->self = identifier [ lex::_val = std::string("identifier") ] 

不要忘記更新令牌類型以反映一組可能的令牌屬性類型:

typedef 
    lex::lexertl::actor_lexer<lex::lexertl::token<base_iterator_type, 
     boost::mpl::vector<std::string> > > 
    lexer_type; 

現在它應該編譯:

#include <boost/spirit/include/lex_lexertl.hpp> 
#include <boost/spirit/include/phoenix.hpp> 
namespace lex = boost::spirit::lex; 
namespace phx = boost::phoenix; 

template <typename Lexer> 
struct my_tokens : lex::lexer<Lexer> 
{ 
    my_tokens() 
    { 
     identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; 
     this->self = identifier [ lex::_val = std::string("identifier") ] 
        ; 
    } 
    lex::token_def<std::string> identifier; 
}; 

int main() 
{ 
    typedef std::string::iterator base_iterator_type; 
    typedef 
     lex::lexertl::actor_lexer<lex::lexertl::token<base_iterator_type, boost::mpl::vector<std::string> > > 
     lexer_type; 

    my_tokens<lexer_type> myLexer; 
    std::string str = "id1"; 
    base_iterator_type first = str.begin(); 
    bool r = lex::tokenize(first, str.end(), myLexer); 

    if (!r) { 
     std::string rest(first, str.end()); 
     std::cerr << "Lexical analysis failed\n" << "stopped at: \"" 
        << rest << "\"\n"; 
    } 
} 
+0

將屬性類型添加到令牌類型定義的可能性很棘手。關於這個問題的文件很短。這是我失蹤的關鍵。感謝您指出! – coproc 2013-05-14 08:51:40

+0

是否有可能根據令牌正則表達式中的匹配組形成令牌值?或者至少可以訪問它們? – 2016-02-18 08:05:13

+0

我結束了對此的一個單獨的問題:http://stackoverflow.com/questions/35476454/how-to-make-boost-spirit-lex-token-value-be-a-substring-of-matched-sequence-預 – 2016-02-18 08:37:45