|
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