如何使用 Boost::Spirit::Lex 来 lex 一个文件而不先将整个文件读入内存?

发布于 2024-10-12 07:23:02 字数 583 浏览 4 评论 0原文

我正在考虑使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鼻尖触碰 2024-10-19 07:23:02

Spirit Lex 可与任何迭代器配合使用,只要它符合标准前向迭代器的要求即可。这意味着您可以使用任何符合要求的迭代器来提供词法分析器(调用 lex::tokenize())。例如,如果您想使用 std::istream,您可以将其包装到 boost::spirit::istream_iterator 中,

bool tokenize(std::istream& is, ...)
{
    lex_functor_type< lex::lexertl::lexer<> > lex_functor;

    boost::spirit::istream_iterator first(is);
    boost::spirit::istream_iterator last;

    return lex::tokenize(first, last, lex_functor,
        boost::bind (lex_callback_functor(), _1, ... ));   
}

这样就可以工作。

对于问题的第二部分(与输入的行/列号相关):是的,可以使用词法分析器跟踪输入位置。不过,这并不是一件小事。您需要创建自己的令牌类型来存储行/列信息并使用它而不是预定义的令牌类型。很多人都在问这个,所以我可能会继续创建一个例子。

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 a std::istream, you could wrap it into a boost::spirit::istream_iterator:

bool tokenize(std::istream& is, ...)
{
    lex_functor_type< lex::lexertl::lexer<> > lex_functor;

    boost::spirit::istream_iterator first(is);
    boost::spirit::istream_iterator last;

    return lex::tokenize(first, last, lex_functor,
        boost::bind (lex_callback_functor(), _1, ... ));   
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文