我想使用Boost.Spirit.Lex來解析二進制文件;爲此,我寫了下面的程序(這裏是摘錄):
使用Boost.Spirit.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」的確切類型確實很重要。很多。 – sehe
我已修復修改後的問題的代碼。如果你發佈了一個新問題,我會解釋這些問題。 – sehe
我的問題很簡單,對不起,如果我的英語不是很清楚! :-(現在,如果我想使用[Boost.Spirit.Lex](http://www.boost.org/doc/libs/1_55_0/libs/spirit/example/lex/word_count_functor.cpp)中的示例,但用'istream_iterator'而不是'const char *',這個例子沒有編譯報告指定的錯誤。在我的更新中,我放了我的實際代碼。 –