C++ 如何使用Boost::Spirit::Lex对文件进行Lex处理,而不首先将整个文件读入内存?
我正在考虑使用boost::spirit::lex编写一个lexer,但是我能找到的所有示例似乎都假设您已经首先将整个文件读入RAM。我想写一个lexer,它不需要整个字符串都在RAM中,这可能吗?还是我需要用别的东西 我尝试使用istream_迭代器,但boost会给我一个编译错误,除非我使用const char*作为迭代器类型 e、 g.我能找到的所有示例基本上都是这样做的:C++ 如何使用Boost::Spirit::Lex对文件进行Lex处理,而不首先将整个文件读入内存?,c++,boost,lex,boost-spirit,C++,Boost,Lex,Boost Spirit,我正在考虑使用boost::spirit::lex编写一个lexer,但是我能找到的所有示例似乎都假设您已经首先将整个文件读入RAM。我想写一个lexer,它不需要整个字符串都在RAM中,这可能吗?还是我需要用别的东西 我尝试使用istream_迭代器,但boost会给我一个编译错误,除非我使用const char*作为迭代器类型 e、 g.我能找到的所有示例基本上都是这样做的: lex_functor_type< lex::lexertl::lexer<> > lex_
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_函子类型lex_函子;
//假设整个文件都在内存中
char const*first=str.c_str();
字符常量*last=&first[str.size()];
bool r=lex::tokenize(第一个,最后一个,lex_函子,
绑定(lex_回调函数(),_1,…);
另外,是否有可能以某种方式从lex标记确定行/列编号
谢谢 Spirit Lex可以与任何迭代器一起工作,只要它符合标准正向迭代器的要求。这意味着您可以向lexer(invoke
lex::tokenize()
)提供任何符合条件的迭代器。例如,如果要使用std::istream
,可以将其包装到boost::spirit::istream\u迭代器中:
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, ... ));
}
bool标记化(std::istream&is,…)
{
lex_函子类型lex_函子;
boost::spirit::istream_迭代器优先(is);
boost::spirit::istream_迭代器last;
返回lex::tokenize(第一个,最后一个,lex_函子,
绑定(lex_回调函数(),_1,…);
}
这会奏效的
对于问题的第二部分(与输入的行号/列号相关):是的,可以使用lexer跟踪输入位置。不过,这不是小事。您需要创建自己的令牌类型,该类型存储行/列信息,并使用该类型而不是预定义的令牌类型。很多人都在问这个问题,所以我可以继续创建一个示例。+1,是的,Spirit文档中的新示例将非常好:)事实上,我做到了。BoostV1.47将有这样一个令牌类型和一个演示如何使用它的新示例。谢谢Harmut!非常期待以新的精神推动1.47版本的发布!有人在没有将整个文件读入内存的情况下运行了它吗?@hkaiser我找不到您参考的示例。你能看看吗?非常感谢。