【发布时间】:2014-05-17 10:01:21
【问题描述】:
我想使用 Boost.Spirit.Lex 来 lex 一个二进制文件;为此,我编写了以下程序(这是摘录):
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <fstream>
#include <iterator>
#include <string>
namespace spirit = boost::spirit;
namespace lex = spirit::lex;
#define X 1
#define Y 2
#define Z 3
template<typename L>
class word_count_tokens : public lex::lexer<L>
{
public:
word_count_tokens () {
this->self.add
("[^ \t\n]+", X)
("\n", Y)
(".", Z);
}
};
class counter
{
public:
typedef bool result_type;
template<typename T>
bool operator () (const T &t, size_t &c, size_t &w, size_t &l) const {
switch (t.id ()) {
case X:
++w; c += t.value ().size ();
break;
case Y:
++l; ++c;
break;
case Z:
++c;
break;
}
return true;
}
};
int main (int argc, char **argv)
{
std::ifstream ifs (argv[1], std::ios::in | std::ios::binary);
auto first = spirit::make_default_multi_pass (std::istream_iterator<char> (ifs));
auto last = spirit::make_default_multi_pass (std::istream_iterator<char> ());
size_t w, c, l;
word_count_tokens<lex::lexertl::lexer<>> word_count_functor;
w = c = l = 0;
bool r = lex::tokenize (first, last, word_count_functor, boost::bind (counter (), _1, boost::ref (c), boost::ref (w), boost::ref (l)));
ifs.close ();
if (r) {
std::cout << l << ", " << w << ", " << c << std::endl;
}
return 0;
}
构建返回以下错误:
lexer.hpp:390:46: error: non-const lvalue reference to type 'const char *' cannot bind to a value of unrelated type
现在,错误是由于具体词法分析器lex::lexer<>的定义造成的;事实上,它的第一个参数默认为const char *。如果我使用spirit::istream_iterator 或spirit::make_default_multi_pass (.....),也会出现同样的错误。
但是,如果我指定lex::lexer<> 的正确模板参数,我会得到大量错误!
解决方案?
更新
我已经把所有的源文件;这是 word_counter 网站的例子。
【问题讨论】:
-
当然,
first和last的确切类型很重要。很多。 -
我已经修复了您修改后问题的代码。如果你发布一个新问题,我会解释修复方法。
-
我的问题很简单,如果我的英语不是很清楚请见谅! :-( 现在,如果我想使用类似于Boost.Spirit.Lex 的示例但使用
istream_iterator而不是const char *,则该示例不会编译报告指定的错误。在我的更新中,我输入了我的实际代码。 -
我看到了你的更新。我的意思是让您发布一个新问题,因为您更新的问题会使现有答案无效。没关系,我刚刚posted a new answer。
标签: c++ c++11 boost boost-spirit