#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
namespace lex = boost::spirit::lex;
namespace qi = boost::spirit::qi;
namespace mpl = boost::mpl;
struct rational
{
rational(int n = 0, int d = 0)
: nominator_(n), denominator_(d)
{}
int nominator_;
int denominator_;
};
namespace boost { namespace spirit { namespace traits
{
template <typename Iterator>
struct assign_to_attribute_from_iterators<rational, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, rational& attr)
{
int x, y;
Iterator b = first;
qi::parse(b, last,
'{' >> qi::int_ >> ',' >> qi::int_ >> '}', x, y);
attr = rational(x, y);
}
};
}}}
template <typename Lexer>
struct lex_rational : lex::lexer<Lexer>
{
lex_rational()
{
this->self.add_pattern("INT", "[1-9][0-9]*");
rt = "\\{{INT},{INT}\\}";
this->self.add(rt);
}
lex::token_def<rational> rt;
};
int main()
{
typedef lex::lexertl::token<std::string::iterator,
mpl::vector<rational> > token_type;
typedef lex::lexertl::lexer<token_type> lexer_type;
typedef lexer_type::iterator_type iterator_type;
std::string input("{3,4}");
std::string::iterator s = input.begin();
lex_rational<lexer_type> lex;
iterator_type b = lex.begin(s, input.end());
rational r;
if (!qi::parse(b, lex.end(), lex.rt, r))
{
std::cerr << "Parsing failed!" << std::endl;
return -1;
}
std::cout << "Parsing succeeded: {"
<< r.nominator_ << ", " << r.denominator_ << "}" << std::endl;
return 0;
}