$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61551 - trunk/libs/spirit/example/scheme/test
From: joel_at_[hidden]
Date: 2010-04-25 05:22:02
Author: djowel
Date: 2010-04-25 05:22:02 EDT (Sun, 25 Apr 2010)
New Revision: 61551
URL: http://svn.boost.org/trac/boost/changeset/61551
Log:
primitives
Text files modified: 
   trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp |   136 +++++++++++++++++---------------------- 
   1 files changed, 61 insertions(+), 75 deletions(-)
Modified: trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp	(original)
+++ trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp	2010-04-25 05:22:02 EDT (Sun, 25 Apr 2010)
@@ -16,98 +16,74 @@
 namespace scheme
 {
     ///////////////////////////////////////////////////////////////////////////
-    // parser
+    // parser compiler
     ///////////////////////////////////////////////////////////////////////////
-    using boost::spirit::unused;
     namespace qi = boost::spirit::qi;
     namespace spirit = boost::spirit;
 
-    typedef boost::iterator_range<char const*> source_type;
+    typedef qi::rule<char const*> skipper_type;
+    typedef qi::rule<char const*, utree(), skipper_type> rule_type;
 
-    template <typename Parser, bool no_attr>
-    struct qi_parser_function
-      : actor<qi_parser_function<Parser, no_attr> >
+    template <typename Rule>
+    class rule_fragments
     {
-        Parser p;
-        qi_parser_function(Parser const& p)
-          : p(p) {}
+    public:
 
-        utree eval(scope const& env) const
-        {
-            // the source input
-            source_type rng = env[0].get<source_type>();
-            char const* iter = rng.begin();
-
-            // the skipper
-            utree const& skipper = env[1];
-
-            // do a pre-skip
-            while (skipper.eval(env) == true)
-                ;
-
-            // the attribute
-            utree& attribute = env[2];
-            bool r = false;
-            if (r = p.parse(iter, rng.end(), unused, unused, attribute))
-                env[0] = source_type(iter, rng.end());
+        rule_fragments() {};
 
-            return r;
+        template <typename Expr>
+        boost::tuple<Rule const&, int>
+        new_rule(Expr const& expr)
+        {
+            rules.push_back(Rule());
+            rules.front() = expr;
+            return boost::tuple<Rule const&, int>(
+                rules.front(), rules.size()-1);
         }
-    };
-
-    template <typename Parser>
-    struct qi_parser_function<Parser, true> // unused attribute
-      : actor<qi_parser_function<Parser, true> >
-    {
-        Parser p;
-        qi_parser_function(Parser const& p)
-          : p(p) {}
 
-        utree eval(scope const& env) const
+        Rule const& get_rule(int id) const
         {
-            // the source input
-            source_type rng = env[0].get<source_type>();
-            char const* iter = rng.begin();
-
-            // the skipper
-            utree const& skipper = env[1];
-
-            // do a pre-skip
-            while (skipper.eval(env) == true)
-                ;
-
-            bool r = false;
-            if (r = p.parse(iter, rng.end(), unused, unused, unused))
-                env[0] = source_type(iter, rng.end());
-
-            return r;
+            return rules[i];
         }
+
+    private:
+
+        std::vector<Rule> rules;
     };
 
-    struct qi_parser
+    struct primitive_parser_composite : composite<primitive_parser_composite>
     {
-        typedef function result_type;
-
-        template <typename Expression>
-        function operator()(Expression const& expr) const
+        int id;
+        primitive_parser_composite(int id)
+          : id(id)
         {
-            typedef typename
-                boost::spirit::result_of::compile<
-                    qi::domain, Expression>::type
-            parser_type;
-
-            typedef boost::is_same<
-                typename spirit::traits::attribute_of<parser_type>::type,
-                spirit::unused_type>
-            is_unused;
+        }
 
-            return function(qi_parser_function<parser_type, is_unused::value>(
-                qi::compile<qi::domain>(expr)));
+        function compose(actor_list const& elements) const
+        {
+            return val(id);
         }
     };
 
-    qi_parser const primitive_parser = {};
-    function const space = primitive_parser(qi::space);
+    template <typename Fragments, typename Expr>
+    inline primitive_parser_composite
+    make_primitive_parser_composite(Fragments& fragments, Expr const& expr)
+    {
+        return primitive_parser_composite(
+            boost::get<1>(fragments.new_rule(expr)));
+    }
+
+    template <typename Fragments>
+    void build_qi_environment(Fragments& fragments, environment& env)
+    {
+        build_basic_environment(env);
+        env.define("qi:space",
+            make_primitive_parser_composite(fragments, qi::space), 0, true);
+        env.define("qi:alpha",
+            make_primitive_parser_composite(fragments, qi::alpha), 0, true);
+        env.define("qi:int_",
+            make_primitive_parser_composite(fragments, qi::int_), 0, true);
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -116,11 +92,21 @@
 int main()
 {
     using scheme::interpreter;
+    using scheme::environment;
+    using scheme::build_qi_environment;
+    using scheme::rule_fragments;
+    using scheme::rule_type;
     using scheme::utree;
 
-    utree src = "(define (factorial n) (if (<= n 0) 1 (* n (factorial (- n 1)))))";
-    scheme::interpreter program(src);
-    BOOST_TEST(program["factorial"](10) == 3628800);
+    environment env;
+    rule_fragments<rule_type> fragments;
+    build_qi_environment(fragments, env);
+
+    {
+        utree src = "(define (factorial n) (if (<= n 0) 1 (* n (factorial (- n 1)))))";
+        interpreter program(src, &env);
+        BOOST_TEST(program["factorial"](10) == 3628800);
+    }
 
     return boost::report_errors();
 }