|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r61564 - in trunk/libs/spirit/example/scheme: scheme test test/scheme
From: joel_at_[hidden]
Date: 2010-04-25 22:02:49
Author: djowel
Date: 2010-04-25 22:02:48 EDT (Sun, 25 Apr 2010)
New Revision: 61564
URL: http://svn.boost.org/trac/boost/changeset/61564
Log:
updates
Text files modified:
trunk/libs/spirit/example/scheme/scheme/compiler.hpp | 15 ++-
trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp | 146 +++++++++++++++++++++++++++++++++++----
trunk/libs/spirit/example/scheme/test/scheme/scheme_test3.cpp | 14 +++
3 files changed, 149 insertions(+), 26 deletions(-)
Modified: trunk/libs/spirit/example/scheme/scheme/compiler.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme/compiler.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme/compiler.hpp 2010-04-25 22:02:48 EDT (Sun, 25 Apr 2010)
@@ -555,11 +555,12 @@
interpreter(
Source& in,
std::string const& source_file = "",
- environment* outer = 0)
- : env(outer)
+ environment* envp = 0)
{
- if (outer == 0)
+ if (envp == 0)
build_basic_environment(env);
+ else
+ env = *envp;
if (input::parse_sexpr_list(in, program, source_file))
{
@@ -569,11 +570,13 @@
interpreter(
utree const& program,
- environment* outer = 0)
- : env(outer)
+ environment* envp = 0)
{
- if (outer == 0)
+ if (envp == 0)
build_basic_environment(env);
+ else
+ env = *envp;
+
compile_all(program, env, flist, fragments);
}
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 22:02:48 EDT (Sun, 25 Apr 2010)
@@ -13,7 +13,9 @@
#include <utree/io.hpp>
#include <boost/spirit/include/qi.hpp>
-namespace scheme
+#include "../../../test/qi/test.hpp"
+
+namespace scheme { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// parser compiler
@@ -24,6 +26,10 @@
typedef qi::rule<char const*> skipper_type;
typedef qi::rule<char const*, utree(), skipper_type> rule_type;
+ ///////////////////////////////////////////////////////////////////////////
+ // All rule are stored here. Rules are held in the utree by its id;
+ // i.e. it's index in the vector.
+ ///////////////////////////////////////////////////////////////////////////
template <typename Rule>
class rule_fragments
{
@@ -32,18 +38,21 @@
rule_fragments() {};
template <typename Expr>
- boost::tuple<Rule const&, int>
- new_rule(Expr const& expr)
+ int new_rule(Expr const& expr)
{
rules.push_back(Rule());
rules.front() = expr;
- return boost::tuple<Rule const&, int>(
- rules.front(), rules.size()-1);
+ return rules.size()-1;
}
Rule const& get_rule(int id) const
{
- return rules[i];
+ return rules[id];
+ }
+
+ Rule const& get_rule(utree const& id) const
+ {
+ return rules[id.get<int>()];
}
private:
@@ -51,6 +60,11 @@
std::vector<Rule> rules;
};
+ ///////////////////////////////////////////////////////////////////////////
+ // Composes primitive parsers held by index. Handles the compilation of
+ // primitive (nullary) parsers such as int_, double_, alpha, space and all
+ // those that require no arguments.
+ ///////////////////////////////////////////////////////////////////////////
struct primitive_parser_composite : composite<primitive_parser_composite>
{
int id;
@@ -69,43 +83,141 @@
inline primitive_parser_composite
make_primitive_parser_composite(Fragments& fragments, Expr const& expr)
{
- return primitive_parser_composite(
- boost::get<1>(fragments.new_rule(expr)));
+ return primitive_parser_composite(fragments.new_rule(expr));
}
+ ///////////////////////////////////////////////////////////////////////////
+ // Handles the compilation of char_
+ ///////////////////////////////////////////////////////////////////////////
template <typename Fragments>
- void build_qi_environment(Fragments& fragments, environment& env)
+ struct char_function : actor<char_function<Fragments> >
+ {
+ Fragments& fragments;
+ function a;
+ function b;
+ char_function(
+ Fragments& fragments, function const& a, function const& b)
+ : a(a), b(b), fragments(fragments)
+ {
+ }
+
+ utree eval(utree const& a) const
+ {
+ // $$$ use exceptions here $$$.
+ BOOST_ASSERT(a.which() == utree_type::string_type);
+
+ utf8_string_range a_ = a.get<utf8_string_range>();
+ if (a_.size() == 1)
+ {
+ // char_('x')
+ return fragments.new_rule(qi::char_(a_[0]));
+ }
+ else
+ {
+ // char_("some-regex")
+ return fragments.new_rule(
+ qi::char_(std::string(a_.begin(), a_.end())));
+ }
+ }
+
+ utree eval(utree const& a, utree const& b) const
+ {
+ // $$$ use exceptions here $$$.
+ BOOST_ASSERT(a.which() == utree_type::string_type);
+ BOOST_ASSERT(b.which() == utree_type::string_type);
+
+ utf8_string_range a_ = a.get<utf8_string_range>();
+ utf8_string_range b_ = b.get<utf8_string_range>();
+ // $$$ use exceptions here $$$.
+ BOOST_ASSERT(a_.size() == 1);
+ BOOST_ASSERT(b_.size() == 1);
+
+ // char_('x', 'y')
+ return fragments.new_rule(qi::char_(a_[0], b_[0]));
+ }
+
+ utree eval(scope const& env) const
+ {
+ if (b.empty())
+ return eval(a(env));
+ else
+ return eval(a(env), b(env));
+ }
+ };
+
+ template <typename Fragments>
+ struct unary_char_composite
+ : composite<unary_char_composite<Fragments> >
+ {
+ Fragments& fragments;
+ unary_char_composite(Fragments& fragments)
+ : fragments(fragments) {}
+
+ function compose(actor_list const& elements) const
+ {
+ typedef char_function<Fragments> function_type;
+ actor_list::const_iterator i = elements.begin();
+
+ function empty;
+ function const& a = *i++;
+ function const& b = (i == elements.end())? empty : *i;
+ return function(function_type(fragments, a, b));
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Build our scheme compiler environment.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Fragments>
+ void build_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);
+
+ env.define("qi:char_",
+ unary_char_composite<Fragments>(fragments), 1, false);
}
-}
+}}
///////////////////////////////////////////////////////////////////////////////
// Main program
///////////////////////////////////////////////////////////////////////////////
int main()
{
+ using scheme::utree;
using scheme::interpreter;
using scheme::environment;
- using scheme::build_qi_environment;
- using scheme::rule_fragments;
- using scheme::rule_type;
- using scheme::utree;
+ using scheme::qi::build_environment;
+ using scheme::qi::rule_fragments;
+ using scheme::qi::rule_type;
+ using spirit_test::test;
environment env;
rule_fragments<rule_type> fragments;
- build_qi_environment(fragments, env);
+ build_environment(fragments, env);
+
+ scheme::qi::skipper_type space = boost::spirit::qi::space;
{
- utree src = "(define foo 123)";
+ utree src =
+ "(define r (qi:char_ \"x\"))"
+ "(define r2 (qi:int_))";
interpreter parser(src, "parse.scm", &env);
- std::cout << parser["qi:int_"]() << std::endl;
+ //~ std::cout << parser["r"]() << std::endl;
+ //~ std::cout << parser["r2"]() << std::endl;
+
+ BOOST_TEST(test("x", fragments.get_rule(parser["r"]()), space));
+ BOOST_TEST(!test("y", fragments.get_rule(parser["r"]()), space));
+
+
}
return boost::report_errors();
Modified: trunk/libs/spirit/example/scheme/test/scheme/scheme_test3.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme/scheme_test3.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/scheme/scheme_test3.cpp 2010-04-25 22:02:48 EDT (Sun, 25 Apr 2010)
@@ -20,9 +20,17 @@
using scheme::interpreter;
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);
+ {
+ utree src = "(define n 123)";
+ scheme::interpreter program(src);
+ BOOST_TEST(program["n"]() == 123);
+ }
+
+ {
+ utree src = "(define (factorial n) (if (<= n 0) 1 (* n (factorial (- n 1)))))";
+ scheme::interpreter program(src);
+ BOOST_TEST(program["factorial"](10) == 3628800);
+ }
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