Boost logo

Boost Users :

From: Markus Werle (numerical.simulation_at_[hidden])
Date: 2008-08-27 09:16:50


>

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 <boost/tr1/functional.hpp>
#include <boost/tr1/tuple.hpp>

#include <boost/mpl/assert.hpp>
#include <boost/mpl/at.hpp>

#include <boost/config/warning_disable.hpp>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_container.hpp>

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/foreach.hpp>

#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>

#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 <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; \
        } \
    }

    // int
    PARSER_TRAITS(int, int_type);

    // unsigned int
    PARSER_TRAITS(unsigned int, uint_type);

    // double
    PARSER_TRAITS(double, double_type);
};

////////////////////////////////////////////////////////////////////////////////
// parser

template <typename Iterator, typename Tuple> struct tuple_grammar;

template <typename Iterator, typename T1, typename T2>
struct
tuple_grammar<Iterator, std::tr1::tuple<T1, T2> >
: grammar<Iterator,
          std::list<std::tr1::tuple<T1, T2> >(),
          space_type>
{
    typename parser_traits::parser<T1>::type p1;
    typename parser_traits::parser<T2>::type p2;

    typedef typename std::tr1::tuple<T1, T2> 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<Iterator, tuple_t(), space_type> rule_tuple;
    rule<Iterator, std::list<tuple_t>(), space_type> rule_tuple_list;
};

////////////////////////////////////////////////////////////////////////////////
// string_to_list_of_tuples

template <typename Tuple> struct string_to_list_of_tuples;

template <typename T1, typename T2>
struct
string_to_list_of_tuples<std::tr1::tuple<T1, T2> >
{
    typedef std::tr1::tuple<T1, T2> tuple_t;

    static
    std::list<tuple_t>
    apply(std::string const & s)
    {
        std::list<tuple_t> result;
        
        typedef tuple_grammar<std::string::const_iterator, tuple_t>
            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<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