Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61578 - trunk/libs/spirit/example/scheme/test/qi
From: joel_at_[hidden]
Date: 2010-04-26 12:22:27


Author: djowel
Date: 2010-04-26 12:22:26 EDT (Mon, 26 Apr 2010)
New Revision: 61578
URL: http://svn.boost.org/trac/boost/changeset/61578

Log:
calculator working. memoization saved the day.
Text files modified:
   trunk/libs/spirit/example/scheme/test/qi/calc.scm | 43 +++-----
   trunk/libs/spirit/example/scheme/test/qi/qi_interpreter.cpp | 184 ++++++++++++++++++++++++++-------------
   2 files changed, 141 insertions(+), 86 deletions(-)

Modified: trunk/libs/spirit/example/scheme/test/qi/calc.scm
==============================================================================
--- trunk/libs/spirit/example/scheme/test/qi/calc.scm (original)
+++ trunk/libs/spirit/example/scheme/test/qi/calc.scm 2010-04-26 12:22:26 EDT (Mon, 26 Apr 2010)
@@ -2,32 +2,23 @@
 
 (define expression) ; forward declaration
 
-(define expression
- (qi:>> (qi:int_)
+(define factor
+ (qi:|
+ (qi:int_)
+ (qi:>> (qi:char_ "(") (expression) (qi:char_ ")"))
+ (qi:>> (qi:char_ "-") (factor))
+ (qi:>> (qi:char_ "+") (factor))))
+
+(define term
+ (qi:>> (factor)
         (qi:*
             (qi:|
- (qi:>> (qi:char_ "+") (qi:int_))
- (qi:>> (qi:char_ "-") (qi:int_))))))
-
-; (define expression)
-
-; (define factor
- ; (qi:|
- ; (qi:int_)
- ; (qi:>> (qi:char_ "(") (expression) (qi:char_ ")"))
- ; (qi:>> (qi:char_ "-") (factor))
- ; (qi:>> (qi:char_ "+") (factor))))
+ (qi:>> (qi:char_ "*") (factor))
+ (qi:>> (qi:char_ "/") (factor))))))
 
-; (define term
- ; (qi:>> (factor)
- ; (qi:*
- ; (qi:|
- ; (qi:>> (qi:char_ "*") (factor))
- ; (qi:>> (qi:char_ "/") (factor))))))
-
-; (define expression
- ; (qi:>> (term)
- ; (qi:*
- ; (qi:|
- ; (qi:>> (qi:char_ "+") (term))
- ; (qi:>> (qi:char_ "-") (term))))))
\ No newline at end of file
+(define expression
+ (qi:>> (term)
+ (qi:*
+ (qi:|
+ (qi:>> (qi:char_ "+") (term))
+ (qi:>> (qi:char_ "-") (term))))))
\ No newline at end of file

Modified: trunk/libs/spirit/example/scheme/test/qi/qi_interpreter.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/qi/qi_interpreter.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/qi/qi_interpreter.cpp 2010-04-26 12:22:26 EDT (Mon, 26 Apr 2010)
@@ -30,7 +30,7 @@
     namespace spirit = boost::spirit;
 
     typedef qi::rule<char const*> skipper_type;
- typedef qi::rule<char const*, utree(), skipper_type> rule_type;
+ typedef qi::rule<char const*, skipper_type> rule_type;
 
     ///////////////////////////////////////////////////////////////////////////
     // All rule are stored here. Rules are held in the utree by its id;
@@ -46,13 +46,18 @@
         {
         };
 
- template <typename Expr>
- int new_rule(Expr const& expr)
+ int new_rule()
         {
- rules[index] = expr;
+ rules[index];
             return index++;
         }
 
