Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61230 - in trunk/libs/spirit/example/scheme: . detail input output test/parse_qiexpr
From: hartmut.kaiser_at_[hidden]
Date: 2010-04-12 15:49:29


Author: hkaiser
Date: 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
New Revision: 61230
URL: http://svn.boost.org/trac/boost/changeset/61230

Log:
Spirit: working on Spirit parser
Added:
   trunk/libs/spirit/example/scheme/utree_io.hpp (contents, props changed)
Text files modified:
   trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp | 11 ++
   trunk/libs/spirit/example/scheme/detail/utree_detail3.hpp | 26 ++----
   trunk/libs/spirit/example/scheme/input/parse_qiexpr_impl.hpp | 4
   trunk/libs/spirit/example/scheme/input/qiexpr.hpp | 101 +++++++++++++++++++++++----
   trunk/libs/spirit/example/scheme/output/sexpr.hpp | 12 ---
   trunk/libs/spirit/example/scheme/test/parse_qiexpr/input.txt | 19 ++++
   trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qi_test.cpp | 1
   trunk/libs/spirit/example/scheme/utree.hpp | 21 +++--
   trunk/libs/spirit/example/scheme/utree_operators.hpp | 147 ++++++++++++++++++++-------------------
   9 files changed, 215 insertions(+), 127 deletions(-)

Modified: trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp (original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -191,6 +191,7 @@
     inline void list::copy(list const& other)
     {
         first = last = 0;
+ size = 0;
         node* p = other.first;
         while (p != 0)
         {
@@ -963,6 +964,16 @@
     {
         return utree::visit(*this, utree_cast<T>());
     }
+
+ inline utree& utree::deref()
+ {
+ return (get_type() == type::reference_type) ? *p : *this;
+ }
+
+ inline utree const& utree::deref() const
+ {
+ return (get_type() == type::reference_type) ? *p : *this;
+ }
 }
 
 #if defined(BOOST_MSVC)

Modified: trunk/libs/spirit/example/scheme/detail/utree_detail3.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail3.hpp (original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail3.hpp 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -32,7 +32,6 @@
             utree_type::list_type);
         SCHEME_GET_UTREE_TYPE(boost::iterator_range<utree::const_iterator>,
             utree_type::list_type);
- SCHEME_GET_UTREE_TYPE(function_ptr, utree_type::function_type);
 
 #undef SCHEME_GET_UTREE_TYPE
 
@@ -119,26 +118,21 @@
                 return type(x.s.str(), x.s.size());
             }
         };
-
- template <>
- struct get_impl<function_ptr>
- {
- typedef function_ptr type;
- static type call(utree const& x)
- {
- return type(x.f);
- }
- };
     }
 
+ ///////////////////////////////////////////////////////////////////////////
     template <typename T>
- typename scheme::detail::get_impl<T>::type
- get(scheme::utree const& x)
+ typename detail::get_impl<T>::type
+ get(utree const& x)
     {
- if (x.which() != scheme::detail::get_utree_type<T>::value)
- throw boost::bad_get();
+ if (x.which() != detail::get_utree_type<T>::value)
+ {
+ if (x.which() == utree_type::reference_type)
+ return get<T>(x.deref());
 
- return scheme::detail::get_impl<T>::call(x);
+ throw boost::bad_get();
+ }
+ return detail::get_impl<T>::call(x);
     }
 }
 

Modified: trunk/libs/spirit/example/scheme/input/parse_qiexpr_impl.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/parse_qiexpr_impl.hpp (original)
+++ trunk/libs/spirit/example/scheme/input/parse_qiexpr_impl.hpp 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -24,7 +24,9 @@
         scheme::input::qiexpr<iterator_type> p;
         scheme::input::qiexpr_white_space<iterator_type> ws;
 
- return phrase_parse(str.begin(), str.end(), p, ws, result);
+ iterator_type begin = str.begin();
+ iterator_type end = str.end();
+ return phrase_parse(begin, end, p, ws, result) && begin == end;
     }
 }}
 

Modified: trunk/libs/spirit/example/scheme/input/qiexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/qiexpr.hpp (original)
+++ trunk/libs/spirit/example/scheme/input/qiexpr.hpp 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -13,12 +13,15 @@
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_stl.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
 
 #include "../utree.hpp"
 #include "../utree_operators.hpp"
 #include "string.hpp"
 
