$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r60884 - in trunk/libs/spirit/example/scheme: . detail input output
From: hartmut.kaiser_at_[hidden]
Date: 2010-03-27 22:04:32
Author: hkaiser
Date: 2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
New Revision: 60884
URL: http://svn.boost.org/trac/boost/changeset/60884
Log:
Spirit: added Karma generator for outputting arbitrary sexpr
Added:
   trunk/libs/spirit/example/scheme/detail/utree_detail3.hpp   (contents, props changed)
   trunk/libs/spirit/example/scheme/input/
   trunk/libs/spirit/example/scheme/input/sexpr.hpp   (contents, props changed)
   trunk/libs/spirit/example/scheme/output/
   trunk/libs/spirit/example/scheme/output/sexpr.hpp   (contents, props changed)
   trunk/libs/spirit/example/scheme/sexpr_output_test.cpp   (contents, props changed)
Removed:
   trunk/libs/spirit/example/scheme/sexpr.hpp
Text files modified: 
   trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp |     2 ++                                      
   trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp |     5 +++++                                   
   trunk/libs/spirit/example/scheme/sexpr_test.cpp           |     4 +++-                                    
   trunk/libs/spirit/example/scheme/utree.hpp                |     3 +++                                     
   trunk/libs/spirit/example/scheme/utree_test.cpp           |     2 ++                                      
   5 files changed, 15 insertions(+), 1 deletions(-)
