Opened 6 years ago

Closed 6 months 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:


if #define BOOST_SPIRIT_USE_PHOENIX_V3 1 this code can't be compile error


#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>
		: 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;

			=   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[])
		lex::lexertl::token<char const*, lex::omit, boost::mpl::false_> 

	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\
		Have you the plane tickets for there and back?\n\
		I do, I do.  We're all ready to go.  Grab my hand and be my beau.\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))

	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;

Attachments (0)

Change History (3)

comment:1 Changed 6 years ago by anonymous

the compiler is vc10

comment:2 Changed 7 months ago by Nikita Kniazev <nok.raven@…>

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 Changed 6 months ago by Joel de Guzman

Resolution: fixed
Status: newclosed

Modify Ticket

Change Properties
Set your email in Preferences
as closed The owner will remain Joel de Guzman.
The resolution will be deleted.

Add Comment

E-mail address and name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.