-namespace scheme { namespace input
+///////////////////////////////////////////////////////////////////////////////
+namespace scheme { namespace input
 {
     using boost::spirit::ascii::space;
     using boost::spirit::qi::grammar;
@@ -28,6 +31,7 @@
     using boost::spirit::qi::_val;
     using boost::spirit::qi::_1;
     using boost::phoenix::push_back;
+ using boost::phoenix::function;
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Iterator>
@@ -45,16 +49,56 @@
         rule<Iterator> start;
     };
 
+ namespace detail
+ {
+ ///////////////////////////////////////////////////////////////////////
+ // return true if the utree instance represents a list whose first
+ // element is a symbol node equal to the second argument
+ inline bool is_list_node(utree const& u, utf8_symbol const& symbol)
+ {
+ if (u.which() != utree_type::list_type)
+ return false;
+ return u.front() == symbol;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // ensure the given utree instance represents a list whose first
+ // element is the symbol this function object has been constructed from
+ struct make_list_node
+ {
+ template <typename S, typename C>
+ struct result { typedef void type; };
+
+ explicit make_list_node(char const* symbol_)
+ : symbol(symbol_)
+ {}
+
+ void operator()(utree& seq, utree const& element) const
+ {
+ if (!is_list_node(seq, symbol)) {
+ utree u;
+ u.push_back(symbol);
+ u.push_back(seq);
+ seq = u;
+ }
+ seq.push_back(element);
+ }
+
+ utf8_symbol symbol;
+ };
+ }
+
     ///////////////////////////////////////////////////////////////////////////
     // a list of names for all supported parser primitives taking no parameters
     static char const* const primitives0[] =
     {
- // character parsers
+ // character parsers
         "char_"
       , "alnum", "alpha", "blank", "cntrl", "digit", "graph", "print", "punct"
       , "space", "xdigit"
       , "lower", "upper"
- // numerics
+
+ // numerics
       , "long_long", "long_", "int_", "short_"
       , "ulong_long", "ulong_", "uint_", "ushort_"
       , "bin", "oct", "hex"
@@ -86,14 +130,39 @@
 
         qiexpr() : qiexpr::base_type(start)
         {
- start = *expr;
+ typedef function<detail::make_list_node> make_list_type;
+
+ make_list_type make_sequence = detail::make_list_node(">>");
+ make_list_type make_alternative = detail::make_list_node("|");
+
+ start = -alternative;
+
+ // A | B
+ alternative =
+ sequence [ _val = _1 ]
+ >> *( '|' >> sequence [ make_alternative(_val, _1) ] )
+ ;
 
- expr =
+ // A >> B
+ sequence =
+ term [ _val = _1 ]
+ >> *( ">>" >> term [ make_sequence(_val, _1) ] )
+ ;
+
+ // A, (A)
+ term =
+ primitive
+ | '(' >> alternative >> ')'
+ ;
+
+ // any primitive parser
+ primitive =
                     primitive2 >> '(' >> literal >> ',' >> literal >> ')'
                 | primitive1 >> '(' >> literal >> ')'
                 | primitive0 // taking no parameter
                 ;
 
+ // a literal (either 'x' or "abc")
             literal =
                     string_lit [ push_back(_val, _1) ]
                 | string_lit.char_lit [ push_back(_val, _1) ]
@@ -102,27 +171,29 @@
             // fill the symbol tables with all known primitive parser names
             for (char const* const* p = primitives0; *p; ++p)
             {
- utree l;
- l.push_back(utf8_symbol(*p));
- primitive0.add(*p, l);
+ utree u;
+ u.push_back(utf8_symbol(*p));
+ primitive0.add(*p, u);
             }
 
             for (char const* const* p = primitives1; *p; ++p)
             {
- utree l;
- l.push_back(utf8_symbol(*p));
- primitive1.add(*p, l);
+ utree u;
+ u.push_back(utf8_symbol(*p));
+ primitive1.add(*p, u);
             }
 
             for (char const* const* p = primitives2; *p; ++p)
             {
- utree l;
- l.push_back(utf8_symbol(*p));
- primitive2.add(*p, l);
+ utree u;
+ u.push_back(utf8_symbol(*p));
+ primitive2.add(*p, u);
             }
         }
 
- rule<Iterator, qiexpr_white_space<Iterator>, utree()> start, expr, literal;
+ typedef rule<Iterator, qiexpr_white_space<Iterator>, utree()> rule_type;
+
+ rule_type start, alternative, sequence, primitive, term, literal;
         symbols<char_type, utree> primitive0, primitive1, primitive2;
         scheme::input::string<Iterator> string_lit;
     };

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-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -132,15 +132,6 @@
         typedef scheme::binary_string compatible_type;
         typedef mpl::int_<scheme::utree_type::binary_type> distance;
     };
-
- template <>
- struct compute_compatible_component_variant<
- scheme::function_ptr, scheme::utree>
- : mpl::true_
- {
- typedef scheme::function_ptr compatible_type;
- typedef mpl::int_<scheme::utree_type::function_type> distance;
- };
 }}}
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -176,7 +167,6 @@
                       | symbol
                       | byte_str
                       | list
