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