Modified: trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp	(original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
@@ -19,6 +19,8 @@
     template <typename UTreeX, typename UTreeY>
     struct visit_impl;
     struct index_impl;
+    template <typename T>
+    struct get_impl;
 
     ///////////////////////////////////////////////////////////////////////////
     // Our POD double linked list. Straightforward implementation.
Modified: trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp	(original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
@@ -997,6 +997,11 @@
         return 0;
     }
 
+    inline int utree::which() const
+    {
+        return get_type();
+    }
+
     inline utree& utree::front()
     {
         if (get_type() == type::reference_type)
Added: trunk/libs/spirit/example/scheme/detail/utree_detail3.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail3.hpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,132 @@
+/*=============================================================================
+    Copyright (c) 2001-2010 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_UTREE_DETAIL3)
+#define BOOST_SPIRIT_UTREE_DETAIL3
+
+#include <boost/variant/get.hpp>    // boost::bad_get
+
+namespace scheme 
+{ 
+    namespace detail
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename T>
+        struct get_utree_type;
+
+#define SCHEME_GET_UTREE_TYPE(t, v)                                           \
+    template <> struct get_utree_type<t> { enum { value = v }; }              \
+    /**/
+
+        SCHEME_GET_UTREE_TYPE(nil, utree_type::nil_type);
+        SCHEME_GET_UTREE_TYPE(bool, utree_type::bool_type);
+        SCHEME_GET_UTREE_TYPE(int, utree_type::int_type);
+        SCHEME_GET_UTREE_TYPE(double, utree_type::double_type);
+        SCHEME_GET_UTREE_TYPE(utf8_string_range, utree_type::string_type);
+        SCHEME_GET_UTREE_TYPE(utf8_symbol_range, utree_type::symbol_type);
+        SCHEME_GET_UTREE_TYPE(binary_range, utree_type::binary_type);
+        SCHEME_GET_UTREE_TYPE(boost::iterator_range<utree::iterator>, 
+            utree_type::list_type);
+        SCHEME_GET_UTREE_TYPE(boost::iterator_range<utree::const_iterator>, 
+            utree_type::list_type);
+
+#undef SCHEME_GET_UTREE_TYPE
+
+        ///////////////////////////////////////////////////////////////////////
+        template <typename T>
+        struct get_impl;
+
+        template <>
+        struct get_impl<nil>
+        {
+            typedef nil type;
+            static type call(utree const&) { return nil(); }
+        };
+
+        template <>
+        struct get_impl<bool>
+        {
+            typedef bool type;
+            static type call(utree const& x) { return x.b; }
+        };
+
+        template <>
+        struct get_impl<int>
+        {
+            typedef int type;
+            static type call(utree const& x) { return x.i; }
+        };
+
+        template <>
+        struct get_impl<double>
+        {
+            typedef double type;
+            static type call(utree const& x) { return x.d; }
+        };
+
+        template <>
+        struct get_impl<boost::iterator_range<utree::iterator> >
+        {
+            typedef boost::iterator_range<utree::iterator> type;
+            static type call(utree const& x) 
+            { 
+                return type(utree::iterator(x.l.first), utree::iterator(0)); 
+            }
+        };
+
+        template <>
+        struct get_impl<boost::iterator_range<utree::const_iterator> >
+        {
+            typedef boost::iterator_range<utree::const_iterator> type;
+            static type call(utree const& x) 
+            { 
+                return type(utree::const_iterator(x.l.first), utree::const_iterator(0)); 
+            }
+        };
+
+        template <>
+        struct get_impl<utf8_string_range>
+        {
+            typedef utf8_string_range type;
+            static type call(utree const& x) 
+            { 
+                return type(x.s.str(), x.s.size()); 
+            }
+        };
+
+        template <>
+        struct get_impl<utf8_symbol_range>
+        {
+            typedef utf8_symbol_range type;
+            static type call(utree const& x) 
+            { 
+                return type(x.s.str(), x.s.size()); 
+            }
+        };
+
+        template <>
+        struct get_impl<binary_range>
+        {
+            typedef binary_range type;
+            static type call(utree const& x) 
+            { 
+                return type(x.s.str(), x.s.size()); 
+            }
+        };
+    }
+
+    template <typename T>
+    typename detail::get_impl<T>::type 
+    get(utree const& x)
+    {
+        if (x.which() != detail::get_utree_type<T>::value)
+            throw boost::bad_get();
+
+        return detail::get_impl<T>::call(x);
+    }
+}
+
+#endif
Added: trunk/libs/spirit/example/scheme/input/sexpr.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/input/sexpr.hpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,166 @@
+/*=============================================================================
+    Copyright (c) 2001-2010 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_SEXPR)
+#define BOOST_SPIRIT_SEXPR
+
+#include <string>
+
+#include <boost/cstdint.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_container.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/regex/pending/unicode_iterator.hpp>
+
+#include "utree.hpp"
+
+namespace scheme { namespace input
+{
+    using boost::spirit::ascii::char_;
+    using boost::spirit::ascii::space;
+    using boost::spirit::qi::grammar;
+    using boost::spirit::qi::rule;
+    using boost::spirit::qi::eol;
+    using boost::spirit::qi::_val;
+    using boost::spirit::qi::_r1;
+    using boost::spirit::qi::_1;
+    using boost::spirit::qi::uint_parser;
+    using boost::spirit::qi::real_parser;
+    using boost::spirit::qi::strict_real_policies;
+    using boost::spirit::qi::char_set;
+    using boost::spirit::qi::int_;
+    using boost::spirit::qi::hex;
+    using boost::spirit::qi::oct;
+    using boost::spirit::qi::bool_;
+    using boost::spirit::qi::no_case;
+    using boost::spirit::qi::lexeme;
+    using boost::spirit::qi::lit;
+    using boost::phoenix::function;
+
+    typedef boost::uint32_t uchar; // a unicode code point
+
+    template <typename Iterator>
+    struct white_space : grammar<Iterator>
+    {
+        white_space() : white_space::base_type(start)
+        {
+            start =
+                    space                           // tab/space/cr/lf
+                |   ';' >> *(char_ - eol) >> eol    // comments
+                ;
+        }
+
+        rule<Iterator> start;
+    };
+
+    namespace detail
+    {
+        struct push_utf8
+        {
+            template <typename S, typename C>
+            struct result { typedef void type; };
+
+            void operator()(std::string& utf8, uchar code_point) const
+            {
+                typedef std::back_insert_iterator<std::string> insert_iter;
+                insert_iter out_iter(utf8);
+                boost::utf8_output_iterator<insert_iter> utf8_iter(out_iter);
+                *utf8_iter++ = code_point;
+            }
+        };
+
+        struct push_esc
+        {
+            template <typename S, typename C>
+            struct result { typedef void type; };
+
+            void operator()(std::string& utf8, uchar c) const
+            {
+                switch (c)
+                {
+                    case 'b': utf8 += '\b';     break;
+                    case 't': utf8 += '\t';     break;
+                    case 'n': utf8 += '\n';     break;
+                    case 'f': utf8 += '\f';     break;
+                    case 'r': utf8 += '\r';     break;
+                    case '"': utf8 += '"';      break;
+                    case '\\': utf8 += '\\';    break;
+                }
+            }
+        };
+    }
+
+    template <typename Iterator>
+    struct string : grammar<Iterator, std::string()>
+    {
+        string() : string::base_type(start)
+        {
+            uint_parser<uchar, 16, 4, 4> hex4;
+            uint_parser<uchar, 16, 8, 8> hex8;
+            function<detail::push_utf8> push_utf8;
+            function<detail::push_esc> push_esc;
+
+            str_esc
+                =  '\\'
+                >>  (   ('u' >> hex4)               [push_utf8(_r1, _1)]
+                    |   ('U' >> hex8)               [push_utf8(_r1, _1)]
+                    |   char_("btnfr\\\"'")         [push_esc(_r1, _1)]
+                    )
+                ;
+
+            start
+                = '"'
+                >> *(str_esc(_val) | (~char_('"'))  [_val += _1])
+                >> '"'
+                ;
+        }
+
+        rule<Iterator, void(std::string&)> str_esc;
+        rule<Iterator, std::string()> start;
+    };
+
+    template <typename Iterator>
+    struct sexpr : grammar<Iterator, white_space<Iterator>, utree()>
+    {
+        sexpr() : sexpr::base_type(start)
+        {
+            real_parser<double, strict_real_policies<double> > strict_double;
+            uint_parser<unsigned char, 16, 2, 2> hex2;
+
+            start   = atom | list;
+
+            list    = '(' >> *start >> ')';
+
+            atom    = number                            [_val = _1]
+                    | bool_                             [_val = _1]
+                    | string                            [_val = _1]
+                    | byte_str                          [_val = _1]
+                    | symbol                            [_val = _1]
+                    ;
+
+            char const* exclude = " ();\"\0-\31\127";
+            symbol  = lexeme[+(~char_(exclude))];
+
+            number  = strict_double                     [_val = _1]
+                    | lexeme[no_case["0x"] >> hex]      [_val = _1]
+                    | lexeme['0' >> oct]                [_val = _1]
+                    | int_                              [_val = _1]
+                    ;
+
+            byte_str = lexeme[no_case['b'] >> +hex2];
+        }
+
+        rule<Iterator, white_space<Iterator>, utree()> start, list;
+        rule<Iterator, utree()> atom, number;
+        rule<Iterator, utf8_symbol()> symbol;
+        rule<Iterator, binary_string()> byte_str;
+        scheme::input::string<Iterator> string;
+    };
+}}
+
+#endif
Added: trunk/libs/spirit/example/scheme/output/sexpr.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/output/sexpr.hpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,185 @@
+//  Copyright (c) 2001-2010 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SCHEME_OUTPUT_SEXPR_MAR_8_2010_829AM)
+#define SCHEME_OUTPUT_SEXPR_MAR_8_2010_829AM
+
+#include <string>
+
+#include <boost/cstdint.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/spirit/include/karma.hpp>
+
+#include "utree.hpp"
+#include "detail/utree_detail3.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+    // the specialization below tells Spirit to handle scheme::utree as if it 
+    // where a 'real' variant
+    template <typename T>
+    struct not_is_variant;
+
+    template <>
+    struct not_is_variant<scheme::utree>
+      : mpl::false_ {};
+
+    // The specializations below tell Spirit to verify whether an attribute 
+    // type is compatible with a given variant type
+    template <>
+    struct compute_compatible_component_variant<
+            boost::iterator_range<scheme::utree::iterator>, scheme::utree>
+      : mpl::true_
+    {
+        typedef boost::iterator_range<scheme::utree::iterator> compatible_type;
+        typedef mpl::int_<scheme::utree_type::list_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<
+            boost::iterator_range<scheme::utree::const_iterator>, scheme::utree>
+      : mpl::true_
+    {
+        typedef boost::iterator_range<scheme::utree::const_iterator> compatible_type;
+        typedef mpl::int_<scheme::utree_type::list_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<scheme::nil, scheme::utree>
+      : mpl::true_
+    {
+        typedef scheme::nil compatible_type;
+        typedef mpl::int_<scheme::utree_type::nil_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<bool, scheme::utree>
+      : mpl::true_
+    {
+        typedef bool compatible_type;
+        typedef mpl::int_<scheme::utree_type::bool_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<int, scheme::utree>
+      : mpl::true_
+    {
+        typedef int compatible_type;
+        typedef mpl::int_<scheme::utree_type::int_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<double, scheme::utree>
+      : mpl::true_
+    {
+        typedef double compatible_type;
+        typedef mpl::int_<scheme::utree_type::double_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<
+            scheme::utf8_string_range, scheme::utree>
+      : mpl::true_
+    {
+        typedef scheme::utf8_string_range compatible_type;
+        typedef mpl::int_<scheme::utree_type::string_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<
+            scheme::utf8_string, scheme::utree>
+      : mpl::true_
+    {
+        typedef scheme::utf8_string compatible_type;
+        typedef mpl::int_<scheme::utree_type::string_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<
+            scheme::utf8_symbol_range, scheme::utree>
+      : mpl::true_
+    {
+        typedef scheme::utf8_symbol_range compatible_type;
+        typedef mpl::int_<scheme::utree_type::symbol_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<
+            scheme::utf8_symbol, scheme::utree>
+      : mpl::true_
+    {
+        typedef scheme::utf8_symbol compatible_type;
+        typedef mpl::int_<scheme::utree_type::symbol_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<
+            scheme::binary_range, scheme::utree>
+      : mpl::true_
+    {
+        typedef scheme::binary_range compatible_type;
+        typedef mpl::int_<scheme::utree_type::binary_type> distance;
+    };
+
+    template <>
+    struct compute_compatible_component_variant<
+            scheme::binary_string, scheme::utree>
+      : mpl::true_
+    {
+        typedef scheme::binary_string compatible_type;
+        typedef mpl::int_<scheme::utree_type::binary_type> distance;
+    };
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace scheme { namespace output
+{
+    using boost::spirit::karma::grammar;
+    using boost::spirit::karma::space_type;
+    using boost::spirit::karma::rule;
+    using boost::spirit::karma::double_;
+    using boost::spirit::karma::int_;
+    using boost::spirit::karma::char_;
+    using boost::spirit::karma::bool_;
+    using boost::spirit::karma::space_type;
+    using boost::spirit::karma::uint_generator;
+
+    typedef boost::uint32_t uchar; // a unicode code point
+
+    template <typename OutputIterator>
+    struct sexpr : grammar<OutputIterator, space_type, utree()>
+    {
+        sexpr() : sexpr::base_type(start)
+        {
+            uint_generator<unsigned char, 16> hex2;
+
+            start     = double_
+                      | int_
+                      | bool_
+                      | string
+                      | symbol
+                      | byte_str
+                      | list
+                      ;
+
+            list      = '(' << *start << ')';
+
+            string    = '"' << *char_ << '"';
+            symbol    = *char_;
+            byte_str  = 'b' << *hex2;
+        }
+
+        typedef boost::iterator_range<utree::const_iterator> utree_list;
+
+        rule<OutputIterator, space_type, utree()> start;
+        rule<OutputIterator, space_type, utree_list()> list;
+        rule<OutputIterator, utf8_symbol_range()> symbol;
+        rule<OutputIterator, utf8_string_range()> string;
+        rule<OutputIterator, binary_range()> byte_str;
+    };
+}}
+
+#endif
Deleted: trunk/libs/spirit/example/scheme/sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/sexpr.hpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
+++ (empty file)
@@ -1,167 +0,0 @@
-/*=============================================================================
-    Copyright (c) 2001-2010 Joel de Guzman
-
-    Distributed under the Boost Software License, Version 1.0. (See accompanying
-    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(BOOST_SPIRIT_SEXPR)
-#define BOOST_SPIRIT_SEXPR
-
-#include <string>
-
-#include <boost/config/warning_disable.hpp>
-#include <boost/cstdint.hpp>
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_container.hpp>
-#include <boost/spirit/include/phoenix_statement.hpp>
-#include <boost/spirit/include/phoenix_operator.hpp>
-#include <boost/regex/pending/unicode_iterator.hpp>
-
-#include "utree.hpp"
-
-namespace scheme { namespace input
-{
-    using boost::spirit::ascii::char_;
-    using boost::spirit::ascii::space;
-    using boost::spirit::qi::grammar;
-    using boost::spirit::qi::rule;
-    using boost::spirit::qi::eol;
-    using boost::spirit::qi::_val;
-    using boost::spirit::qi::_r1;
-    using boost::spirit::qi::_1;
-    using boost::spirit::qi::uint_parser;
-    using boost::spirit::qi::real_parser;
-    using boost::spirit::qi::strict_real_policies;
-    using boost::spirit::qi::char_set;
-    using boost::spirit::qi::int_;
-    using boost::spirit::qi::hex;
-    using boost::spirit::qi::oct;
-    using boost::spirit::qi::bool_;
-    using boost::spirit::qi::no_case;
-    using boost::spirit::qi::lexeme;
-    using boost::spirit::qi::lit;
-    using boost::phoenix::function;
-
-    typedef boost::uint32_t uchar; // a unicode code point
-
-    template <typename Iterator>
-    struct white_space : grammar<Iterator>
-    {
-        white_space() : white_space::base_type(start)
-        {
-            start =
-                    space                           // tab/space/cr/lf
-                |   ';' >> *(char_ - eol) >> eol    // comments
-                ;
-        }
-
-        rule<Iterator> start;
-    };
-
-    namespace detail
-    {
-        struct push_utf8
-        {
-            template <typename S, typename C>
-            struct result { typedef void type; };
-
-            void operator()(std::string& utf8, uchar code_point) const
-            {
-                typedef std::back_insert_iterator<std::string> insert_iter;
-                insert_iter out_iter(utf8);
-                boost::utf8_output_iterator<insert_iter> utf8_iter(out_iter);
-                *utf8_iter++ = code_point;
-            }
-        };
-
-        struct push_esc
-        {
-            template <typename S, typename C>
-            struct result { typedef void type; };
-
-            void operator()(std::string& utf8, uchar c) const
-            {
-                switch (c)
-                {
-                    case 'b': utf8 += '\b';     break;
-                    case 't': utf8 += '\t';     break;
-                    case 'n': utf8 += '\n';     break;
-                    case 'f': utf8 += '\f';     break;
-                    case 'r': utf8 += '\r';     break;
-                    case '"': utf8 += '"';      break;
-                    case '\\': utf8 += '\\';    break;
-                }
-            }
-        };
-    }
-
-    template <typename Iterator>
-    struct string : grammar<Iterator, std::string()>
-    {
-        string() : string::base_type(start)
-        {
-            uint_parser<uchar, 16, 4, 4> hex4;
-            uint_parser<uchar, 16, 8, 8> hex8;
-            function<detail::push_utf8> push_utf8;
-            function<detail::push_esc> push_esc;
-
-            str_esc
-                =  '\\'
-                >>  (   ('u' >> hex4)               [push_utf8(_r1, _1)]
-                    |   ('U' >> hex8)               [push_utf8(_r1, _1)]
-                    |   char_("btnfr\\\"'")         [push_esc(_r1, _1)]
-                    )
-                ;
-
-            start
-                = '"'
-                >> *(str_esc(_val) | (~char_('"'))  [_val += _1])
-                >> '"'
-                ;
-        }
-
-        rule<Iterator, void(std::string&)> str_esc;
-        rule<Iterator, std::string()> start;
-    };
-
-    template <typename Iterator>
-    struct sexpr : grammar<Iterator, white_space<Iterator>, utree()>
-    {
-        sexpr() : sexpr::base_type(start)
-        {
-            real_parser<double, strict_real_policies<double> > strict_double;
-            uint_parser<unsigned char, 16, 2, 2> hex2;
-
-            start   = atom | list;
-
-            list    = '(' >> *start >> ')';
-
-            atom    = number                            [_val = _1]
-                    | bool_                             [_val = _1]
-                    | string                            [_val = _1]
-                    | byte_str                          [_val = _1]
-                    | symbol                            [_val = _1]
-                    ;
-
-            char const* exclude = " ();\"\0-\31\127";
-            symbol  = lexeme[+(~char_(exclude))];
-
-            number  = strict_double                     [_val = _1]
-                    | lexeme[no_case["0x"] >> hex]      [_val = _1]
-                    | lexeme['0' >> oct]                [_val = _1]
-                    | int_                              [_val = _1]
-                    ;
-
-            byte_str = lexeme[no_case['b'] >> +hex2];
-        }
-
-        rule<Iterator, white_space<Iterator>, utree()> start, list;
-        rule<Iterator, utree()> atom, number;
-        rule<Iterator, utf8_symbol()> symbol;
-        rule<Iterator, binary_string()> byte_str;
-        scheme::input::string<Iterator> string;
-    };
-}}
-
-#endif
Added: trunk/libs/spirit/example/scheme/sexpr_output_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/sexpr_output_test.cpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,131 @@
+//  Copyright (c) 2001-2010 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/config/warning_disable.hpp>
+
+#define BOOST_SPIRIT_UNICODE
+
+#include <iostream>
+#include <fstream>
+#include <iterator>
+
+#include "input/sexpr.hpp"
+#include "output/sexpr.hpp"
+
+namespace client
+{
+    bool parse_sexpr_from_file(char const* filename, scheme::utree& result)
+    {
+        std::ifstream in(filename, std::ios_base::in);
+
+        if (!in)
+        {
+            std::cerr << "Error: Could not open input file: "
+                << filename << std::endl;
+            exit(-1);
+        }
+
+        // Ignore the BOM marking the beginning of a UTF-8 file in Windows
+        char c = in.peek();
+        if (c == '\xef')
+        {
+            char s[3];
+            in >> s[0] >> s[1] >> s[2];
+            s[3] = '\0';
+            if (s != std::string("\xef\xbb\xbf"))
+            {
+                std::cerr << "Error: Unexpected characters from input file: "
+                    << filename << std::endl;
+                exit(-1);
+            }
+        }
+
+        std::string source_code;      // We will read the contents here.
+        in.unsetf(std::ios::skipws);  // No white space skipping!
+        std::copy(
+            std::istream_iterator<char>(in),
+            std::istream_iterator<char>(),
+            std::back_inserter(source_code));
+
+        typedef std::string::const_iterator iterator_type;
+        iterator_type first(source_code.begin());
+        iterator_type last(source_code.end());
+
+        scheme::input::sexpr<iterator_type> p;
+        scheme::input::white_space<iterator_type> ws;
+
+        return phrase_parse(first, last, p, ws, result);
+    }
+
+    bool generate_sexpr_to_file(scheme::utree const& tree, char const* filename)
+    {
+        std::ofstream out(filename);
+
+        if (!out)
+        {
+            std::cerr << "Error: Could not open output file: "
+                << filename << std::endl;
+            exit(-1);
+        }
+
+        typedef std::back_insert_iterator<std::string> output_iterator_type;
+        using boost::spirit::karma::space;
+
+        std::string output;
+        output_iterator_type sink(output);
+        scheme::output::sexpr<output_iterator_type> g;
+        if (!generate_delimited(sink, g, space, tree))
+        {
+            return false;
+        }
+
+        out << output;
+        return true;
+    }
+}
+
+int main(int argc, char **argv)
+{
+    char const* filename_in;
+    if (argc > 1)
+    {
+        filename_in = argv[1];
+    }
+    else
+    {
+        std::cerr << "Error: No input file provided." << std::endl;
+        return -1;
+    }
+
+    char const* filename_out;
+    if (argc > 2)
+    {
+        filename_out = argv[2];
+    }
+    else
+    {
+        std::cerr << "Error: No output file provided." << std::endl;
+        return -1;
+    }
+
+    scheme::utree result;
+    if (client::parse_sexpr_from_file(filename_in, result))
+    {
+        if (client::generate_sexpr_to_file(result, filename_out))
+        {
+            std::cout << "success!" << std::endl;
+        }
+        else
+        { 
+            std::cout << "generate error" << std::endl;
+        }
+    }
+    else
+    {
+        std::cout << "parse error" << std::endl;
+    }
+
+    return 0;
+}
Modified: trunk/libs/spirit/example/scheme/sexpr_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/sexpr_test.cpp	(original)
+++ trunk/libs/spirit/example/scheme/sexpr_test.cpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
@@ -4,7 +4,9 @@
     Distributed under the Boost Software License, Version 1.0. (See accompanying
     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
-#include "sexpr.hpp"
+#include <boost/config/warning_disable.hpp>
+
+#include "input/sexpr.hpp"
 #include "simple_print.hpp"
 #include <iostream>
 #include <fstream>
Modified: trunk/libs/spirit/example/scheme/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree.hpp	(original)
+++ trunk/libs/spirit/example/scheme/utree.hpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
@@ -249,6 +249,8 @@
         bool empty() const;
         std::size_t size() const;
 
+        int which() const;
+
     private:
 
         typedef utree_type type;
@@ -257,6 +259,7 @@
         friend struct detail::visit_impl;
         friend struct detail::index_impl;
         friend struct ulist;
+        template <typename T> friend struct detail::get_impl;
 
         type::info get_type() const;
         void set_type(type::info t);
Modified: trunk/libs/spirit/example/scheme/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree_test.cpp	(original)
+++ trunk/libs/spirit/example/scheme/utree_test.cpp	2010-03-27 22:04:31 EDT (Sat, 27 Mar 2010)
@@ -5,6 +5,8 @@
     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 
+#include <boost/config/warning_disable.hpp>
+
 #include "utree.hpp"
 #include "simple_print.hpp"
 #include <iostream>