[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
#include
#include
#include
#include <list>
#include <string>
namespace sp = boost::spirit::classic;
namespace fusion = boost::fusion;
namespace mpl = boost::mpl;
namespace
{
struct parser_traits
{
template struct parser;
#define PARSER_TRAITS(TYPE, PARSER_T) \
template <int Dummy> struct parser \
{ \
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
real_parser_t;
PARSER_TRAITS(float, real_parser_t);
PARSER_TRAITS(double, real_parser_t);
template <int Dummy> struct parser
{
typedef sp::contiguous
,
sp::kleene_star
sp::anychar_parser,
sp::strlit,
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 comma()
{
sp::strlit str_p(",");
return str_p;
}
};
};
template
struct
rule_generator_helper
{
typedef typename std::tr1::tuple_element::type element_type;
typedef typename parser_traits::parser pt_type;
typedef typename rule_generator_helper::type element_1_t;
typedef typename
sp::sequence, typename
pt_type::type> type;
static
type
apply()
{
return
rule_generator_helper::apply()
>> sp::ch_p(',')
>> pt_type::p()
;
}
};
template <typename Tuple>
struct
rule_generator_helper
{
typedef typename std::tr1::tuple_element<0, Tuple>::type element_type;
typedef typename parser_traits::parser 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 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::rulesp::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 tuple_t;
std::list test =
string_to_list_of_tuples::apply(" ( 1, 2 ) ( 3, 4)
(5,6)");
std::copy(test.begin(), test.end(),
std::ostream_iterator(std::cout, "\n"));
}
{
typedef std::tr1::tuple tuple_t;
std::list test =
string_to_list_of_tuples::apply
(" ( 1, -2 , 5.123) ( 3, 4,7.9)(5,6,8.6789)");
std::copy(test.begin(), test.end(),
std::ostream_iterator(std::cout, "\n"));
}
}
catch (std::exception const & e)
{
std::cerr << e.what() << std::endl;
}
}