|
Boost Users : |
From: Markus Werle (numerical.simulation_at_[hidden])
Date: 2008-08-25 10:32:08
> [gmane anti-top-poster-complaint-header]
Hi!
[OK, Joel, it's not as trivial as I thought. Show me the way, master]
Below is my first toy implementation of string_to_list_of_tuples for
tr1::tuple. Unfortunately this code only parses the text, but does not store
the data. Any idea how to add the correct semantic actions in a pure and
elegant way?
Markus
---snip---
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#define BOOST_SPIRIT_DEBUG
// #include "Enforce.h"
#include <iostream>
#include <iterator>
#include <boost/tr1/tuple.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/at.hpp>
#include <boost/spirit/include/classic_spirit.hpp>
#include <list>
#include <string>
namespace sp = boost::spirit::classic;
namespace fusion = boost::fusion;
namespace mpl = boost::mpl;
namespace
{
struct parser_traits
{
template <typename T, int Dummy = 0> struct parser;
#define PARSER_TRAITS(TYPE, PARSER_T) \
template <int Dummy> struct parser<TYPE, Dummy> \
{ \
typedef PARSER_T type; \
\
static inline \
PARSER_T p() \
{ \
PARSER_T result; \
return result; \
} \
}
PARSER_TRAITS(int, sp::int_parser<int>);
PARSER_TRAITS(unsigned int, sp::uint_parser<unsigned>);
typedef sp::real_parser
<double, sp::ureal_parser_policies<double> > real_parser_t;
PARSER_TRAITS(float, real_parser_t);
PARSER_TRAITS(double, real_parser_t);
template <int Dummy> struct parser<std::string, Dummy>
{
typedef sp::contiguous
<sp::confix_parser
<sp::strlit<const char*>,
sp::kleene_star
<sp::anychar_parser>,
sp::strlit<const char*>,
sp::unary_parser_category,
sp::non_nested,
sp::non_lexeme> > parser_t;
static inline
parser_t p()
{
using namespace phoenix;
parser_t result = sp::lexeme_d[sp::confix_p("\"" ,
(*sp::anychar_p) , "\"")];
return result;
}
static inline
sp::strlit<char const *> comma()
{
sp::strlit<char const *> str_p(",");
return str_p;
}
};
};
template <typename Tuple, long I>
struct
rule_generator_helper
{
typedef typename std::tr1::tuple_element<I, Tuple>::type element_type;
typedef typename parser_traits::parser<element_type> pt_type;
typedef typename rule_generator_helper<Tuple, (I-1)>::type element_1_t;
typedef typename
sp::sequence<sp::sequence<element_1_t, sp::chlit<char> >, typename
pt_type::type> type;
static
type
apply()
{
return
rule_generator_helper<Tuple, (I-1)>::apply()
>> sp::ch_p(',')
>> pt_type::p()
;
}
};
template <typename Tuple>
struct
rule_generator_helper<Tuple, 0L>
{
typedef typename std::tr1::tuple_element<0, Tuple>::type element_type;
typedef typename parser_traits::parser<element_type> pt_type;
typedef typename pt_type::type type;
static
type
apply()
{
return pt_type::p();
}
};
template <typename Tuple>
struct
rule_generator
{
typedef std::tr1::tuple_size<Tuple> tuple_size;
BOOST_MPL_ASSERT_RELATION(tuple_size::value, >, 0);
typedef
rule_generator_helper<Tuple, (tuple_size::value - 1)> helper_t;
static
inline
typename helper_t::type
apply()
{
return helper_t::apply();
}
};
template <typename Tuple>
struct
string_to_list_of_tuples
{
static
std::list<Tuple>
apply(std::string const & s)
{
std::list<Tuple> result;
typedef sp::rule<sp::phrase_scanner_t> rule_t;
rule_t rule_tuple_rep =
'(' >> rule_generator<Tuple>::apply() >> ')';
rule_t rule_tuple_list =
*(rule_tuple_rep)
>> sp::end_p // for trailing whitespace
;
BOOST_SPIRIT_DEBUG_RULE(rule_tuple_rep);
BOOST_SPIRIT_DEBUG_RULE(rule_tuple_list);
sp::parse_info<> info;
try
{
info = sp::parse(s.c_str(), rule_tuple_list, sp::space_p);
}
catch (std::exception const & e)
{
std::cerr << e.what() << std::endl;
}
// ENFORCE(info.full)
// ("Failed to generate a list of tuples from ")
// ("string representation\n'")
// (s)("'\n");
return result;
}
};
} // namespace
int main()
{
try
{
{
typedef std::tr1::tuple<int, int> tuple_t;
std::list<tuple_t> test =
string_to_list_of_tuples<tuple_t>::apply(" ( 1, 2 ) ( 3, 4)
(5,6)");
std::copy(test.begin(), test.end(),
std::ostream_iterator<tuple_t>(std::cout, "\n"));
}
{
typedef std::tr1::tuple<unsigned int, int, double> tuple_t;
std::list<tuple_t> test =
string_to_list_of_tuples<tuple_t>::apply
(" ( 1, -2 , 5.123) ( 3, 4,7.9)(5,6,8.6789)");
std::copy(test.begin(), test.end(),
std::ostream_iterator<tuple_t>(std::cout, "\n"));
}
}
catch (std::exception const & e)
{
std::cerr << e.what() << std::endl;
}
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net