$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r57826 - trunk/libs/spirit/example/qi
From: hartmut.kaiser_at_[hidden]
Date: 2009-11-20 19:35:03
Author: hkaiser
Date: 2009-11-20 19:35:03 EST (Fri, 20 Nov 2009)
New Revision: 57826
URL: http://svn.boost.org/trac/boost/changeset/57826
Log:
Spirit: added a new Qi example
Added:
   trunk/libs/spirit/example/qi/iter_pos.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/iter_pos_parser.cpp   (contents, props changed)
Text files modified: 
   trunk/libs/spirit/example/qi/Jamfile |     2 ++                                      
   1 files changed, 2 insertions(+), 0 deletions(-)
Modified: trunk/libs/spirit/example/qi/Jamfile
==============================================================================
--- trunk/libs/spirit/example/qi/Jamfile	(original)
+++ trunk/libs/spirit/example/qi/Jamfile	2009-11-20 19:35:03 EST (Fri, 20 Nov 2009)
@@ -30,6 +30,8 @@
 exe key_value_sequence_ordered : key_value_sequence_ordered.cpp ;
 exe key_value_sequence_empty_value : key_value_sequence_empty_value.cpp ;
 
+exe iter_pos_parser : iter_pos_parser.cpp ;
+
 exe calculator1 : calc1.cpp ;
 exe calculator2 : calc2.cpp ;
 exe calculator2_ast : calc2_ast.cpp ;
Added: trunk/libs/spirit/example/qi/iter_pos.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/iter_pos.hpp	2009-11-20 19:35:03 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,83 @@
+//  Copyright (c) 2001-2009 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(ITER_POS_NOV_20_2009_1245PM)
+#define ITER_POS_NOV_20_2009_1245PM
+
+#include <boost/spirit/include/qi_parse.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// definition the place holder 
+namespace custom_parser 
+{ 
+    BOOST_SPIRIT_TERMINAL(iter_pos);
+} 
+
+///////////////////////////////////////////////////////////////////////////////
+// implementation the enabler
+namespace boost { namespace spirit 
+{ 
+    // We want custom_parser::iter_pos to be usable as a terminal only, 
+    // and only for parser expressions (qi::domain).
+    template <>
+    struct use_terminal<qi::domain, custom_parser::tag::iter_pos> 
+      : mpl::true_ 
+    {}; 
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+// implementation of the parser
+namespace custom_parser 
+{ 
+    struct iter_pos_parser 
+      : boost::spirit::qi::primitive_parser<iter_pos_parser>
+    {
+        // Define the attribute type exposed by this parser component
+        template <typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef Iterator type;
+        };
+
+        // This function is called during the actual parsing process
+        template <typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        bool parse(Iterator& first, Iterator const& last
+          , Context&, Skipper const& skipper, Attribute& attr) const
+        {
+            boost::spirit::qi::skip_over(first, last, skipper);
+            boost::spirit::traits::assign_to(first, attr);
+            return true;
+        }
+
+        // This function is called during error handling to create
+        // a human readable string for the error context.
+        template <typename Context>
+        boost::spirit::info what(Context&) const
+        {
+            return boost::spirit::info("iter_pos");
+        }
+    };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// instantiation of the parser
+namespace boost { namespace spirit { namespace qi
+{
+    // This is the factory function object invoked in order to create 
+    // an instance of our iter_pos_parser.
+    template <typename Modifiers>
+    struct make_primitive<custom_parser::tag::iter_pos, Modifiers>
+    {
+        typedef custom_parser::iter_pos_parser result_type;
+
+        result_type operator()(unused_type, unused_type) const
+        {
+            return result_type();
+        }
+    };
+}}}
+
+#endif
Added: trunk/libs/spirit/example/qi/iter_pos_parser.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/iter_pos_parser.cpp	2009-11-20 19:35:03 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,51 @@
+//  Copyright (c) 2001-2009 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)
+
+//  The purpose of this example is to show how a simple custom primitive parser
+//  component can be written. We develop a custom parser exposing the current 
+//  iterator position as its attribute.
+//
+//  For more information see: http://spirit.sourceforge.net/home/
+
+#include <boost/spirit/include/qi_parse_attr.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+
+#include <string>
+#include "iter_pos.hpp"
+
+namespace qi = boost::spirit::qi;
+
+int main()
+{
+    using custom_parser::iter_pos;
+
+    std::string prefix, suffix;           // attributes receiving the
+    std::string::iterator position;       // parsed values
+
+    std::string input("prefix1234567");
+    std::string::iterator first = input.begin();
+    bool result = 
+        qi::parse(first, input.end()
+          , +qi::alpha >> iter_pos >> +qi::digit
+          , prefix, position, suffix);
+
+    if (result) 
+    {
+        std::cout << "-------------------------------- \n";
+        std::cout << "Parsing succeeded\n";
+        std::cout << "prefix is: " << prefix << "\n";
+        std::cout << "suffix is: " << suffix << "\n";
+        std::cout << "position is: " << std::distance(input.begin(), position) << "\n";
+        std::cout << "-------------------------------- \n";
+    }
+    else 
+    {
+        std::cout << "-------------------------------- \n";
+        std::cout << "Parsing failed\n";
+        std::cout << "-------------------------------- \n";
+    }
+    return 0;
+}