我知道如何使用标识符添加令牌定义:
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的标记定义?
答案 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);
)即可实现您的目标。
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'];