首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检索token_def<>的ID

检索token_def<>的ID
EN

Stack Overflow用户
提问于 2012-07-10 00:57:53
回答 1查看 206关注 0票数 2

是否可以从精神解析器的语义操作中检索在lexer:token_def<> tok;中定义的令牌的ID。

我要做的是使用每个操作符的令牌ID (比如+,-,*等等)并从解析器语义操作中检索该操作符的相应名称(例如,添加、减法、次数等)。

据我所知,在这样的一部作品中:

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

如果toks.plus是或类型为token_def<> plus;,则_1将引用第一个toks.symbol,_2将引用第二个toks.symbol。这是真的吗?如果是这样的话,我如何访问中间令牌(只是为了检索ID)?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-10 07:49:00

您可以使用内置的延迟占位符lex::_tokenid,请参阅docs:

  • 使用凤凰的词义动作

我对教程中的第二个单词计数示例进行了调整,以便动态打印令牌I:

代码语言:javascript
复制
#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;
}

输出:

代码语言:javascript
复制
65536;65538;65536;65538;65536;65538;65536;65538;65536;65538;65536;65538;65536;65538;65536;
lines: 0, words: 8, characters: 41
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11405288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档