Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r60336 - trunk/libs/spirit/example/qi/scheme
From: joel_at_[hidden]
Date: 2010-03-08 00:02:42


Author: djowel
Date: 2010-03-08 00:02:40 EST (Mon, 08 Mar 2010)
New Revision: 60336
URL: http://svn.boost.org/trac/boost/changeset/60336

Log:
sexpr working
Added:
   trunk/libs/spirit/example/qi/scheme/sexpr_test.cpp
      - copied, changed from r60312, /trunk/libs/spirit/example/qi/scheme/sexpr.cpp
   trunk/libs/spirit/example/qi/scheme/sexpr_test.txt (contents, props changed)
   trunk/libs/spirit/example/qi/scheme/simple_print.hpp (contents, props changed)
Removed:
   trunk/libs/spirit/example/qi/scheme/sexpr.cpp
Text files modified:
   trunk/libs/spirit/example/qi/scheme/sexpr.hpp | 47 +++++
   trunk/libs/spirit/example/qi/scheme/sexpr_test.cpp | 66 ++++++-
   trunk/libs/spirit/example/qi/scheme/utree.hpp | 43 +++-
   trunk/libs/spirit/example/qi/scheme/utree_test.cpp | 333 ++++++++++++++++-----------------------
   4 files changed, 266 insertions(+), 223 deletions(-)

Deleted: trunk/libs/spirit/example/qi/scheme/sexpr.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/scheme/sexpr.cpp 2010-03-08 00:02:40 EST (Mon, 08 Mar 2010)
+++ (empty file)
@@ -1,28 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2010 Joel de Guzman
-
- 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 "sexpr.hpp"
-
-int main()
-{
- using namespace boost::spirit;
- using namespace boost::spirit::qi;
-
- char const* first = "\"this is a\\n hmmm... \\u20AC string\"";
- char const* last = first + std::strlen(first);
-
- scheme::string<char const*> p;
-
- std::string result;
- if (parse(first, last, p, result))
- std::cout << "success: '" << result << '\'' << std::endl;
- else
- std::cout << "parse error" << std::endl;
-
- return 0;
-}
-
-

Modified: trunk/libs/spirit/example/qi/scheme/sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/scheme/sexpr.hpp (original)
+++ trunk/libs/spirit/example/qi/scheme/sexpr.hpp 2010-03-08 00:02:40 EST (Mon, 08 Mar 2010)
@@ -20,6 +20,8 @@
 #include <boost/spirit/include/phoenix_operator.hpp>
 #include <boost/regex/pending/unicode_iterator.hpp>
 
+#include "utree.hpp"
+
 namespace scheme
 {
     using boost::spirit::unicode::char_;
@@ -31,6 +33,13 @@
     using boost::spirit::qi::_r1;
     using boost::spirit::qi::_1;
     using boost::spirit::qi::uint_parser;
+ using boost::spirit::qi::real_parser;
+ using boost::spirit::qi::strict_real_policies;
+ using boost::spirit::qi::char_set;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::hex;
+ using boost::spirit::qi::oct;
+ using boost::spirit::qi::no_case;
     using boost::phoenix::function;
 
     typedef boost::spirit::char_encoding::unicode unicode;
@@ -113,6 +122,44 @@
         rule<Iterator, unicode, void(std::string&)> str_esc;
         rule<Iterator, unicode, std::string()> start;
     };
