Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61347 - in trunk/libs/spirit/example/scheme: example/generate_qiexpr output qi utree/detail
From: hartmut.kaiser_at_[hidden]
Date: 2010-04-17 21:56:33


Author: hkaiser
Date: 2010-04-17 21:56:32 EDT (Sat, 17 Apr 2010)
New Revision: 61347
URL: http://svn.boost.org/trac/boost/changeset/61347

Log:
Spirit: big move forward with Qi expression generator
Added:
   trunk/libs/spirit/example/scheme/example/generate_qiexpr/input.txt (contents, props changed)
   trunk/libs/spirit/example/scheme/output/utree_traits.hpp (contents, props changed)
Text files modified:
   trunk/libs/spirit/example/scheme/example/generate_qiexpr/generate_qiexpr.cpp | 4
   trunk/libs/spirit/example/scheme/output/sexpr.hpp | 125 ---------------------------------------
   trunk/libs/spirit/example/scheme/qi/component_names.hpp | 7 ++
   trunk/libs/spirit/example/scheme/qi/qiexpr_generator.hpp | 95 ++++++++++++++++++-----------
   trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp | 10 +-
   trunk/libs/spirit/example/scheme/utree/detail/utree_detail3.hpp | 6
   6 files changed, 77 insertions(+), 170 deletions(-)

Modified: trunk/libs/spirit/example/scheme/example/generate_qiexpr/generate_qiexpr.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/example/generate_qiexpr/generate_qiexpr.cpp (original)
+++ trunk/libs/spirit/example/scheme/example/generate_qiexpr/generate_qiexpr.cpp 2010-04-17 21:56:32 EDT (Sat, 17 Apr 2010)
@@ -3,8 +3,8 @@
 // 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)
 
