Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61567 - trunk/libs/spirit/example/scheme/test
From: joel_at_[hidden]
Date: 2010-04-26 00:56:43


Author: djowel
Date: 2010-04-26 00:56:42 EDT (Mon, 26 Apr 2010)
New Revision: 61567
URL: http://svn.boost.org/trac/boost/changeset/61567

Log:
implemented:
+ space, alpha, int_, char_
+ kleene_composite
+ difference
+ sequence
Text files modified:
   trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp | 138 +++++++++++++++++++++++++++++++++++++--
   1 files changed, 131 insertions(+), 7 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-26 00:56:42 EDT (Mon, 26 Apr 2010)
@@ -110,6 +110,12 @@
         {
         }
 
+ utree eval() const
+ {
+ // char_
+ return fragments.new_rule(qi::char_);
+ }
+
         utree eval(utree const& a) const
         {
             // $$$ use exceptions here $$$.
@@ -147,7 +153,9 @@
 
         utree eval(scope const& env) const
         {
- if (b.empty())
+ if (a.empty())
+ return eval();
+ else if (b.empty())
                 return eval(a(env));
             else
                 return eval(a(env), b(env));
@@ -168,7 +176,7 @@
             actor_list::const_iterator i = elements.begin();
 
             function empty;
- function const& a = *i++;
+ function const& a = (i == elements.end())? empty : *i++;
             function const& b = (i == elements.end())? empty : *i;
             return function(function_type(fragments, a, b));
         }
@@ -261,6 +269,109 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ // Handles the compilation of sequence a >> b
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Fragments>
+ struct sequence_function : actor<sequence_function<Fragments> >
+ {
+ Fragments& fragments;
+ actor_list elements;
+ sequence_function(
+ Fragments& fragments, actor_list const& elements)
+ : elements(elements), fragments(fragments)
+ {
+ }
+
+ utree eval(utree const& a, utree const& b) const
+ {
+ // a >> b
+ return fragments.new_rule(
+ fragments[a] >> fragments[b]);
+ }
+
+ utree eval(utree const& a, utree const& b, utree const& c) const
+ {
+ // a >> b >> c
+ return fragments.new_rule(
+ fragments[a] >> fragments[b] >> fragments[c]);
+ }
+
+ utree eval(utree const& a, utree const& b, utree const& c,
+ utree const& d) const
+ {
+ // a >> b >> c >> d
+ return fragments.new_rule(
+ fragments[a] >> fragments[b] >> fragments[c] >>
+ fragments[d]);
+ }
+
+ utree eval(utree const& a, utree const& b, utree const& c,
+ utree const& d, utree const& e) const
+ {
+ // a >> b >> c >> d >> e
+ return fragments.new_rule(
+ fragments[a] >> fragments[b] >> fragments[c] >>
+ fragments[d] >> fragments[e]);
+ }
+
+ utree eval(scope const& env) const
+ {
+ actor_list::const_iterator i = elements.begin();
+ switch (elements.size())
+ {
+ case 2:
+ {
+ function const& a = *i++;
+ function const& b = *i;
+ return eval(a(env), b(env));
+ }
+ case 3:
+ {
+ function const& a = *i++;
+ function const& b = *i++;
+ function const& c = *i;
+ return eval(a(env), b(env), c(env));
+ }
+ case 4:
+ {
+ function const& a = *i++;
+ function const& b = *i++;
+ function const& c = *i++;
+ function const& d = *i;
+ return eval(a(env), b(env), c(env), d(env));
+ }
+ case 5:
+ {
+ function const& a = *i++;
+ function const& b = *i++;
+ function const& c = *i++;
+ function const& d = *i++;
+ function const& e = *i;
+ return eval(a(env), b(env), c(env), d(env), e(env));
+ }
+
+ // $$$ Use Boost PP using SCHEME_QI_COMPILER_LIMIT $$$
+ }
+ return utree();
+ }
+ };
+
+ template <typename Fragments>
+ struct sequence_composite
+ : composite<sequence_composite<Fragments> >
+ {
+ Fragments& fragments;
+ sequence_composite(Fragments& fragments)
+ : fragments(fragments) {}
+
+ function compose(actor_list const& elements) const
+ {
+ typedef sequence_function<Fragments> function_type;
+ return function(function_type(fragments, elements));
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // Build our scheme compiler environment.
     ///////////////////////////////////////////////////////////////////////////
     template <typename Fragments>
@@ -278,13 +389,16 @@
             make_primitive_parser_composite(fragments, qi::int_), 0, true);
 
         env.define("qi:char_",
- char_composite<Fragments>(fragments), 1, false);
+ char_composite<Fragments>(fragments), 0, false);
 
         env.define("qi:*",
             kleene_composite<Fragments>(fragments), 1, true);
 
         env.define("qi:-",
             difference_composite<Fragments>(fragments), 2, true);
+
+ env.define("qi:>>",
+ sequence_composite<Fragments>(fragments), 2, false);
     }
 }}
 
@@ -311,17 +425,27 @@
         utree src =
             "(define charx (qi:char_ \"x\"))"
             "(define integer (qi:int_))"
- "(define int_not_0 (qi:- (qi:int_) (qi:char_ \"0\")))"
- "(define integers (qi:* (qi:int_)))";
+ "(define nonzero (qi:- (qi:int_) (qi:char_ \"0\")))"
+ "(define integers (qi:* (qi:int_)))"
+ "(define intpair (qi:>> "
+ "(qi:char_ \"(\") "
+ "(qi:int_) "
+ "(qi:char_ \",\") "
+ "(qi:int_) "
+ "(qi:char_ \")\")))"
+ ;
         interpreter parser(src, "parse.scm", &env);
 
+ BOOST_TEST(test("z", fragments[parser["qi:char_"]()], space));
         BOOST_TEST(test("x", fragments[parser["charx"]()], space));
         BOOST_TEST(!test("y", fragments[parser["charx"]()], space));
         BOOST_TEST(test("1234", fragments[parser["integer"]()], space));
         BOOST_TEST(!test("x1234", fragments[parser["integer"]()], space));
         BOOST_TEST(test("1 2 3 4", fragments[parser["integers"]()], space));
- BOOST_TEST(test("1", fragments[parser["int_not_0"]()], space));
- BOOST_TEST(!test("0", fragments[parser["int_not_0"]()], space));
+ BOOST_TEST(test("1", fragments[parser["nonzero"]()], space));
+ BOOST_TEST(!test("0", fragments[parser["nonzero"]()], space));
+ BOOST_TEST(test("(1, 2)", fragments[parser["intpair"]()], space));
+ BOOST_TEST(!test("(1, x)", fragments[parser["intpair"]()], space));
     }
 
     return boost::report_errors();


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