Hi!
Though I appreciate simple examples in the docs it is indeed
helpful to have examples with fully qualified names.
I am having hard times figuring out which versions of "_1", "at_c", etc.
are in use. the fusion/phoenix/proto/mpl chaos is hard to keep track of.
In summary: using declaratives are nice for toy examples but drive
you nuts, once you #include more files and have ADL destroying the idyll
of simplicity.
Below is a piece of code that nearly compiles. One line has a problem:
A semantic action, namely a push_back fails under vc8 and the error
message is far from being helpful.
So could you please be so nice and give me some hint on how to fix this.
(BTW, Joel: "iter+30" directives from the spirit2 examples are
assert-catched by the VC8 debugging STL, so I changed that part
a little bit to first check the distance and doing iterator
arithmetics afterwards. See below.)
best regards,
Markus
---snip---
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#define BOOST_SPIRIT_DEBUG
#include "Enforce.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include <list>
#include <string>
#include <vector>
#include <iostream>
#include <iterator>
using namespace boost::spirit;
using namespace boost::spirit::qi;
using namespace boost::spirit::ascii;
using namespace boost::spirit::arg_names;
using boost::phoenix::push_back;
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
namespace
{
////////////////////////////////////////////////////////////////////////////////
// parser traits
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; \
} \
}
// int
PARSER_TRAITS(int, int_type);
// unsigned int
PARSER_TRAITS(unsigned int, uint_type);
// double
PARSER_TRAITS(double, double_type);
};
////////////////////////////////////////////////////////////////////////////////
// parser
template struct tuple_grammar;
template
struct
tuple_grammar >
: grammar >(),
space_type>
{
typename parser_traits::parser<T1>::type p1;
typename parser_traits::parser<T2>::type p2;
typedef typename std::tr1::tuple tuple_t;
tuple_grammar()
: tuple_grammar::base_type(rule_tuple_list)
{
using phoenix::at_c;
using boost::spirit::arg_names::_1;
// using boost::spirit::container::push_back;
using boost::phoenix::push_back;
rule_tuple =
'('
>> p1[at_c<0>(_val) = _1]
>> ','
>> p2[at_c<1>(_val) = _1]
>> ')'
;
rule_tuple_list =
// COMPILER FALS ON THIS SEMANTIC ACTION - WHY?
*(rule_tuple[push_back(ref(_val), _1)])
;
}
rule rule_tuple;
rule(), space_type> rule_tuple_list;
};
////////////////////////////////////////////////////////////////////////////////
// string_to_list_of_tuples
template <typename Tuple> struct string_to_list_of_tuples;
template
struct
string_to_list_of_tuples >
{
typedef std::tr1::tuple tuple_t;
static
std::list
apply(std::string const & s)
{
std::list result;
typedef tuple_grammar
tuple_grammar;
tuple_grammar tg;
std::string::const_iterator iter = s.begin();
std::string::const_iterator end = s.end();
bool r = phrase_parse(iter, end, tg, result, space);
if (r && iter == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << "-------------------------\n";
}
else
{
std::size_t dist = std::distance(iter, end);
std::string::const_iterator some = dist > 30 ? iter+30 : end;
std::string context(iter, some);
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "stopped at: \"" << context << "...\"\n";
std::cout << "-------------------------\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;
}
}