2013-05-13 51 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