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

时间:2011-01-17 17:10:05

标签: c++ boost lex boost-spirit

我正在寻找使用boost :: spirit :: lex编写词法分析器,但我能找到的所有示例似乎都假设您已经将整个文件首先读入RAM。我想写一个不需要整个字符串在RAM中的词法分析器,这可能吗?或者我需要使用其他东西吗?

我尝试使用istream_iterator,但是boost会给我一个编译错误,除非我使用const char *作为迭代器类型。

e.g。我能找到的所有例子基本上都是这样做的:

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令牌的行/列号?

谢谢!

1 个答案:

答案 0 :(得分:6)

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, ... ));   
}

它会起作用。

对于问题的第二部分(与输入的行/列号相关):是的,可以使用词法分析器跟踪输入位置。不过,这不是微不足道的。您需要创建自己的令牌类型,该类型存储行/列信息并使用此类型而不是预定义的令牌类型。许多人一直在要求这样做,所以我可以继续创建一个例子。