Boost logo

Boost-Commit :

From: hartmut.kaiser_at_[hidden]
Date: 2008-05-02 18:18:43


Author: hkaiser
Date: 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
New Revision: 45044
URL: http://svn.boost.org/trac/boost/changeset/45044

Log:
Spirit.Karma: Fixed some fusion sequence problems
Added:
   trunk/libs/spirit/example/karma/mini_xml_karma.cpp
      - copied, changed from r44957, /trunk/libs/spirit/example/qi/mini_xml_karma.cpp
Removed:
   trunk/libs/spirit/example/qi/mini_xml_karma.cpp
Text files modified:
   trunk/boost/spirit/home/karma/action/action.hpp | 9 ++
   trunk/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp | 2
   trunk/boost/spirit/home/karma/operator/alternative.hpp | 2
   trunk/boost/spirit/home/karma/operator/sequence.hpp | 2
   trunk/boost/spirit/home/qi/action/action.hpp | 2
   trunk/boost/spirit/home/support/algorithm/any_if.hpp | 2
   trunk/boost/spirit/home/support/attribute_transform.hpp | 31 ++++++++--
   trunk/boost/spirit/home/support/detail/action_dispatch.hpp | 44 ++++++++++++--
   trunk/libs/spirit/example/karma/mini_xml_karma.cpp | 114 ++++++++++++---------------------------
   9 files changed, 111 insertions(+), 97 deletions(-)

