在boost :: spirit :: lex中,如何添加具有语义操作和令牌ID的令牌?

时间:2016-08-26 16:45:03

标签: c++ boost boost-spirit lexer

我知道如何使用标识符添加令牌定义:

this->self.add(identifier, ID_IDENTIFIER);

我知道如何使用语义操作添加令牌定义:

this->self += whitespace [ lex::_pass = lex::pass_flags::pass_ignore ];

不幸的是,这不起作用:

this->self.add(whitespace
                   [ lex::_pass = lex::pass_flags::pass_ignore ],
               ID_IDENTIFIER);

它给出了一个错误,即令牌无法转换为字符串(!?):

  

错误C2664:'const boost :: spirit :: lex :: detail :: lexer_def_> :: adder& boost :: spirit :: lex :: detail :: lexer_def_> :: adder :: operator ()(wchar_t,unsigned int)const':不能将参数1从'const boost :: proto :: exprns _ :: expr'转换为'const std :: basic_string,std :: allocator> &安培;'

有趣的是,lexer.hpp中的adder有一个operator (),它将一个动作作为第三个参数 - 但它在我的boost版本(1.55.0)中被注释掉了。这是否适用于较新版本?

如果没有这个,我如何向词法分析器添加带语义动作和ID的标记定义?

1 个答案:

答案 0 :(得分:2)

查看头文件似乎至少有两种可能的方法:

  • 您可以使用template<class BidirIt, class UnaryPred> BidirIt partition(BidirIt first, BidirIt last, UnaryPred pred, std::bidirectional_iterator_tag) { while (true) { while ((first != last) && pred(*first)) { ++first; } if (first == last) { break; } --last; while ((first != last) && !pred(*last)) { --last; } if (first == last) { break; } std::iter_swap(first, last); ++first; } return first; } template<class ForwardIt, class UnaryPred> ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPred pred, std::forward_iterator_tag) { first = std::find_if_not(first, last, pred); if (first == last) { return first; } for (ForwardIt src = std::next(first); src != last; ++src) { if (pred(*src)) { std::iter_swap(first, src); ++src; } } return first; } template<class ForwardIt, class UnaryPred> ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPred pred) { return partition(first, last, pred, typename std::iterator_traits<ForwardIt>::iterator_category()); } 的{​​{1}}成员函数,以便在定义令牌后设置ID:

    token_def
  • 定义令牌时,您可以使用id的两个参数构造函数:

    ellipses = "\\.\\.\\.";
    ...
    ellipses.id(ID_ELLIPSES);
    

然后您可以像以前一样简单地添加语义操作:

token_def

以下代码为based on Boost.Spirit.Lex example3.cpp,稍作修改(标有number = lex::token_def<>("[0-9]+", ID_NUMBER); )即可实现您的目标。

完整示例(Running on rextester)

this->self = ellipses[phx::ref(std::cout) << "Found ellipses.\n"] | '(' | ')' | number[phx::ref(std::cout) << "Found: " << phx::construct<std::string>(lex::_start, lex::_end) << '\n'];