如何使用 Boost::Spirit::Lex 来 lex 一个文件而不先将整个文件读入内存?
我正在考虑使用 boost::spirit::lex 编写词法分析器,但我能找到的所有示例似乎都假设您已先将整个文件读入 RAM。我想编写一个不需要整个字符串都在 RAM 中的词法分析器,这可能吗?或者我需要使用其他东西吗?
我尝试使用 istream_iterator,但 boost 会给我一个编译错误,除非我使用 const char* 作为迭代器类型。
例如,我能找到的所有示例基本上都是这样做的:
lex_functor_type< lex::lexertl::lexer<> > lex_functor;
// assumes entire file is in memory
char const* first = str.c_str();
char const* last = &first[str.size()];
bool r = lex::tokenize(first, last, lex_functor,
boost::bind(lex_callback_functor(), _1, ... ));
另外,是否可以以某种方式从 lex 标记确定行/列号?
谢谢!
I'm looking at writing a lexer using boost::spirit::lex, but all the examples I can find seem to assume that you've read the entire file into RAM first. I'd like to write a lexer that doesn't require the whole string to be in RAM, is that possible? Or do I need to use something else?
I tried using istream_iterator, but boost gives me a compile error unless I use const char* as the iterator types.
e.g. All the examples I can find basically do this:
lex_functor_type< lex::lexertl::lexer<> > lex_functor;
// assumes entire file is in memory
char const* first = str.c_str();
char const* last = &first[str.size()];
bool r = lex::tokenize(first, last, lex_functor,
boost::bind(lex_callback_functor(), _1, ... ));
Also, is it possible to determine line/column numbers from lex tokens somehow?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Spirit Lex 可与任何迭代器配合使用,只要它符合标准前向迭代器的要求即可。这意味着您可以使用任何符合要求的迭代器来提供词法分析器(调用 lex::tokenize())。例如,如果您想使用 std::istream,您可以将其包装到 boost::spirit::istream_iterator 中,
这样就可以工作。
对于问题的第二部分(与输入的行/列号相关):是的,可以使用词法分析器跟踪输入位置。不过,这并不是一件小事。您需要创建自己的令牌类型来存储行/列信息并使用它而不是预定义的令牌类型。很多人都在问这个,所以我可能会继续创建一个例子。
Spirit Lex works with any iterator as long as it conforms to the requirements of standard forward iterators. That means you can feed the lexer (invoke
lex::tokenize()
) with any conforming iterator. For instance, if you want to use astd::istream
, you could wrap it into aboost::spirit::istream_iterator
:and it would work.
For the second part of your question (related to the line/column number of the input): yes it is possible to track the input position using the lexer. It's not trivial, though. You need to create your own token type which stores the line/column information and use this instead of the predefined token type. Many people have been asking for this, so I might just go ahead and create an example.