+
+ template <typename Iterator>
+ struct sexpr : grammar<Iterator, unicode, white_space<Iterator>, utree()>
+ {
+ sexpr() : sexpr::base_type(start)
+ {
+ function<detail::push_utf8> push_utf8;
+ function<detail::push_esc> push_esc;
+
+ start = atom | list;
+
+ list = '(' >> *start >> ')';
+
+ atom = number [_val = _1]
+ | string [_val = _1]
+ | symbol [_val = _1]
+ ;
+
+ char const* symbol_start = "a-zA-Z!#$%&'*+,-./:;<=>?@[\\]^_`{|}~";
+ char const* symbol_rest = "a-zA-Z0-9!#$%&'*+,-./:;<=>?@[\\]^_`{|}~";
+
+ symbol = char_(symbol_start) [push_utf8(_val, _1)]
+ >> +char_(symbol_rest) [push_utf8(_val, _1)]
+ ;
+
+ number = strict_double [_val = _1]
+ | int_ [_val = _1]
+ | no_case["0x"] >> hex [_val = _1]
+ | '0' >> oct [_val = _1]
+ ;
+ }
+
+ rule<Iterator, unicode, white_space<Iterator>, utree()> start, list;
+ rule<Iterator, unicode, utree()> atom, number;
+ rule<Iterator, unicode, std::string()> symbol;
+ string<Iterator> string;
+ real_parser<double, strict_real_policies<double> > strict_double;
+ };
 }
 
 #endif

