2012-07-10 40 views
2

是否有可能從Spirit分析器的語義操作中檢索在詞法分析器中定義的標記的標識,如下所示:token_def<> tok;檢索token_def的標識<>

我想要做的是使用每個運算符的標識ID(如+, - ,*等),並從解析器語義操作(如添加,減,時間等)

據我明白,在象生產:

toks.symbol >> >> toks.plus toks.symbol;

如果toks.plus是或類型token_def<> plus;,_1將參照第一toks.symbol和_2將參考第二toks.symbol。真的嗎?如果是這樣,我怎樣才能訪問中間令牌(只是爲了檢索ID)?

謝謝!

回答

2

您可以使用內置的懶惰佔位lex::_tokenid,請參閱文檔:

我適應了second word-count sample from the tutorials打印在飛行令牌IDS:

#include <boost/config/warning_disable.hpp> 
#include <boost/spirit/include/lex_lexertl.hpp> 
#include <boost/spirit/include/phoenix_operator.hpp> 
#include <boost/spirit/include/phoenix_statement.hpp> 
#include <boost/spirit/include/phoenix_algorithm.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 

#include <iostream> 
#include <string> 

namespace lex = boost::spirit::lex; 
namespace phx = boost::phoenix; 

struct distance_func 
{ 
    template <typename Iterator1, typename Iterator2> 
    struct result : boost::iterator_difference<Iterator1> {}; 

    template <typename Iterator1, typename Iterator2> 
    typename result<Iterator1, Iterator2>::type 
    operator()(Iterator1& begin, Iterator2& end) const 
    { 
     return std::distance(begin, end); 
    } 
}; 
boost::phoenix::function<distance_func> const distance = distance_func(); 

template <typename Lexer> 
struct word_count_tokens : lex::lexer<Lexer> 
{ 
    word_count_tokens() 
     : c(0), w(0), l(0) 
     , word("[^ \t\n]+")  // define tokens 
     , eol("\n") 
     , any(".") 
    { 
     using boost::spirit::lex::_start; 
     using boost::spirit::lex::_end; 
     using boost::spirit::lex::_tokenid; 
     using boost::phoenix::ref; 

     // associate tokens with the lexer 
     this->self 
      = word [++ref(w), ref(c) += distance(_start, _end), phx::ref(std::cout) << _tokenid << ";" ] 
      | eol [++ref(c), ++ref(l), phx::ref(std::cout) << _tokenid << ";" ] 
      | any [++ref(c), phx::ref(std::cout) << _tokenid << ";" ] 
      ; 
    } 

    std::size_t c, w, l; 
    lex::token_def<> word, eol, any; 
}; 

/////////////////////////////////////////////////////////////////////////////// 
int main(int argc, char* argv[]) 
{ 
    typedef 
     lex::lexertl::token<char const*, lex::omit, boost::mpl::false_> 
     token_type; 

    typedef lex::lexertl::actor_lexer<token_type> lexer_type; 

    word_count_tokens<lexer_type> word_count_lexer; 

    std::string str ("the lazy moon jumped over the brazen mold"); 
    char const* first = str.c_str(); 
    char const* last = &first[str.size()]; 

    lexer_type::iterator_type iter = word_count_lexer.begin(first, last); 
    lexer_type::iterator_type end = word_count_lexer.end(); 

    while (iter != end && token_is_valid(*iter)) 
     ++iter; 

    if (iter == end) { 
     std::cout << "\nlines: " << word_count_lexer.l 
      << ", words: " << word_count_lexer.w 
      << ", characters: " << word_count_lexer.c 
      << "\n"; 
    } 
    else { 
     std::string rest(first, last); 
     std::cout << "Lexical analysis failed\n" << "stopped at: \"" 
      << rest << "\"\n"; 
    } 
    return 0; 
} 

輸出:

65536;65538;65536;65538;65536;65538;65536;65538;65536;65538;65536;65538;65536;65538;65536; 
lines: 0, words: 8, characters: 41 
+0

謝謝sehe。因此,這是如何從詞法分析器語義操作中訪問令牌ID的。有沒有一種方法可以從解析器語義操作中訪問它?如下所示:tok.symbol >> tok.plus >> tok.symbol [std :: cout <<「plus_token_id」<< std :: endl]; – 2012-07-10 17:14:55

+0

@HaithamGad [這是Lex教程改編的第三個示例](http://ideone.com/YqoDo)使用SA從解析器SA打印標記ID。我不明白這是否會增加價值,因爲令牌在您匹配時已經知道了? – sehe 2012-07-10 23:39:32

+0

我看到在這種情況下,單詞被定義爲token_def 。如果單詞被定義爲token_def <>,這個代碼是否可以工作?據我所知,像這樣定義的令牌在解析器語義操作中不能被佔位符訪問。真的嗎? – 2012-07-11 15:23:26