лексер boost spirit в потоке недостаточно рано выполняет токенизацию (слишком много упреждающих действий?)

Я использую лексер boost::spirit::lex для токенизации входного потока, используя Spirit::istream_iterators, как описано в Использование Boost.Spirit.Lex и итераторов потока .

Моя проблема в том, что lex::tokenize, похоже, не выводит токен как «ранний» (вдоль входного потока), как я думаю. Он ожидает, пока дополнительный токен (или два?) станет доступным целиком, прежде чем я получу предыдущий токен. Я предполагаю, что это предварительная задержка, но я не уверен, почему это необходимо или как это обойти.

Вот пример:

#include <boost/bind.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
namespace spirit = boost::spirit;
namespace lex = spirit::lex;

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

template <typename Lexer>
struct ALexer : lex::lexer<Lexer> {
  ALexer() {
    this->self.add
      ("hello")
      ("goodbye")
      ("[ \\t\\r\\n]+")
    ;
  }
};

struct Emitter {
  typedef bool result_type;   // for boost::bind
  template <typename Token>
  bool operator() (const Token& t) const {
    cout << "token: " << t.value() << endl;
    return true;
  }
};

int main() {
  cin >> std::noskipws;

  // iterate over stream input
  spirit::istream_iterator in_begin(cin);
  spirit::istream_iterator in_end;

  typedef lex::lexertl::token<spirit::istream_iterator> token_type;
  typedef lex::lexertl::lexer<token_type> lexer_type;
  typedef ALexer<lexer_type> tokenizer_type;
  tokenizer_type tokenizer;

  (void) lex::tokenize(in_begin, in_end, tokenizer, boost::bind(Emitter(), _1));

  return 0;
}

Пример сеанса: (Обратите внимание, что моя ОС буферизует строку cin, поэтому первая «строка» сразу становится доступной для лексера)

(input)    hello goodbye<NEWLINE>
(output)   token: hello
           token:  
(input)    <EOF>
(output)   token: goodbye
           token: 

Я хочу, чтобы лексер получил первую строку, и как только он доберется до <NEWLINE>, он должен знать, что был лексирован полный токен «до свидания», и выдать его. Вместо этого он, кажется, ждет больше информации, прежде чем я смогу попрощаться.


person nfomon    schedule 02.08.2014    source источник