Copied: trunk/libs/spirit/example/qi/scheme/sexpr_test.cpp (from r60312, /trunk/libs/spirit/example/qi/scheme/sexpr.cpp)
==============================================================================
--- /trunk/libs/spirit/example/qi/scheme/sexpr.cpp (original)
+++ trunk/libs/spirit/example/qi/scheme/sexpr_test.cpp 2010-03-08 00:02:40 EST (Mon, 08 Mar 2010)
@@ -1,27 +1,65 @@
-/*=============================================================================
+/*=============================================================================
     Copyright (c) 2001-2010 Joel de Guzman
 
     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 "sexpr.hpp"
+#include "simple_print.hpp"
+#include <iostream>
+#include <fstream>
 
-int main()
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int main(int argc, char **argv)
 {
- using namespace boost::spirit;
- using namespace boost::spirit::qi;
-
- char const* first = "\"this is a\\n hmmm... \\u20AC string\"";
- char const* last = first + std::strlen(first);
-
- scheme::string<char const*> p;
-
- std::string result;
- if (parse(first, last, p, result))
- std::cout << "success: '" << result << '\'' << std::endl;
+ char const* filename;
+ if (argc > 1)
+ {
+ filename = argv[1];
+ }
     else
+ {
+ std::cerr << "Error: No input file provided." << std::endl;
+ return 1;
+ }
+
+ std::ifstream in(filename, std::ios_base::in);
+
+ if (!in)
+ {
+ std::cerr << "Error: Could not open input file: "
+ << filename << std::endl;
+ return 1;
+ }
+
+ std::string source_code; // We will read the contents here.
+ in.unsetf(std::ios::skipws); // No white space skipping!
+ std::copy(
+ std::istream_iterator<char>(in),
+ std::istream_iterator<char>(),
+ std::back_inserter(source_code));
+
+ typedef std::string::const_iterator iterator_type;
+ iterator_type first = source_code.begin();
+ iterator_type last = source_code.end();
+
+ scheme::sexpr<iterator_type> p;
+ scheme::white_space<iterator_type> ws;
+
+ scheme::utree result;
+ if (phrase_parse(first, last, p, ws, result))
+ {
+ std::cout << "success: ";
+ println(result);
+ std::cout << std::endl;
+ }
+ else
+ {
         std::cout << "parse error" << std::endl;
-
+ }
+
     return 0;
 }
 

Added: trunk/libs/spirit/example/qi/scheme/sexpr_test.txt
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/scheme/sexpr_test.txt 2010-03-08 00:02:40 EST (Mon, 08 Mar 2010)
@@ -0,0 +1 @@
+(123.45 "this is a \u20AC string" (92 ("another string" apple)))
\ No newline at end of file

Added: trunk/libs/spirit/example/qi/scheme/simple_print.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/scheme/simple_print.hpp 2010-03-08 00:02:40 EST (Mon, 08 Mar 2010)
@@ -0,0 +1,77 @@
+#if !defined(UTREE_SIMPLE_PRINT)
+#define UTREE_SIMPLE_PRINT
+
+#include "utree.hpp"
+#include <iostream>
+
+namespace
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // simple utree printing facility prints the utree in a single line
+ ///////////////////////////////////////////////////////////////////////////
+ void print(char ch);
+ void print(scheme::utree const& val);
+ void println(scheme::utree const& val);
+
+ // simple_print visitor
+ struct simple_print
+ {
+ typedef void result_type;
+
+ void operator()(scheme::utree::nil) const
+ {
+ std::cout << "nil";
+ }
+
+ template <typename T>
+ void operator()(T val) const
+ {
+ std::cout << val;
+ }
+
+ void operator()(bool b) const
+ {
+ std::cout << (b ? "true" : "false");
+ }
+
+ template <typename Iterator>
+ void operator()(boost::iterator_range<Iterator> const& range) const
+ {
+ // This code works for both strings and lists
+ typedef typename boost::iterator_range<Iterator>::const_iterator iterator;
+ bool const is_string = boost::is_pointer<Iterator>::value;
+ char const start = is_string ? '"' : '(';
+ char const end = is_string ? '"' : ')';
+
+ print(start);
+ for (iterator i = range.begin(); i != range.end(); ++i)
+ {
+ if (!is_string)
+ {
+ if (i != range.begin())
+ print(' ');
+ }
+ print(*i);
+ }
+ print(end);
+ }
+ };
+
+ inline void print(char ch)
+ {
+ std::cout << ch;
+ }
+
+ inline void print(scheme::utree const& val)
+ {
+ scheme::utree::visit(val, simple_print());
+ }
+
+ inline void println(scheme::utree const& val)
+ {
+ print(val);
+ std::cout << std::endl;
+ }
+}
+
+#endif
\ No newline at end of file

Modified: trunk/libs/spirit/example/qi/scheme/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/scheme/utree.hpp (original)
+++ trunk/libs/spirit/example/qi/scheme/utree.hpp 2010-03-08 00:02:40 EST (Mon, 08 Mar 2010)
@@ -18,8 +18,9 @@
 
 #if defined(BOOST_MSVC)
 # pragma warning(push)
-# pragma warning(disable: 4804) // unsafe mix of type 'const bool' and type 'const int' in operation
-# pragma warning(disable: 4805) // unsafe mix of type 'const bool' and type 'const int' in operation
+# pragma warning(disable: 4804)
+# pragma warning(disable: 4805)
+# pragma warning(disable: 4244)
 #endif
 
 namespace scheme { namespace detail
@@ -331,7 +332,7 @@
     {
         unsigned const size = l-f;
         char* str;
- if (size <= small_string_size)
+ if (size < small_string_size)
         {
             // if it fits, store it in-situ; the first byte
             // is the length of the string.
@@ -468,6 +469,7 @@
     template <typename T>
     inline void list::insert_before(T const& val, node* np)
     {
+ BOOST_ASSERT(np != 0);
         node* new_node = new node(val, np, np->prev);
         if (np->prev)
             np->prev->next = new_node;
@@ -480,6 +482,7 @@
     template <typename T>
     inline void list::insert_after(T const& val, node* np)
     {
+ BOOST_ASSERT(np != 0);
         node* new_node = new node(val, np->next, np);
         if (np->next)
             np->next->prev = new_node;
@@ -534,6 +537,7 @@
 
     inline list::node* list::erase(node* pos)
     {
+ BOOST_ASSERT(pos != 0);
         if (pos == first)
         {
             pop_front();
@@ -967,8 +971,16 @@
     inline utree::iterator utree::insert(iterator pos, T const& val)
     {
         ensure_list_type();
- l.insert_before(val, pos.node);
- return utree::iterator(pos.node->prev);
+ if (pos.node == l.last)
+ {
+ push_back(val);
+ return begin();
+ }
+ else
+ {
+ l.insert_before(val, pos.node);
+ return utree::iterator(pos.node->prev);
+ }
     }
 
 
@@ -984,7 +996,7 @@
     {
         ensure_list_type();
         while (first != last)
- l.insert_before(*first++, pos.node);
+ insert(pos, *first++);
     }
 
     template <typename Iter>
@@ -998,8 +1010,9 @@
 
     inline void utree::clear()
     {
- BOOST_ASSERT(get_type() == type::list_type);
+ // clear will always make this a nil type
         free();
+ set_type(type::nil_type);
     }
 
     inline void utree::pop_front()
@@ -1029,13 +1042,13 @@
 
     inline utree::iterator utree::begin()
     {
- BOOST_ASSERT(get_type() == type::list_type);
+ ensure_list_type();
         return iterator(l.first);
     }
 
     inline utree::iterator utree::end()
     {
- BOOST_ASSERT(get_type() == type::list_type);
+ ensure_list_type();
         return iterator(l.last);
     }
 
@@ -1053,14 +1066,18 @@
 
     inline bool utree::empty() const
     {
- BOOST_ASSERT(get_type() == type::list_type);
- return l.first == l.last;
+ if (get_type() == type::list_type)
+ return l.size == 0;
+ BOOST_ASSERT(get_type() == type::nil_type);
+ return true;
     }
 
     inline std::size_t utree::size() const
     {
- BOOST_ASSERT(get_type() == type::list_type);
- return l.size;
+ if (get_type() == type::list_type)
+ return l.size;
+ BOOST_ASSERT(get_type() == type::nil_type);
+ return 0;
     }
 
     inline utree& utree::front()

Modified: trunk/libs/spirit/example/qi/scheme/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/scheme/utree_test.cpp (original)
+++ trunk/libs/spirit/example/qi/scheme/utree_test.cpp 2010-03-08 00:02:40 EST (Mon, 08 Mar 2010)
@@ -1,213 +1,154 @@
 #include "utree.hpp"
+#include "simple_print.hpp"
 #include <iostream>
 
-namespace
-{
- ///////////////////////////////////////////////////////////////////////////
- // simple utree printing facility prints the utree in a single line
- ///////////////////////////////////////////////////////////////////////////
- void print(char ch);
- void print(scheme::utree const& val);
- void println(scheme::utree const& val);
-
- // simple_print visitor
- struct simple_print
- {
- typedef void result_type;
-
- void operator()(scheme::utree::nil) const
- {
- std::cout << "nil";
- }
-
- template <typename T>
- void operator()(T val) const
- {
- std::cout << val;
- }
-
- void operator()(bool b) const
- {
- std::cout << (b ? "true" : "false");
- }
-
- template <typename Iterator>
- void operator()(boost::iterator_range<Iterator> const& range) const
- {
- // This code works for both strings and lists
- typedef typename boost::iterator_range<Iterator>::const_iterator iterator;
- bool const is_string = boost::is_pointer<Iterator>::value;
- char const start = is_string ? '"' : '(';
- char const end = is_string ? '"' : ')';
-
- print(start);
- for (iterator i = range.begin(); i != range.end(); ++i)
- {
- if (!is_string)
- {
- if (i != range.begin())
- print(',');
- }
- print(*i);
- }
- print(end);
- }
- };
-
- inline void print(char ch)
- {
- std::cout << ch;
- }
-
- inline void print(scheme::utree const& val)
- {
- scheme::utree::visit(val, simple_print());
- }
-
- inline void println(scheme::utree const& val)
- {
- print(val);
- std::cout << std::endl;
- }
-}
-
 int main()
 {
     using scheme::utree;
     using scheme::ulist;
 
- {
- // test the size
- std::cout << "size of utree is: "
- << sizeof(scheme::utree) << " bytes" << std::endl;
- }
-
- {
- utree val;
- println(val);
- }
-
- {
- utree val(true);
- println(val);
- }
-
- {
- utree val(123);
- println(val);
- }
-
- {
- utree val(123.456);
- println(val);
- }
-
- {
- utree val("Hello, World");
- println(val);
- utree val2;
- val2 = val;
- println(val2);
- utree val3("Hello, World. Chuckie is back!!!");
- val = val3;
- println(val);
-
- utree val4("Apple");
- utree val5("Apple");
- BOOST_ASSERT(val4 == val5);
-
- utree val6("ApplePie");
- BOOST_ASSERT(val4 < val6);
- }
+ //~ {
+ //~ // test the size
+ //~ std::cout << "size of utree is: "
+ //~ << sizeof(scheme::utree) << " bytes" << std::endl;
+ //~ }
+
+ //~ {
+ //~ utree val;
+ //~ println(val);
+ //~ }
+
+ //~ {
+ //~ utree val(true);
+ //~ println(val);
+ //~ }
+
+ //~ {
+ //~ utree val(123);
+ //~ println(val);
+ //~ }
+
+ //~ {
+ //~ utree val(123.456);
+ //~ println(val);
+ //~ }
+
+ //~ {
+ //~ utree val("Hello, World");
+ //~ println(val);
+ //~ utree val2;
+ //~ val2 = val;
+ //~ println(val2);
+ //~ utree val3("Hello, World. Chuckie is back!!!");
+ //~ val = val3;
+ //~ println(val);
+
+ //~ utree val4("Apple");
+ //~ utree val5("Apple");
+ //~ BOOST_ASSERT(val4 == val5);
+
+ //~ utree val6("ApplePie");
+ //~ BOOST_ASSERT(val4 < val6);
+ //~ }
+
+ //~ {
+ //~ utree val;
+ //~ val.push_back(123);
+ //~ val.push_back("Chuckie");
+ //~ utree val2;
+ //~ val2.push_back(123.456);
+ //~ val2.push_back("Mah Doggie");
+ //~ val.push_back(val2);
+ //~ println(val);
+ //~ println(val.front());
+
+ //~ utree val3;
+ //~ val3.swap(val);
+ //~ println(val);
+ //~ val3.swap(val);
+ //~ println(val);
+ //~ val.push_back("Ba Ba Black Sheep");
+ //~ println(val);
+ //~ val.pop_front();
+ //~ println(val);
+ //~ utree::iterator i = val.begin();
+ //~ ++++i;
+ //~ val.insert(i, "Right in the middle");
+ //~ BOOST_ASSERT(val.size() == 4);
+ //~ println(val);
+ //~ val.pop_back();
+ //~ println(val);
+ //~ BOOST_ASSERT(val.size() == 3);
+ //~ val.erase(val.end());
+ //~ println(val);
+ //~ BOOST_ASSERT(val.size() == 2);
+
+ //~ val.insert(val.begin(), val2.begin(), val2.end());
+ //~ println(val);
+ //~ }
 
     {
         utree val;
- val.push_back(123);
- val.push_back("Chuckie");
- utree val2;
- val2.push_back(123.456);
- val2.push_back("Mah Doggie");
- val.push_back(val2);
- println(val);
- println(val.front());
-
- utree val3;
- val3.swap(val);
- println(val);
- val3.swap(val);
- println(val);
- val.push_back("Ba Ba Black Sheep");
- println(val);
- val.pop_front();
- println(val);
- utree::iterator i = val.begin();
- ++++i;
- val.insert(i, "Right in the middle");
- BOOST_ASSERT(val.size() == 4);
- println(val);
- val.pop_back();
- println(val);
- BOOST_ASSERT(val.size() == 3);
- val.erase(val.end());
- println(val);
- BOOST_ASSERT(val.size() == 2);
-
- val.insert(val.begin(), val2.begin(), val2.end());
+ val.insert(val.end(), 123);
+ val.insert(val.end(), "Mia");
+ val.insert(val.end(), "Chuckie");
+ val.insert(val.end(), "Poly");
+ val.insert(val.end(), "Mochi");
         println(val);
     }
 
- {
- utree a, b;
- BOOST_ASSERT(a == b);
- a = 123;
- BOOST_ASSERT(a != b);
- b = 123;
- BOOST_ASSERT(a == b);
- a = 100.00;
- BOOST_ASSERT(a < b);
-
- b = a = ulist();
- BOOST_ASSERT(a == b);
- a.push_back(1);
- a.push_back("two");
- a.push_back(3.0);
- b.push_back(1);
- b.push_back("two");
- b.push_back(3.0);
- BOOST_ASSERT(a == b);
- b.push_back(4);
- BOOST_ASSERT(a != b);
- BOOST_ASSERT(a < b);
- }
-
- {
- ulist a;
- a.push_back(1);
- a.push_back(2);
- a.push_back(3);
- a.push_back(4);
- a.push_back(5);
- a.push_back(6);
- a.push_back(7);
- a.push_back(8);
- a.push_back(9);
- a.push_back(10);
- a.push_back(11);
- a.push_back(12);
-
- BOOST_ASSERT(a[0] == utree(1));
- BOOST_ASSERT(a[1] == utree(2));
- BOOST_ASSERT(a[2] == utree(3));
- BOOST_ASSERT(a[3] == utree(4));
- BOOST_ASSERT(a[4] == utree(5));
- BOOST_ASSERT(a[5] == utree(6));
- BOOST_ASSERT(a[6] == utree(7));
- BOOST_ASSERT(a[7] == utree(8));
- BOOST_ASSERT(a[8] == utree(9));
- BOOST_ASSERT(a[9] == utree(10));
- BOOST_ASSERT(a[10] == utree(11));
- BOOST_ASSERT(a[11] == utree(12));
- }
+ //~ {
+ //~ utree a, b;
+ //~ BOOST_ASSERT(a == b);
+ //~ a = 123;
+ //~ BOOST_ASSERT(a != b);
+ //~ b = 123;
+ //~ BOOST_ASSERT(a == b);
+ //~ a = 100.00;
+ //~ BOOST_ASSERT(a < b);
+
+ //~ b = a = ulist();
+ //~ BOOST_ASSERT(a == b);
+ //~ a.push_back(1);
+ //~ a.push_back("two");
+ //~ a.push_back(3.0);
+ //~ b.push_back(1);
+ //~ b.push_back("two");
+ //~ b.push_back(3.0);
+ //~ BOOST_ASSERT(a == b);
+ //~ b.push_back(4);
+ //~ BOOST_ASSERT(a != b);
+ //~ BOOST_ASSERT(a < b);
+ //~ }
+
+ //~ {
+ //~ ulist a;
+ //~ a.push_back(1);
+ //~ a.push_back(2);
+ //~ a.push_back(3);
+ //~ a.push_back(4);
+ //~ a.push_back(5);
+ //~ a.push_back(6);
+ //~ a.push_back(7);
+ //~ a.push_back(8);
+ //~ a.push_back(9);
+ //~ a.push_back(10);
+ //~ a.push_back(11);
+ //~ a.push_back(12);
+
+ //~ BOOST_ASSERT(a[0] == utree(1));
+ //~ BOOST_ASSERT(a[1] == utree(2));
+ //~ BOOST_ASSERT(a[2] == utree(3));
+ //~ BOOST_ASSERT(a[3] == utree(4));
+ //~ BOOST_ASSERT(a[4] == utree(5));
+ //~ BOOST_ASSERT(a[5] == utree(6));
+ //~ BOOST_ASSERT(a[6] == utree(7));
+ //~ BOOST_ASSERT(a[7] == utree(8));
+ //~ BOOST_ASSERT(a[8] == utree(9));
+ //~ BOOST_ASSERT(a[9] == utree(10));
+ //~ BOOST_ASSERT(a[10] == utree(11));
+ //~ BOOST_ASSERT(a[11] == utree(12));
+ //~ }
 
     return 0;
 }


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