我正在使用 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>
,它应该知道已经对完整的“再见”令牌进行了词法分析,并发出它。相反,它似乎要等待更多的输入才能让我再见。