- | function_
                       | nil_
                       ;
 
@@ -185,7 +175,6 @@
             string_ = '"' << string << '"';
             symbol = string;
             byte_str = 'b' << *right_align(2, '0')[hex2];
- function_ = verbatim["function_ptr(" << hex << ")"];
             nil_ = eps;
         }
 
@@ -196,7 +185,6 @@
         rule<OutputIterator, utf8_symbol_range()> symbol;
         rule<OutputIterator, utf8_string_range()> string_;
         rule<OutputIterator, binary_range()> byte_str;
- rule<OutputIterator, function_ptr()> function_;
         rule<OutputIterator, nil()> nil_;
     };
 }}

Modified: trunk/libs/spirit/example/scheme/test/parse_qiexpr/input.txt
==============================================================================
--- trunk/libs/spirit/example/scheme/test/parse_qiexpr/input.txt (original)
+++ trunk/libs/spirit/example/scheme/test/parse_qiexpr/input.txt 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -3,7 +3,24 @@
 // 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)
  
-char_("abc")
+// parser primitives
 char_
+char_("abc")
 char_('a')
 char_('a', 'b')
+
+// 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')
+

Modified: trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qi_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qi_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qi_test.cpp 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -11,6 +11,7 @@
 #include <fstream>
 #include <iterator>
 
+#include "../../utree.hpp"
 #include "../../input/parse_qiexpr.hpp"
 #include "../../output/generate_sexpr.hpp"
 

Modified: trunk/libs/spirit/example/scheme/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree.hpp 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -12,13 +12,6 @@
 #include <string>
 #include <ostream>
 
-#if defined(BOOST_MSVC)
-# pragma warning(push)
-# pragma warning(disable: 4804)
-# pragma warning(disable: 4805)
-# pragma warning(disable: 4244)
-#endif
-
 #include <boost/assert.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/iterator/iterator_facade.hpp>
@@ -26,6 +19,13 @@
 #include <boost/ref.hpp>
 #include "detail/utree_detail1.hpp"
 
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4804)
+# pragma warning(disable: 4805)
+# pragma warning(disable: 4244)
+#endif
+
 namespace scheme
 {
     ///////////////////////////////////////////////////////////////////////////
@@ -259,6 +259,9 @@
         template <typename T>
         T as() const;
 
+ utree& deref();
+ utree const& deref() const;
+
     private:
 
         typedef utree_type type;
@@ -288,10 +291,10 @@
     };
 }
 
-#include "detail/utree_detail2.hpp"
-
 #if defined(BOOST_MSVC)
 # pragma warning(pop)
 #endif
 
+#include "detail/utree_detail2.hpp"
+
 #endif

Added: trunk/libs/spirit/example/scheme/utree_io.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/utree_io.hpp 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -0,0 +1,31 @@
+// 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(BOOST_SPIRIT_UTREE_IO)
+#define BOOST_SPIRIT_UTREE_IO
+
+#include "utree.hpp"
+#include "utree_operators.hpp"
+#include "input/parse_sexpr_impl.hpp"
+#include "output/generate_sexpr_impl.hpp"
+
+namespace scheme
+{
+ // Printing
+ inline std::ostream& operator<<(std::ostream& out, utree const& x)
+ {
+ output::generate_sexpr(out, x);
+ return out;
+ }
+
+ // Parsing
+ inline std::istream& operator>>(std::istream& in, utree& x)
+ {
+ input::parse_sexpr(in, x);
+ return in;
+ }
+}
+
+#endif

Modified: trunk/libs/spirit/example/scheme/utree_operators.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree_operators.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree_operators.hpp 2010-04-12 15:49:28 EDT (Mon, 12 Apr 2010)
@@ -28,8 +28,9 @@
     bool operator<=(utree const& a, utree const& b);
     bool operator>=(utree const& a, utree const& b);
 