Modified: trunk/boost/spirit/home/karma/action/action.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/action/action.hpp (original)
+++ trunk/boost/spirit/home/karma/action/action.hpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
@@ -23,6 +23,10 @@
 
 namespace boost { namespace spirit { namespace karma
 {
+ ///////////////////////////////////////////////////////////////////////////
+ struct sequence; // forward declaration only
+
+ ///////////////////////////////////////////////////////////////////////////
     struct action
     {
         template <typename Component, typename Context, typename Unused>
@@ -44,7 +48,8 @@
             typedef typename
                 result_of::left<Component>::type::director
             director;
-
+ typedef typename is_same<director, sequence>::type is_sequence;
+
             typedef typename
                 attribute<Component, Context, unused_type>::type
             param_type;
@@ -63,7 +68,7 @@
             // fail parsing.
             // call the function, passing the attribute, the context.
             // The client can return false to fail parsing.
- bool pass = spirit::detail::action_dispatch(
+ bool pass = spirit::detail::action_dispatch<is_sequence>(
                 spirit::right(component), p, ctx);
 
             return pass &&

Modified: trunk/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp (original)
+++ trunk/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
@@ -85,7 +85,7 @@
             Parameter const& param)
         {
             typedef typename Nonterminal::locals_type locals_type;
- fusion::vector<Parameter const&> front(param);
+ fusion::single_view<Parameter const&> front(param);
             NonterminalContext context(
                 fusion::join(
                     front,

Modified: trunk/boost/spirit/home/karma/operator/alternative.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/alternative.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/alternative.hpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
@@ -46,7 +46,7 @@
 
         template <typename Component, typename Context, typename Iterator>
         struct attribute :
- build_fusion_sequence<alternative, Component, Iterator, Context>
+ build_fusion_sequence<alternative, Component, Iterator, Context, mpl::true_>
         {
         };
 

Modified: trunk/boost/spirit/home/karma/operator/sequence.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/sequence.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/sequence.hpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
@@ -43,7 +43,7 @@
         template <typename Component, typename Context, typename Iterator>
         struct attribute :
             build_fusion_sequence<
- sequence, Component, Iterator, Context
+ sequence, Component, Iterator, Context, mpl::true_
>
         {
         };

Modified: trunk/boost/spirit/home/qi/action/action.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/action/action.hpp (original)
+++ trunk/boost/spirit/home/qi/action/action.hpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
@@ -40,7 +40,7 @@
             // before calling detail::action_dispatch whereby
             // disallowing mutability of the attribute in semantic
             // actions.
- return spirit::detail::action_dispatch(f, attr, context);
+ return spirit::detail::action_dispatch<mpl::true_>(f, attr, context);
         }
 
         template <

Modified: trunk/boost/spirit/home/support/algorithm/any_if.hpp
==============================================================================
--- trunk/boost/spirit/home/support/algorithm/any_if.hpp (original)
+++ trunk/boost/spirit/home/support/algorithm/any_if.hpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
@@ -31,6 +31,8 @@
     // used to decide, whether to advance the second iterator or not.
     // This is needed for sequences containing components with unused
     // attributes.
+ // The second iterator is advanced only if the attribute of the
+ // corresponding component iterator is not unused.
     ///////////////////////////////////////////////////////////////////////////
     namespace detail
     {

Modified: trunk/boost/spirit/home/support/attribute_transform.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attribute_transform.hpp (original)
+++ trunk/boost/spirit/home/support/attribute_transform.hpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
@@ -12,6 +12,7 @@
 #include <boost/spirit/home/support/component.hpp>
 #include <boost/spirit/home/support/attribute_of.hpp>
 #include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
 #include <boost/variant/variant_fwd.hpp>
 #include <boost/fusion/include/transform.hpp>
 #include <boost/fusion/include/filter_if.hpp>
@@ -26,23 +27,40 @@
     {
         // Here, we provide policies for stripping single element fusion
         // sequences. Add more specializations as needed.
- template <typename T>
+ template <typename T, typename IsSequence>
         struct strip_single_element_sequence
         {
             typedef T type;
         };
 
         template <typename T>
- struct strip_single_element_sequence<fusion::vector<T> >
+ struct strip_single_element_sequence<fusion::vector<T>, mpl::false_>
         {
             // Strips single element fusion vectors into its 'naked'
             // form: vector<T> --> T
             typedef T type;
         };
 
- template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ template <typename T>
+ struct strip_single_element_sequence<fusion::vector<T>, mpl::true_>
+ {
+ // Strips single element fusion vectors into its 'naked'
+ // form: vector<T> --> T, but does so only if T is not a fusion
+ // sequence itself
+ typedef typename
+ mpl::if_<
+ fusion::traits::is_sequence<T>,
+ fusion::vector<T>,
+ T
+ >::type
+ type;
+ };
+
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename IsSequence>
         struct strip_single_element_sequence<
- fusion::vector<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > >
+ fusion::vector<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+ , IsSequence
+ >
         {
             // Exception: Single element variants are not stripped!
             typedef fusion::vector<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > type;
@@ -65,7 +83,8 @@
     //
     template <
         typename Director, typename Component
- , typename Iterator, typename Context>
+ , typename Iterator, typename Context
+ , typename IsSequence = mpl::false_>
     struct build_fusion_sequence
     {
         template <
@@ -121,7 +140,7 @@
         // Finally, strip single element sequences into its
         // naked form (e.g. vector<T> --> T)
         typedef typename
- traits::strip_single_element_sequence<attribute_sequence>::type
+ traits::strip_single_element_sequence<attribute_sequence, IsSequence>::type
         type;
     };
 

Modified: trunk/boost/spirit/home/support/detail/action_dispatch.hpp
==============================================================================
--- trunk/boost/spirit/home/support/detail/action_dispatch.hpp (original)
+++ trunk/boost/spirit/home/support/detail/action_dispatch.hpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
@@ -14,7 +14,8 @@
 
 namespace boost { namespace spirit { namespace detail
 {
- template <typename F, typename Attribute, typename Context>
+ // general handler for everything not explicitly specialized below
+ template <typename Pass, typename F, typename Attribute, typename Context>
     bool action_dispatch(F const& f, Attribute& attr, Context& context)
     {
         bool pass = true;
@@ -22,16 +23,44 @@
         return pass;
     }
 
+ // handler for phoenix actors
+
+ // If the component this action has to be invoked for is a sequence, we
+ // wrap any non-fusion sequence into a fusion sequence (done by pass_value)
+ // and pass through any fusion sequence.
     template <typename Eval, typename Attribute, typename Context>
     bool action_dispatch(phoenix::actor<Eval> const& f
- , Attribute& attr, Context& context)
+ , Attribute& attr, Context& context, mpl::true_)
     {
         bool pass = true;
- f(pass_value<Attribute>::call(attr), context, pass);
+ f (pass_value<Attribute>::call(attr), context, pass);
         return pass;
     }
 
- template <typename RT, typename A0, typename A1, typename A2
+ // If this action has to be invoked for anything but a sequence, we always
+ // need to wrap the attribute into a fusion sequence, because the attribute
+ // has to be treated as being a single value in any case (even if it
+ // actually already is a fusion sequence on its own).
+ template <typename Eval, typename Attribute, typename Context>
+ bool action_dispatch(phoenix::actor<Eval> const& f
+ , Attribute& attr, Context& context, mpl::false_)
+ {
+ bool pass = true;
+ f (fusion::vector<Attribute&>(attr), context, pass);
+ return pass;
+ }
+
+ template <typename IsSequence
+ , typename Eval, typename Attribute, typename Context>
+ bool action_dispatch(phoenix::actor<Eval> const& f
+ , Attribute& attr, Context& context)
+ {
+ return action_dispatch(f, attr, context, IsSequence());
+ }
+
+ // specializations for plain function pointers taking a different number of
+ // arguments
+ template <typename Pass, typename RT, typename A0, typename A1, typename A2
       , typename Attribute, typename Context>
     bool action_dispatch(RT(*f)(A0, A1, A2)
       , Attribute& attr, Context& context)
@@ -41,7 +70,7 @@
         return pass;
     }
 
- template <typename RT, typename A0, typename A1
+ template <typename Pass, typename RT, typename A0, typename A1
       , typename Attribute, typename Context>
     bool action_dispatch(RT(*f)(A0, A1)
       , Attribute& attr, Context& context)
@@ -50,7 +79,7 @@
         return true;
     }
 
- template <typename RT, typename A0
+ template <typename Pass, typename RT, typename A0
       , typename Attribute, typename Context>
     bool action_dispatch(RT(*f)(A0)
       , Attribute& attr, Context&)
@@ -59,13 +88,14 @@
         return true;
     }
 
- template <typename RT, typename Attribute, typename Context>
+ template <typename Pass, typename RT, typename Attribute, typename Context>
     bool action_dispatch(RT(*f)()
       , Attribute&, Context&)
     {
         f();
         return true;
     }
+
 }}}
 
 #endif

Copied: trunk/libs/spirit/example/karma/mini_xml_karma.cpp (from r44957, /trunk/libs/spirit/example/qi/mini_xml_karma.cpp)
==============================================================================
--- /trunk/libs/spirit/example/qi/mini_xml_karma.cpp (original)
+++ trunk/libs/spirit/example/karma/mini_xml_karma.cpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
@@ -1,6 +1,6 @@
 /*=============================================================================
- Copyright (c) 2001-2007 Joel de Guzman
- Copyright (c) 2001-2007 Hartmut Kaiser
+ Copyright (c) 2001-2008 Joel de Guzman
+ Copyright (c) 2001-2008 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)
@@ -20,10 +20,10 @@
 #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_function.hpp>
 #include <boost/spirit/include/phoenix_stl.hpp>
 #include <boost/fusion/include/adapt_struct.hpp>
 #include <boost/variant/recursive_variant.hpp>
-#include <boost/function_output_iterator.hpp>
 
 #include <iostream>
 #include <fstream>
@@ -31,8 +31,6 @@
 #include <vector>
 
 using namespace boost::spirit;
-using namespace boost::spirit::qi;
-using namespace boost::spirit::karma;
 using namespace boost::spirit::ascii;
 using namespace boost::spirit::arg_names;
 
@@ -77,25 +75,25 @@
 {
     mini_xml_parser()
     {
- text = lexeme[+(char_ - '<') [text.val += _1]];
- node = (xml | text) [node.val = _1];
+ text = lexeme[+(char_ - '<') [_val += _1]];
+ node = (xml | text) [_val = _1];
 
         start_tag =
                 '<'
- >> lexeme[+(char_ - '>') [start_tag.val += _1]]
+ >> lexeme[+(char_ - '>') [_val += _1]]
>> '>'
         ;
 
         end_tag =
                 "</"
- >> lit(end_tag._1)
+ >> lit(_r1)
>> '>'
         ;
 
         xml =
- start_tag [at_c<0>(xml.val) = _1]
- >> *node [push_back(at_c<1>(xml.val), _1)]
- >> end_tag(at_c<0>(xml.val))
+ start_tag [at_c<0>(_val) = _1]
+ >> *node [push_back(at_c<1>(_val), _1)]
+ >> end_tag(at_c<0>(_val))
         ;
     }
 
@@ -107,85 +105,46 @@
 };
 
 ///////////////////////////////////////////////////////////////////////////////
-//
+// A couple of phoenix functions helping to access the elements of the
+// generated AST
 ///////////////////////////////////////////////////////////////////////////////
-template <typename String>
-struct string_appender
+template <typename T>
+struct get_element
 {
- string_appender(String& s)
- : str(s)
- {}
+ template <typename T1>
+ struct result { typedef T const& type; };
 
- template <typename T>
- void operator()(T const &x) const
+ T const& operator()(mini_xml_node const& node) const
     {
- str += x;
+ return boost::get<T>(node);
     }
-
- String& str;
 };
 
-template <typename String>
-inline string_appender<String>
-make_string_appender(String& str)
-{
- return string_appender<String>(str);
-}
-
-template <typename Char>
-struct output_iterator
-{
- typedef std::basic_string<Char> string_type;
- typedef string_appender<string_type> appender_type;
- typedef boost::function_output_iterator<appender_type> type;
-
- static type
- call(std::basic_string<Char>& str)
- {
- return boost::make_function_output_iterator(
- make_string_appender(str));
- }
-};
+phoenix::function<get_element<std::string> > _string;
+phoenix::function<get_element<mini_xml> > _xml;
 
 ///////////////////////////////////////////////////////////////////////////////
-//
+// The output grammar defining the format of the generated data
 ///////////////////////////////////////////////////////////////////////////////
 template <typename OutputIterator>
 struct mini_xml_generator
- : boost::spirit::karma::grammar_def<OutputIterator, void(mini_xml), space_type>
+ : karma::grammar_def<OutputIterator, mini_xml()>
 {
-// typedef karma::grammar_def<OutputIterator, void(mini_xml), space_type> base_type;
-// boost::mpl::print<typename base_type::start_type::param_types> x;
-
     mini_xml_generator()
     {
-// text = verbatim[lit(text._1)];
-// node = (xml | text) [_1 = node._1];
-//
-// start_tag =
-// '<'
-// << verbatim[lit(start_tag._1)]
-// << '>'
-// ;
-//
-// end_tag =
-// "</"
-// << verbatim[lit(end_tag._1)]
-// << '>'
-// ;
-//
-// xml =
-// start_tag(at_c<0>(xml._1))
-// << (*node) [ref(at_c<1>(xml._1))]
-// << end_tag(at_c<0>(xml._1))
- ;
+ node %=
+ lit[_1 = _string(_r0)]
+ | (char_('\n') << xml[_1 = _xml(_r0)] << '\n')
+ ;
+
+ xml = char_('<') << lit(at_c<0>(_r0)) << '>'
+ << (*node)[_1 = at_c<1>(_r0)]
+ << lit("</") << lit(at_c<0>(_r0)) << '>'
+ ;
     }
 
- karma::rule<OutputIterator, void(mini_xml), space_type> xml;
-// karma::rule<OutputIterator, void(mini_xml_node), space_type> node;
-// karma::rule<OutputIterator, void(std::string), space_type> text;
-// karma::rule<OutputIterator, void(std::string), space_type> start_tag;
-// karma::rule<OutputIterator, void(std::string), space_type> end_tag;
+ karma::rule<OutputIterator, mini_xml()> xml;
+ karma::rule<OutputIterator, mini_xml_node()> node;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -227,7 +186,7 @@
 
     std::string::const_iterator iter = storage.begin();
     std::string::const_iterator end = storage.end();
- bool r = phrase_parse(iter, end, xmlin, ast, space);
+ bool r = qi::phrase_parse(iter, end, xmlin, ast, space);
 
     if (r && iter == end)
     {
@@ -235,15 +194,14 @@
         std::cout << "Parsing succeeded\n";
         std::cout << "-------------------------\n";
 
- typedef output_iterator<char>::type outiter_type;
+ typedef std::back_insert_iterator<std::string> outiter_type;
         typedef mini_xml_generator<outiter_type> mini_xml_generator;
 
         mini_xml_generator gen; // Our grammar definition
         karma::grammar<mini_xml_generator> xmlout(gen, gen.xml); // Our grammar
 
         std::string generated;
- bool r = generate_delimited(output_iterator<char>::call(generated),
- xmlout(ast), space);
+ bool r = karma::generate(std::back_inserter(generated), xmlout, ast);
 
         if (r)
             std::cout << generated << std::endl;

Deleted: trunk/libs/spirit/example/qi/mini_xml_karma.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/mini_xml_karma.cpp 2008-05-02 18:18:42 EDT (Fri, 02 May 2008)
+++ (empty file)
@@ -1,264 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2007 Joel de Guzman
- Copyright (c) 2001-2007 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)
-=============================================================================*/
-///////////////////////////////////////////////////////////////////////////////
-//
-// A mini XML-like parser, Karma is used to print out the generated AST
-//
-// [ JDG March 25, 2007 ] spirit2
-// [ HK April 02, 2007 ] spirit2
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#include <boost/config/warning_disable.hpp>
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/karma.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/fusion/include/adapt_struct.hpp>
-#include <boost/variant/recursive_variant.hpp>
-#include <boost/function_output_iterator.hpp>
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <vector>
-
-using namespace boost::spirit;
-using namespace boost::spirit::qi;
-using namespace boost::spirit::karma;
-using namespace boost::spirit::ascii;
-using namespace boost::spirit::arg_names;
-
-namespace fusion = boost::fusion;
-namespace phoenix = boost::phoenix;
-
-using phoenix::at_c;
-using phoenix::push_back;
-
-///////////////////////////////////////////////////////////////////////////////
-// Our mini XML tree representation
-///////////////////////////////////////////////////////////////////////////////
-struct mini_xml;
-
-typedef
- boost::variant<
- boost::recursive_wrapper<mini_xml>
- , std::string
- >
-mini_xml_node;
-
-struct mini_xml
-{
- std::string name; // tag name
- std::vector<mini_xml_node> children; // children
-};
-
-// We need to tell fusion about our mini_xml struct
-// to make it a first-class fusion citizen
-BOOST_FUSION_ADAPT_STRUCT(
- mini_xml,
- (std::string, name)
- (std::vector<mini_xml_node>, children)
-)
-
-///////////////////////////////////////////////////////////////////////////////
-// Our mini XML grammar definition
-///////////////////////////////////////////////////////////////////////////////
-template <typename Iterator>
-struct mini_xml_parser :
- qi::grammar_def<Iterator, mini_xml(), space_type>
-{
- mini_xml_parser()
- {
- text = lexeme[+(char_ - '<') [text.val += _1]];
- node = (xml | text) [node.val = _1];
-
- start_tag =
- '<'
- >> lexeme[+(char_ - '>') [start_tag.val += _1]]
- >> '>'
- ;
-
- end_tag =
- "</"
- >> lit(end_tag._1)
- >> '>'
- ;
-
- xml =
- start_tag [at_c<0>(xml.val) = _1]
- >> *node [push_back(at_c<1>(xml.val), _1)]
- >> end_tag(at_c<0>(xml.val))
- ;
- }
-
- qi::rule<Iterator, mini_xml(), space_type> xml;
- qi::rule<Iterator, mini_xml_node(), space_type> node;
- qi::rule<Iterator, std::string(), space_type> text;
- qi::rule<Iterator, std::string(), space_type> start_tag;
- qi::rule<Iterator, void(std::string), space_type> end_tag;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-//
-///////////////////////////////////////////////////////////////////////////////
-template <typename String>
-struct string_appender
-{
- string_appender(String& s)
- : str(s)
- {}
-
- template <typename T>
- void operator()(T const &x) const
- {
- str += x;
- }
-
- String& str;
-};
-
-template <typename String>
-inline string_appender<String>
-make_string_appender(String& str)
-{
- return string_appender<String>(str);
-}
-
-template <typename Char>
-struct output_iterator
-{
- typedef std::basic_string<Char> string_type;
- typedef string_appender<string_type> appender_type;
- typedef boost::function_output_iterator<appender_type> type;
-
- static type
- call(std::basic_string<Char>& str)
- {
- return boost::make_function_output_iterator(
- make_string_appender(str));
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-//
-///////////////////////////////////////////////////////////////////////////////
-template <typename OutputIterator>
-struct mini_xml_generator
- : boost::spirit::karma::grammar_def<OutputIterator, void(mini_xml), space_type>
-{
-// typedef karma::grammar_def<OutputIterator, void(mini_xml), space_type> base_type;
-// boost::mpl::print<typename base_type::start_type::param_types> x;
-
- mini_xml_generator()
- {
-// text = verbatim[lit(text._1)];
-// node = (xml | text) [_1 = node._1];
-//
-// start_tag =
-// '<'
-// << verbatim[lit(start_tag._1)]
-// << '>'
-// ;
-//
-// end_tag =
-// "</"
-// << verbatim[lit(end_tag._1)]
-// << '>'
-// ;
-//
-// xml =
-// start_tag(at_c<0>(xml._1))
-// << (*node) [ref(at_c<1>(xml._1))]
-// << end_tag(at_c<0>(xml._1))
- ;
- }
-
- karma::rule<OutputIterator, void(mini_xml), space_type> xml;
-// karma::rule<OutputIterator, void(mini_xml_node), space_type> node;
-// karma::rule<OutputIterator, void(std::string), space_type> text;
-// karma::rule<OutputIterator, void(std::string), space_type> start_tag;
-// karma::rule<OutputIterator, void(std::string), space_type> end_tag;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Main program
-///////////////////////////////////////////////////////////////////////////////
-int main(int argc, char **argv)
-{
- char const* filename;
- if (argc > 1)
- {
- filename = argv[1];
- }
- else
- {
- std::cerr << "Error: No input file provided." << std::endl;
- return 1;
- }
-
- std::ifstream in(filename, std::ios_base::in);
-
- if (!in)
- {
- std::cerr << "Error: Could not open input file: "
- << filename << std::endl;
- return 1;
- }
-
- std::string storage; // 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(storage));
-
- typedef mini_xml_parser<std::string::const_iterator> mini_xml_parser;
- mini_xml_parser def; // Our grammar definition
- qi::grammar<mini_xml_parser> xmlin(def, def.xml); // Our grammar
- mini_xml ast; // our tree
-
- std::string::const_iterator iter = storage.begin();
- std::string::const_iterator end = storage.end();
- bool r = phrase_parse(iter, end, xmlin, ast, space);
-
- if (r && iter == end)
- {
- std::cout << "-------------------------\n";
- std::cout << "Parsing succeeded\n";
- std::cout << "-------------------------\n";
-
- typedef output_iterator<char>::type outiter_type;
- typedef mini_xml_generator<outiter_type> mini_xml_generator;
-
- mini_xml_generator gen; // Our grammar definition
- karma::grammar<mini_xml_generator> xmlout(gen, gen.xml); // Our grammar
-
- std::string generated;
- bool r = generate_delimited(output_iterator<char>::call(generated),
- xmlout(ast), space);
-
- if (r)
- std::cout << generated << std::endl;
- return 0;
- }
- else
- {
- std::string::const_iterator some = iter+30;
- std::string context(iter, (some>end)?end:some);
- std::cout << "-------------------------\n";
- std::cout << "Parsing failed\n";
- std::cout << "stopped at: \": " << context << "...\"\n";
- std::cout << "-------------------------\n";
- return 1;
- }
-}
-
-


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk