Opened 10 years ago
Closed 5 years ago
#6869 closed Bugs (fixed)
spirit lex use phoenixV3 compile error
| Reported by: | anonymous | Owned by: | Joel de Guzman |
|---|---|---|---|
| Milestone: | To Be Determined | Component: | spirit |
| Version: | Boost 1.49.0 | Severity: | Problem |
| Keywords: | spirit lex | Cc: |
Description
if #define BOOST_SPIRIT_USE_PHOENIX_V3 1 this code can't be compile error
// #define BOOST_SPIRIT_LEXERTL_DEBUG
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/spirit/include/phoenix_algorithm.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <iostream>
#include <fstream>
#include <string>
namespace lex = boost::spirit::lex;
struct distance_func
{
template <typename Iterator1, typename Iterator2>
struct result : boost::iterator_difference<Iterator1> {};
template <typename Iterator1, typename Iterator2>
typename result<Iterator1, Iterator2>::type
operator()(Iterator1& begin, Iterator2& end) const
{
return std::distance(begin, end);
}
};
boost::phoenix::function<distance_func> const distance1 = distance_func();
template <typename Lexer>
struct word_count_tokens : lex::lexer<Lexer>
{
word_count_tokens()
: c(0), w(0), l(0)
, word("[^ \t\n]+")
, eol("\n")
, any(".")
{
using boost::spirit::lex::_start;
using boost::spirit::lex::_end;
using boost::phoenix::ref;
this->self
= word [++ref(w), ref(c) += distance1(_start, _end)]
| eol [++ref(c), ++ref(l)]
| any [++ref(c)]
;
}
std::size_t c, w, l;
lex::token_def<> word, eol, any;
};
int main(int argc, char* argv[])
{
typedef
lex::lexertl::token<char const*, lex::omit, boost::mpl::false_>
token_type;
typedef lex::lexertl::actor_lexer<token_type> lexer_type;
word_count_tokens<lexer_type> word_count_lexer;
std::string str ("Our hiking boots are ready. So, let's pack!\n\
\n\
Have you the plane tickets for there and back?\n\
\n\
I do, I do. We're all ready to go. Grab my hand and be my beau.\n\
\n\
\n");
char const* first = str.c_str();
char const* last = &first[str.size()];
lexer_type::iterator_type iter = word_count_lexer.begin(first, last);
lexer_type::iterator_type end = word_count_lexer.end();
while (iter != end && token_is_valid(*iter))
++iter;
if (iter == end) {
std::cout << "lines: " << word_count_lexer.l
<< ", words: " << word_count_lexer.w
<< ", characters: " << word_count_lexer.c
<< "\n";
}
else {
std::string rest(first, last);
std::cout << "Lexical analysis failed\n" << "stopped at: \""
<< rest << "\"\n";
}
return 0;
}
Change History (3)
comment:1 by , 10 years ago
comment:2 by , 5 years ago
The Spirit examples wrongly uses result_of protocol. I am working on fixing examples, but it is still WIP. To fix your problem, you should fix distance_func like this:
struct distance_func { template <typename Sig> struct result; template <typename F, typename Iterator1, typename Iterator2> struct result<F(Iterator1 const&, Iterator2 const&)> : boost::iterator_difference<Iterator1> {}; template <typename F, typename Iterator1, typename Iterator2> struct result<F(Iterator1&, Iterator2&)> : result<F(Iterator1 const&, Iterator2 const&)> {}; template <typename Iterator1, typename Iterator2> typename result<distance_func(Iterator1&, Iterator2&)>::type operator()(Iterator1& begin, Iterator2& end) const { return std::distance(begin, end); } };
Or it could be a little simpler (std::distance requires both iterators to have the same type):
struct distance_func { template <typename> struct result; template <typename F, typename Iterator> struct result<F(Iterator, Iterator)> : boost::iterator_difference<typename boost::decay<Iterator>::type> {}; template <typename Iterator> typename result<distance_func(Iterator&, Iterator&)>::type operator()(Iterator& begin, Iterator& end) const { return std::distance(begin, end); } };
comment:3 by , 5 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Note:
See TracTickets
for help on using tickets.

the compiler is vc10