+ template <typename Expr>
+ void define_rule(int id, Expr const& expr)
+ {
+ rules[id] = expr;
+ }
+
         Rule const& operator[](int id) const
         {
             typename std::map<int, Rule>::const_iterator
@@ -95,7 +100,9 @@
     inline primitive_parser_composite
     make_primitive_parser_composite(Fragments& fragments, Expr const& expr)
     {
- return primitive_parser_composite(fragments.new_rule(expr));
+ int id = fragments.new_rule();
+ fragments.define_rule(id, expr);
+ return primitive_parser_composite(id);
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -104,22 +111,23 @@
     template <typename Fragments>
     struct char_function : actor<char_function<Fragments> >
     {
- Fragments& fragments;
+ mutable int id;
         function a;
         function b;
+ Fragments& fragments;
         char_function(
             Fragments& fragments, function const& a, function const& b)
- : a(a), b(b), fragments(fragments)
+ : id(-1), a(a), b(b), fragments(fragments)
         {
         }
 
- utree eval() const
+ void define() const
         {
             // char_
- return fragments.new_rule(qi::char_);
+ fragments.define_rule(id, qi::char_);
         }
 
- utree eval(utree const& a) const
+ void define(utree const& a) const
         {
             // $$$ use exceptions here $$$.
             BOOST_ASSERT(a.which() == utree_type::string_type);
@@ -128,17 +136,17 @@
             if (a_.size() == 1)
             {
                 // char_('x')
- return fragments.new_rule(qi::char_(a_[0]));
+ fragments.define_rule(id, qi::char_(a_[0]));
             }
             else
             {
                 // char_("some-regex")
- return fragments.new_rule(
+ fragments.define_rule(id,
                     qi::char_(std::string(a_.begin(), a_.end())));
             }
         }
 
- utree eval(utree const& a, utree const& b) const
+ void define(utree const& a, utree const& b) const
         {
             // $$$ use exceptions here $$$.
             BOOST_ASSERT(a.which() == utree_type::string_type);
@@ -151,17 +159,23 @@
             BOOST_ASSERT(b_.size() == 1);
 
             // char_('x', 'y')
- return fragments.new_rule(qi::char_(a_[0], b_[0]));
+ fragments.define_rule(id, qi::char_(a_[0], b_[0]));
         }
 
         utree eval(scope const& env) const
         {
+ if (id != -1)
+ return id;
+ id = fragments.new_rule();
+
             if (a.empty())
- return eval();
+ define();
             else if (b.empty())
- return eval(a(env));
+ define(a(env));
             else
- return eval(a(env), b(env));
+ define(a(env), b(env));
+
+ return id;
         }
     };
 
@@ -191,22 +205,27 @@
     template <typename Fragments>
     struct kleene_function : actor<kleene_function<Fragments> >
     {
- Fragments& fragments;
+ mutable int id;
         function a;
+ Fragments& fragments;
         kleene_function(
             Fragments& fragments, function const& a)
- : a(a), fragments(fragments)
+ : id(-1), a(a), fragments(fragments)
         {
         }
 
- utree eval(utree const& a) const
+ void define(utree const& a) const
         {
- return fragments.new_rule(*fragments[a]); // *a
+ fragments.define_rule(id, *fragments[a]); // *a
         }
 
         utree eval(scope const& env) const
         {
- return eval(a(env));
+ if (id != -1)
+ return id;
+ id = fragments.new_rule();
+ define(a(env));
+ return id;
         }
     };
 
@@ -231,24 +250,29 @@
     template <typename Fragments>
     struct difference_function : actor<difference_function<Fragments> >
     {
- Fragments& fragments;
+ mutable int id;
         function a;
         function b;
+ Fragments& fragments;
         difference_function(
             Fragments& fragments, function const& a, function const& b)
- : a(a), b(b), fragments(fragments)
+ : id(-1), a(a), b(b), fragments(fragments)
         {
         }
 
- utree eval(utree const& a, utree const& b) const
+ void define(utree const& a, utree const& b) const
         {
- return fragments.new_rule(
+ fragments.define_rule(id,
                 fragments[a] - fragments[b]); // a - b
         }
 
         utree eval(scope const& env) const
         {
- return eval(a(env), b(env));
+ if (id != -1)
+ return id;
+ id = fragments.new_rule();
+ define(a(env), b(env));
+ return id;
         }
     };
 
@@ -277,48 +301,53 @@
     template <typename Fragments>
     struct sequence_function : actor<sequence_function<Fragments> >
     {
- Fragments& fragments;
+ mutable int id;
         actor_list elements;
+ Fragments& fragments;
         sequence_function(
             Fragments& fragments, actor_list const& elements)
- : elements(elements), fragments(fragments)
+ : id(-1), elements(elements), fragments(fragments)
         {
         }
 
- utree eval(utree const& a, utree const& b) const
+ void define(utree const& a, utree const& b) const
         {
             // a >> b
- return fragments.new_rule(
+ fragments.define_rule(id,
                 fragments[a] >> fragments[b]);
         }
 
- utree eval(utree const& a, utree const& b, utree const& c) const
+ void define(utree const& a, utree const& b, utree const& c) const
         {
             // a >> b >> c
- return fragments.new_rule(
+ fragments.define_rule(id,
                 fragments[a] >> fragments[b] >> fragments[c]);
         }
 
- utree eval(utree const& a, utree const& b, utree const& c,
+ void define(utree const& a, utree const& b, utree const& c,
             utree const& d) const
         {
             // a >> b >> c >> d
- return fragments.new_rule(
+ fragments.define_rule(id,
                 fragments[a] >> fragments[b] >> fragments[c] >>
                 fragments[d]);
         }
 
- utree eval(utree const& a, utree const& b, utree const& c,
+ void define(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.define_rule(id,
                 fragments[a] >> fragments[b] >> fragments[c] >>
                 fragments[d] >> fragments[e]);
         }
 
         utree eval(scope const& env) const
         {
+ if (id != -1)
+ return id;
+ id = fragments.new_rule();
+
             actor_list::const_iterator i = elements.begin();
             switch (elements.size())
             {
@@ -326,14 +355,16 @@
                 {
                     function const& a = *i++;
                     function const& b = *i;
- return eval(a(env), b(env));
+ define(a(env), b(env));
+ break;
                 }
                 case 3:
                 {
                     function const& a = *i++;
                     function const& b = *i++;
                     function const& c = *i;
- return eval(a(env), b(env), c(env));
+ define(a(env), b(env), c(env));
+ break;
                 }
                 case 4:
                 {
@@ -341,7 +372,8 @@
                     function const& b = *i++;
                     function const& c = *i++;
                     function const& d = *i;
- return eval(a(env), b(env), c(env), d(env));
+ define(a(env), b(env), c(env), d(env));
+ break;
                 }
                 case 5:
                 {
@@ -350,12 +382,13 @@
                     function const& c = *i++;
                     function const& d = *i++;
                     function const& e = *i;
- return eval(a(env), b(env), c(env), d(env), e(env));
+ define(a(env), b(env), c(env), d(env), e(env));
+ break;
                 }
 
                 // $$$ Use Boost PP using SCHEME_QI_COMPILER_LIMIT $$$
             }
- return utree();
+ return id;
         }
     };
 
@@ -380,48 +413,53 @@
     template <typename Fragments>
     struct alternative_function : actor<alternative_function<Fragments> >
     {
- Fragments& fragments;
+ mutable int id;
         actor_list elements;
+ Fragments& fragments;
         alternative_function(
             Fragments& fragments, actor_list const& elements)
- : elements(elements), fragments(fragments)
+ : id(-1), elements(elements), fragments(fragments)
         {
         }
 
- utree eval(utree const& a, utree const& b) const
+ void define(utree const& a, utree const& b) const
         {
             // a | b
- return fragments.new_rule(
+ fragments.define_rule(id,
                 fragments[a] | fragments[b]);
         }
 
- utree eval(utree const& a, utree const& b, utree const& c) const
+ void define(utree const& a, utree const& b, utree const& c) const
         {
             // a | b | c
- return fragments.new_rule(
+ fragments.define_rule(id,
                 fragments[a] | fragments[b] | fragments[c]);
         }
 
- utree eval(utree const& a, utree const& b, utree const& c,
+ void define(utree const& a, utree const& b, utree const& c,
             utree const& d) const
         {
             // a | b | c | d
- return fragments.new_rule(
+ fragments.define_rule(id,
                 fragments[a] | fragments[b] | fragments[c] |
                 fragments[d]);
         }
 
- utree eval(utree const& a, utree const& b, utree const& c,
+ void define(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.define_rule(id,
                 fragments[a] | fragments[b] | fragments[c] |
                 fragments[d] | fragments[e]);
         }
 
         utree eval(scope const& env) const
         {
+ if (id != -1)
+ return id;
+ id = fragments.new_rule();
+
             actor_list::const_iterator i = elements.begin();
             switch (elements.size())
             {
@@ -429,14 +467,16 @@
                 {
                     function const& a = *i++;
                     function const& b = *i;
- return eval(a(env), b(env));
+ define(a(env), b(env));
+ break;
                 }
                 case 3:
                 {
                     function const& a = *i++;
                     function const& b = *i++;
                     function const& c = *i;
- return eval(a(env), b(env), c(env));
+ define(a(env), b(env), c(env));
+ break;
                 }
                 case 4:
                 {
@@ -444,7 +484,8 @@
                     function const& b = *i++;
                     function const& c = *i++;
                     function const& d = *i;
- return eval(a(env), b(env), c(env), d(env));
+ define(a(env), b(env), c(env), d(env));
+ break;
                 }
                 case 5:
                 {
@@ -453,12 +494,13 @@
                     function const& c = *i++;
                     function const& d = *i++;
                     function const& e = *i;
- return eval(a(env), b(env), c(env), d(env), e(env));
+ define(a(env), b(env), c(env), d(env), e(env));
+ break;
                 }
 
                 // $$$ Use Boost PP using SCHEME_QI_COMPILER_LIMIT $$$
             }
- return utree();
+ return id;
         }
     };
 
@@ -574,11 +616,33 @@
         }
 
         interpreter parser(in, filename, &env);
+ rule_type calc = fragments[parser["expression"]()].alias();
+ std::string str;
+
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
 
- //~ fragments[parser["expression"]()];
+ char const* iter = str.c_str();
+ char const* end = iter + strlen(iter);
+ bool r = phrase_parse(iter, end, calc, space);
 
- BOOST_TEST(!test("1 + 1",
- fragments[parser["expression"]()], space));
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "-------------------------\n";
+ }
+ else
+ {
+ std::string rest(iter, end);
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing failed\n";
+ std::cout << "stopped at: \": " << rest << "\"\n";
+ std::cout << "-------------------------\n";
+ }
+ }
 
     }
 


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