я в конечном итоге реализации моего собственного unput() функциональность следующим образом:
struct unputImpl
{
template <typename Iter1T, typename Iter2T, typename StrT>
struct result {
typedef void type;
};
template <typename Iter1T, typename Iter2T, typename StrT>
typename result<Iter1T, Iter2T, StrT>::type operator()(Iter1T& start, Iter2T& end, StrT str) const {
start -= (str.length() - std::distance(start, end));
std::copy(str.begin(), str.end(), start);
end = start;
}
};
phoenix::function<unputImpl> const unput = unputImpl();
Это может быть использован как:
this->self += lex::token_def<lex::omit>("{SYMBOL}\\(")
[
unput(_start, _end, "(" + construct<string>(_start, _end - 1) + " "),
_pass = lex::pass_flags::pass_ignore
];
Если длина бессмысленной строки является большой r, чем согласованная длина токена, он переопределит часть ранее разобранного ввода. Вещь, о которой вам нужно позаботиться, состоит в том, чтобы убедиться, что входная строка имеет достаточно пустое пространство в самом начале, чтобы обрабатывать случай, когда вызов unput() вызывается для первого совпадающего токена.
Что вы пытаетесь достичь? Я имею в виду, в каком контексте вам нужно будет использовать unput()? Если вы покажете пример, я могу показать вам, как я это сделаю (возможно, используя состояния Lexer) – sehe
В принципе, мне нужен лексер, чтобы он соответствовал идентификатору, за которым следует открытый паз «abc (« как один токен, и верните его обратно во входной поток, когда в начале строки появится параграф типа «(abc»). Следующим шагом будет лексер, который будет сканировать его снова, но как два отдельных токена (токен-маркер, а затем токен идентификатора) –
Хорошо, я отправил свой ответ на этот вопрос, дайте мне знать, если я неправильно понял _goal_. – sehe