- // Printing
+ // Input and output
     std::ostream& operator<<(std::ostream& out, utree const& x);
+ std::istream& operator>>(std::istream& in, utree& x);
 
     // Logical operators
     utree operator&&(utree const& a, utree const& b);
@@ -146,73 +147,73 @@
         }
     };
 
- struct utree_print
- {
- typedef void result_type;
-
- std::ostream& out;
- utree_print(std::ostream& out) : out(out) {}
-
- void operator()(scheme::nil) const
- {
- out << "nil";
- }
-
- template <typename T>
- void operator()(T val) const
- {
- out << val;
- }
-
- void operator()(bool b) const
- {
- out << (b ? "true" : "false");
- }
-
- void operator()(binary_range const& b) const
- {
- out << "b";
- out.width(2);
- out.fill('0');
-
- typedef binary_range::const_iterator iterator;
- for (iterator i = b.begin(); i != b.end(); ++i)
- out << std::hex << int((unsigned char)*i);
- out << std::dec;
- }
-
- void operator()(utf8_string_range const& str) const
- {
- typedef utf8_string_range::const_iterator iterator;
- iterator i = str.begin();
- out << '"';
- for (; i != str.end(); ++i)
- out << *i;
- out << '"';
- }
-
- void operator()(utf8_symbol_range const& str) const
- {
- typedef utf8_symbol_range::const_iterator iterator;
- iterator i = str.begin();
- for (; i != str.end(); ++i)
- out << *i;
- }
-
- template <typename Iterator>
- void operator()(boost::iterator_range<Iterator> const& range) const
- {
- typedef typename boost::iterator_range<Iterator>::const_iterator iterator;
- (*this)('(');
- for (iterator i = range.begin(); i != range.end(); ++i)
- {
- if (i != range.begin())
- (*this)(' ');
- scheme::utree::visit(*i, *this);
- }
- (*this)(')');
- }
- };
+// struct utree_print
+// {
+// typedef void result_type;
+//
+// std::ostream& out;
+// utree_print(std::ostream& out) : out(out) {}
+//
+// void operator()(scheme::nil) const
+// {
+// out << "nil";
+// }
+//
+// template <typename T>
+// void operator()(T val) const
+// {
+// out << val;
+// }
+//
+// void operator()(bool b) const
+// {
+// out << (b ? "true" : "false");
+// }
+//
+// void operator()(binary_range const& b) const
+// {
+// out << "b";
+// out.width(2);
+// out.fill('0');
+//
+// typedef binary_range::const_iterator iterator;
+// for (iterator i = b.begin(); i != b.end(); ++i)
+// out << std::hex << int((unsigned char)*i);
+// out << std::dec;
+// }
+//
+// void operator()(utf8_string_range const& str) const
+// {
+// typedef utf8_string_range::const_iterator iterator;
+// iterator i = str.begin();
+// out << '"';
+// for (; i != str.end(); ++i)
+// out << *i;
+// out << '"';
+// }
+//
+// void operator()(utf8_symbol_range const& str) const
+// {
+// typedef utf8_symbol_range::const_iterator iterator;
+// iterator i = str.begin();
+// for (; i != str.end(); ++i)
+// out << *i;
+// }
+//
+// template <typename Iterator>
+// void operator()(boost::iterator_range<Iterator> const& range) const
+// {
+// typedef typename boost::iterator_range<Iterator>::const_iterator iterator;
+// (*this)('(');
+// for (iterator i = range.begin(); i != range.end(); ++i)
+// {
+// if (i != range.begin())
+// (*this)(' ');
+// scheme::utree::visit(*i, *this);
+// }
+// (*this)(')');
+// }
+// };
 
     template <typename Base>
     struct logical_function
@@ -422,11 +423,11 @@
         return !(a < b);
     }
 
- inline std::ostream& operator<<(std::ostream& out, utree const& x)
- {
- utree::visit(x, utree_print(out));
- return out;
- }
+// inline std::ostream& operator<<(std::ostream& out, utree const& x)
+// {
+// utree::visit(x, utree_print(out));
+// return out;
+// }
 
     SCHEME_CREATE_LOGICAL_FUNCTION(and_, a&&b);
     SCHEME_CREATE_LOGICAL_FUNCTION(or_, a||b);


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