-#include "../../qi/generate_qiexpr.hpp"
-#include "../../qi/generate_qiexpr_impl.hpp"
+#include <qi/generate_qiexpr.hpp>
+#include <qi/generate_qiexpr_impl.hpp>
 
 // explicit template instantiation for the function generate_qiexpr
 namespace scheme { namespace output

Added: trunk/libs/spirit/example/scheme/example/generate_qiexpr/input.txt
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/example/generate_qiexpr/input.txt 2010-04-17 21:56:32 EDT (Sat, 17 Apr 2010)
@@ -0,0 +1,42 @@
+// Copyright (c) 2001-2010 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)
+
+// parser primitives
+char_
+char_("abc")
+char_('a')
+char_('a', 'b')
+'a'
+"abc"
+
+// sequences
+char_ >> char_
+char_ >> char_('a') >> char_('a', 'b')
+(char_ >> char_('a')) >> char_('a', 'b')
+char_ >> (char_('a') >> char_('a', 'b'))
+char_ >> (char_('a')) >> char_('a', 'b')
+
+// alternatives and sequences
+char_ | char_
+char_ | char_('a') >> char_('a', 'b')
+(char_ | char_('a')) | char_('a', 'b')
+char_ >> (char_('a') | char_('a', 'b'))
+char_ >> char_('a') | char_('a', 'b')
+(char_ >> char_('a')) | char_('a', 'b')
+
+// unary operators
+*double_
++*double_
++long_
+!+long_
+// &int_ >> double_
+// !int_ >> *double_
+// char_ >> *(',' >> char_)
+
+// directives
+// lexeme[*double_]
+
+
+

Modified: trunk/libs/spirit/example/scheme/output/sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/output/sexpr.hpp (original)
+++ trunk/libs/spirit/example/scheme/output/sexpr.hpp 2010-04-17 21:56:32 EDT (Sat, 17 Apr 2010)
@@ -8,6 +8,7 @@
 
 #include <utree/utree.hpp>
 #include <utree/detail/utree_detail3.hpp>
+#include <output/utree_traits.hpp>
 
 #include <string>
 
@@ -16,130 +17,6 @@
 #include <boost/spirit/include/karma.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace traits
-{
- // the specialization below tells Spirit to handle scheme::utree as if it
- // where a 'real' variant (in the context of karma)
- template <>
- struct not_is_variant<scheme::utree, karma::domain>
- : mpl::false_ {};
-
- // The specializations below tell Spirit to verify whether an attribute
- // type is compatible with a given variant type
- template <>
- struct compute_compatible_component_variant<
- boost::iterator_range<scheme::utree::iterator>, scheme::utree>
- : mpl::true_
- {
- typedef boost::iterator_range<scheme::utree::iterator> compatible_type;
- typedef mpl::int_<scheme::utree_type::list_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<
- boost::iterator_range<scheme::utree::const_iterator>, scheme::utree>
- : mpl::true_
- {
- typedef boost::iterator_range<scheme::utree::const_iterator> compatible_type;
- typedef mpl::int_<scheme::utree_type::list_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<scheme::nil, scheme::utree>
- : mpl::true_
- {
- typedef scheme::nil compatible_type;
- typedef mpl::int_<scheme::utree_type::nil_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<bool, scheme::utree>
- : mpl::true_
- {
- typedef bool compatible_type;
- typedef mpl::int_<scheme::utree_type::bool_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<int, scheme::utree>
- : mpl::true_
- {
- typedef int compatible_type;
- typedef mpl::int_<scheme::utree_type::int_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<double, scheme::utree>
- : mpl::true_
- {
- typedef double compatible_type;
- typedef mpl::int_<scheme::utree_type::double_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<
- scheme::utf8_string_range, scheme::utree>
- : mpl::true_
- {
- typedef scheme::utf8_string_range compatible_type;
- typedef mpl::int_<scheme::utree_type::string_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<
- scheme::utf8_string, scheme::utree>
- : mpl::true_
- {
- typedef scheme::utf8_string compatible_type;
- typedef mpl::int_<scheme::utree_type::string_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<
- scheme::utf8_symbol_range, scheme::utree>
- : mpl::true_
- {
- typedef scheme::utf8_symbol_range compatible_type;
- typedef mpl::int_<scheme::utree_type::symbol_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<
- scheme::utf8_symbol, scheme::utree>
- : mpl::true_
- {
- typedef scheme::utf8_symbol compatible_type;
- typedef mpl::int_<scheme::utree_type::symbol_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<
- scheme::binary_range, scheme::utree>
- : mpl::true_
- {
- typedef scheme::binary_range compatible_type;
- typedef mpl::int_<scheme::utree_type::binary_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<
- scheme::binary_string, scheme::utree>
- : mpl::true_
- {
- typedef scheme::binary_string compatible_type;
- typedef mpl::int_<scheme::utree_type::binary_type> distance;
- };
-
- template <>
- struct compute_compatible_component_variant<scheme::utree, scheme::utree>
- : mpl::true_
- {
- typedef scheme::utree compatible_type;
- typedef mpl::int_<scheme::utree_type::reference_type> distance;
- };
-}}}
-
-///////////////////////////////////////////////////////////////////////////////
 namespace scheme { namespace output
 {
     using boost::spirit::karma::grammar;

Added: trunk/libs/spirit/example/scheme/output/utree_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/output/utree_traits.hpp 2010-04-17 21:56:32 EDT (Sat, 17 Apr 2010)
@@ -0,0 +1,244 @@
+// Copyright (c) 2001-2010 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(SCHEME_OUTPUT_UTREE_TRAITS_APR_16_2010_0655AM)
+#define SCHEME_OUTPUT_UTREE_TRAITS_APR_16_2010_0655AM
+
+#include <utree/utree.hpp>
+
+#include <string>
+
+#include <boost/cstdint.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/spirit/include/karma.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // the specialization below tells Spirit to handle scheme::utree as if it
+ // where a 'real' variant (in the context of karma)
+ template <>
+ struct not_is_variant<scheme::utree, karma::domain>
+ : mpl::false_ {};
+
+ // The specializations below tell Spirit to verify whether an attribute
+ // type is compatible with a given variant type
+ template <>
+ struct compute_compatible_component_variant<
+ iterator_range<scheme::utree::iterator>, scheme::utree>
+ : mpl::true_
+ {
+ typedef iterator_range<scheme::utree::iterator> compatible_type;
+ typedef mpl::int_<scheme::utree_type::list_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<
+ iterator_range<scheme::utree::const_iterator>, scheme::utree>
+ : mpl::true_
+ {
+ typedef iterator_range<scheme::utree::const_iterator> compatible_type;
+ typedef mpl::int_<scheme::utree_type::list_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<scheme::nil, scheme::utree>
+ : mpl::true_
+ {
+ typedef scheme::nil compatible_type;
+ typedef mpl::int_<scheme::utree_type::nil_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<bool, scheme::utree>
+ : mpl::true_
+ {
+ typedef bool compatible_type;
+ typedef mpl::int_<scheme::utree_type::bool_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<int, scheme::utree>
+ : mpl::true_
+ {
+ typedef int compatible_type;
+ typedef mpl::int_<scheme::utree_type::int_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<double, scheme::utree>
+ : mpl::true_
+ {
+ typedef double compatible_type;
+ typedef mpl::int_<scheme::utree_type::double_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<
+ scheme::utf8_string_range, scheme::utree>
+ : mpl::true_
+ {
+ typedef scheme::utf8_string_range compatible_type;
+ typedef mpl::int_<scheme::utree_type::string_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<
+ scheme::utf8_string, scheme::utree>
+ : mpl::true_
+ {
+ typedef scheme::utf8_string compatible_type;
+ typedef mpl::int_<scheme::utree_type::string_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<
+ scheme::utf8_symbol_range, scheme::utree>
+ : mpl::true_
+ {
+ typedef scheme::utf8_symbol_range compatible_type;
+ typedef mpl::int_<scheme::utree_type::symbol_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<
+ scheme::utf8_symbol, scheme::utree>
+ : mpl::true_
+ {
+ typedef scheme::utf8_symbol compatible_type;
+ typedef mpl::int_<scheme::utree_type::symbol_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<
+ scheme::binary_range, scheme::utree>
+ : mpl::true_
+ {
+ typedef scheme::binary_range compatible_type;
+ typedef mpl::int_<scheme::utree_type::binary_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<
+ scheme::binary_string, scheme::utree>
+ : mpl::true_
+ {
+ typedef scheme::binary_string compatible_type;
+ typedef mpl::int_<scheme::utree_type::binary_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<scheme::utree, scheme::utree>
+ : mpl::true_
+ {
+ typedef iterator_range<scheme::utree::const_iterator> compatible_type;
+ typedef mpl::int_<scheme::utree_type::reference_type> distance;
+
+ static bool is_compatible(int d)
+ {
+ return d >= scheme::utree_type::nil_type &&
+ d <= scheme::utree_type::reference_type;
+ }
+ };
+
+ template <typename Sequence>
+ struct compute_compatible_component_variant<Sequence, scheme::utree
+ , mpl::false_
+ , typename enable_if<fusion::traits::is_sequence<Sequence> >::type>
+ : mpl::true_
+ {
+ typedef iterator_range<scheme::utree::const_iterator> compatible_type;
+ typedef mpl::int_<scheme::utree_type::list_type> distance;
+
+ static bool is_compatible(int d) { return d == distance::value; }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <>
+ struct symbols_lookup<scheme::utf8_symbol, scheme::utree>
+ {
+ typedef std::string type;
+
+ static type call(scheme::utree const& t)
+ {
+ return boost::get<scheme::utf8_symbol>(t);
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <>
+ struct extract_from_attribute<scheme::utree, scheme::utf8_symbol>
+ {
+ typedef std::string type;
+
+ template <typename Context>
+ static type call(scheme::utree const& attr, Context&)
+ {
+ return boost::get<scheme::utf8_symbol>(attr);
+ }
+ };
+
+ template <>
+ struct extract_from_attribute<scheme::utree, scheme::utf8_string>
+ {
+ typedef std::string type;
+
+ template <typename Context>
+ static type call(scheme::utree const& attr, Context&)
+ {
+ return boost::get<scheme::utf8_string>(attr);
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <>
+ struct transform_attribute<scheme::utree const, scheme::utf8_string, karma::domain>
+ {
+ typedef std::string type;
+
+ static type pre(scheme::utree const& val)
+ {
+ return boost::get<scheme::utf8_string>(val);
+ }
+ };
+
+ template <>
+ struct transform_attribute<scheme::utree const, scheme::utf8_symbol, karma::domain>
+ {
+ typedef std::string type;
+
+ static type pre(scheme::utree const& val)
+ {
+ return boost::get<scheme::utf8_symbol>(val);
+ }
+ };
+}}}
+
+#endif

Modified: trunk/libs/spirit/example/scheme/qi/component_names.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/qi/component_names.hpp (original)
+++ trunk/libs/spirit/example/scheme/qi/component_names.hpp 2010-04-17 21:56:32 EDT (Sat, 17 Apr 2010)
@@ -67,6 +67,13 @@
       , "ascii", "standard", "standard_wide", "iso8859_1", "unicode"
       , 0
     };
+
+ // a list of names for all supported unary parser operators
+ static char const* const unary_names[] =
+ {
+ "*", "+", "-", "!", "&"
+ , 0
+ };
 }}
 
 #endif

Modified: trunk/libs/spirit/example/scheme/qi/qiexpr_generator.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/qi/qiexpr_generator.hpp (original)
+++ trunk/libs/spirit/example/scheme/qi/qiexpr_generator.hpp 2010-04-17 21:56:32 EDT (Sat, 17 Apr 2010)
@@ -14,34 +14,10 @@
 #include <utree/utree.hpp>
 #include <utree/detail/utree_detail3.hpp>
 #include <utree/operators.hpp>
+#include <output/utree_traits.hpp>
 #include <qi/component_names.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace traits
-{
- template <>
- struct symbols_lookup<scheme::utree, std::string>
- {
- typedef std::string type;
- static type call(scheme::utree const& t)
- {
- BOOST_ASSERT(t.which() == scheme::utree_type::list_type);
- return boost::get<scheme::utf8_symbol>(t.front());
- }
- };
-
- template <>
- struct symbols_value<scheme::utree, std::string>
- {
- typedef unused_type type;
- static type call(scheme::utree const& t)
- {
- return unused;
- }
- };
-}}}
-
-///////////////////////////////////////////////////////////////////////////////
 namespace scheme { namespace qi
 {
     using boost::spirit::karma::grammar;
@@ -56,30 +32,77 @@
         qiexpr_generator() : qiexpr_generator::base_type(start)
         {
             using boost::spirit::karma::eps;
+ using boost::spirit::karma::string;
+ using boost::spirit::karma::omit;
+ using boost::spirit::karma::repeat;
+ using boost::spirit::karma::_r1;
+
+ start =
+ nil
+ | alternative
+ ;
+
+ alternative =
+ &symbol(std::string("|")) << '(' << permutation % '|' << ')'
+ | permutation
+ ;
 
- start = term.alias();
+ permutation =
+ &symbol(std::string("^")) << '(' << sequence % '^' << ')'
+ | sequence
+ ;
 
- term =
-// primitives2 << '(' << string << ',' << string << ')'
-// | primitives1 << '(' << string << ')'
- /*|*/ primitive0
+ sequence =
+ &symbol(std::string(">>")) << '(' << term % ">>" << ')'
+ | term
                 ;
 
+ term =
+ unary << repeat(1)[alternative]
+ | primitive2 << '(' << literal << ',' << literal << ')'
+ | primitive1 << '(' << literal << ')'
+ | primitive0 << -omit[node]
+ ;
+
+ symbol = string(_r1);
+ literal = '"' << string << '"';
+ node = eps;
+ nil = eps;
+
             // fill the symbol tables with all known primitive parser names
             for (char const* const* p = primitives0; *p; ++p)
- primitive0.add(*p);
+ primitive0.add(utf8_symbol(*p));
 
             for (char const* const* p = primitives1; *p; ++p)
- primitive1.add(*p);
+ primitive1.add(utf8_symbol(*p));
 
             for (char const* const* p = primitives2; *p; ++p)
- primitive2.add(*p);
+ primitive2.add(utf8_symbol(*p));
+
+ for (char const* const* p = unary_names; *p; ++p)
+ unary.add(utf8_symbol(*p));
+
+ start.name("start");
+ alternative.name("alternative");
+ permutation.name("permutation");
+ sequence.name("sequence");
+ term.name("term");
+ node.name("node");
+ literal.name("string");
+ nil.name("nil");
         }
 
- typedef rule<OutputIterator, space_type, utree()> rule_type;
+ typedef rule<OutputIterator, space_type, utree()> delimiting_rule_type;
+ typedef rule<OutputIterator, utree()> rule_type;
+
+ delimiting_rule_type start, alternative, permutation, sequence, term;
+ rule_type node;
+ rule<OutputIterator, nil()> nil;
+ rule<OutputIterator, scheme::utf8_string()> literal;
+ rule<OutputIterator, scheme::utf8_symbol(std::string)> symbol;
 
- rule_type start, term;
- symbols<std::string> primitive0, primitive1, primitive2;
+ symbols<scheme::utf8_symbol> primitive0, primitive1, primitive2;
+ symbols<scheme::utf8_symbol> unary;
     };
 }}
 

Modified: trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp (original)
+++ trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp 2010-04-17 21:56:32 EDT (Sat, 17 Apr 2010)
@@ -184,11 +184,11 @@
 
             // unary operators
             unary_term =
- '*' >> term [ make_kleene(_val, _1) ]
- | '+' >> term [ make_plus(_val, _1) ]
- | '-' >> term [ make_optional(_val, _1) ]
- | '&' >> term [ make_and_pred(_val, _1) ]
- | '!' >> term [ make_not_pred(_val, _1) ]
+ '*' >> alternative [ make_kleene(_val, _1) ]
+ | '+' >> alternative [ make_plus(_val, _1) ]
+ | '-' >> alternative [ make_optional(_val, _1) ]
+ | '&' >> alternative [ make_and_pred(_val, _1) ]
+ | '!' >> alternative [ make_not_pred(_val, _1) ]
                 | term [ _val = _1 ]
                 ;
 

Modified: trunk/libs/spirit/example/scheme/utree/detail/utree_detail3.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree/detail/utree_detail3.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree/detail/utree_detail3.hpp 2010-04-17 21:56:32 EDT (Sat, 17 Apr 2010)
@@ -162,12 +162,12 @@
     typename scheme::detail::get_impl<T>::type
     get(scheme::utree const& x)
     {
+ if (x.which() == scheme::utree_type::reference_type)
+ return get<T>(x.deref());
+
         if (x.which() !=
             (scheme::utree_type::info)scheme::detail::get_utree_type<T>::value)
         {
- if (x.which() == scheme::utree_type::reference_type)
- return get<T>(x.deref());
-
             throw boost::bad_get();
         }
         return scheme::detail::get_impl<T>::call(x);


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