$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61338 - in trunk/libs/spirit/example/scheme: example example/sexpr input support test/scheme
From: joel_at_[hidden]
Date: 2010-04-17 11:26:08
Author: djowel
Date: 2010-04-17 11:26:07 EDT (Sat, 17 Apr 2010)
New Revision: 61338
URL: http://svn.boost.org/trac/boost/changeset/61338
Log:
incorporated error handling and added error reporting tests.
Added:
   trunk/libs/spirit/example/scheme/example/sexpr/sexpr_error_test.cpp   (contents, props changed)
Text files modified: 
   trunk/libs/spirit/example/scheme/example/Jamfile               |     1                                         
   trunk/libs/spirit/example/scheme/input/error_handler.hpp       |    30 ++++++++++++++++++----------            
   trunk/libs/spirit/example/scheme/input/parse_sexpr.hpp         |    35 ++++++++++++++++++++++++--------        
   trunk/libs/spirit/example/scheme/input/parse_sexpr_impl.hpp    |    42 ++++++++++++++++++++++++++++----------- 
   trunk/libs/spirit/example/scheme/input/sexpr.hpp               |     4 +-                                      
   trunk/libs/spirit/example/scheme/support/line_pos_iterator.hpp |     4 +-                                      
   trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp  |     2                                         
   7 files changed, 81 insertions(+), 37 deletions(-)
Modified: trunk/libs/spirit/example/scheme/example/Jamfile
==============================================================================
--- trunk/libs/spirit/example/scheme/example/Jamfile	(original)
+++ trunk/libs/spirit/example/scheme/example/Jamfile	2010-04-17 11:26:07 EDT (Sat, 17 Apr 2010)
@@ -14,6 +14,7 @@
 
 exe sexpr_input_test : sexpr/sexpr_input_test.cpp ;
 exe sexpr_output_test : sexpr/sexpr_output_test.cpp ;
+exe sexpr_error_test : sexpr_error_test.cpp ;
 
 exe parse_qi_test
    : parse_qiexpr/generate_sexpr_to_ostream.cpp
Added: trunk/libs/spirit/example/scheme/example/sexpr/sexpr_error_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/example/sexpr/sexpr_error_test.cpp	2010-04-17 11:26:07 EDT (Sat, 17 Apr 2010)
@@ -0,0 +1,50 @@
+/*=============================================================================
+    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 <boost/config/warning_disable.hpp>
+
+#include <input/sexpr.hpp>
+#include <input/parse_sexpr_impl.hpp>
+#include <utree/io.hpp>
+#include <iostream>
+#include <fstream>
+
+inline std::ostream& println(std::ostream& out, scheme::utree const& val)
+{
+    out << val << std::endl;
+    return out;
+}
+
+void test(std::string const& in, std::string const& file)
+{
+    scheme::utree result;
+    if (scheme::input::parse_sexpr(in, result, file))
+    {
+        std::cout << "success: ";
+        println(std::cout, result);
+        std::cout << std::endl;
+    }
+    else
+    {
+        std::cout << "parse error" << std::endl;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//  Main program
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+    test("(abc def)", "ok.sexpr");
+    test("(abc (123 456) def)", "ok.sexpr");
+    test("(abc \n(\"a string\" 456) \ndef)", "ok.sexpr");
+    test("(abc \n(\"a string\" 456 \ndef)", "missing close paren.sexpr");
+    test("(abc \n(\"a string 456) \ndef)", "missing double quote.sexpr");
+    test("(abc \n(\"a string 0ggg) \ndef)", "erronoeus octal.sexpr");
+    return 0;
+}
+
+
Modified: trunk/libs/spirit/example/scheme/input/error_handler.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/error_handler.hpp	(original)
+++ trunk/libs/spirit/example/scheme/input/error_handler.hpp	2010-04-17 11:26:07 EDT (Sat, 17 Apr 2010)
@@ -9,6 +9,8 @@
 
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
+#include <support/line_pos_iterator.hpp>
+#include <string>
 #include <iostream>
 
 namespace scheme { namespace input
@@ -19,23 +21,29 @@
         template <typename, typename, typename, typename>
         struct result { typedef void type; };
 
+        std::string source_file;
+        error_handler(std::string const& source_file = "")
+          : source_file(source_file) {}
+
         void operator()(
             Iterator first, Iterator last,
             Iterator err_pos, boost::spirit::info const& what) const
         {
-            // Default handler
             Iterator eol = err_pos;
-            while (eol != last && *eol != '\n' && *eol != '\r')
-                ++eol;
+            int line = get_line(err_pos);
+
+            if (source_file != "")
+                std::cerr << source_file;
+
+            if (line != -1)
+            {
+                if (source_file != "")
+                    std::cerr << '(' << line << ')';
+                else
+                    std::cerr << "line(" << line << ')';
+            }
 
-            std::cerr
-                << "Error! Expecting "
-                << what
-                << " here: \""
-                << std::string(err_pos, eol)
-                << "\""
-                << std::endl
-            ;
+            std::cerr << " : Error! Expecting "  << what << std::endl;
         }
     };
 }}
Modified: trunk/libs/spirit/example/scheme/input/parse_sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/parse_sexpr.hpp	(original)
+++ trunk/libs/spirit/example/scheme/input/parse_sexpr.hpp	2010-04-17 11:26:07 EDT (Sat, 17 Apr 2010)
@@ -12,33 +12,50 @@
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/is_base_of.hpp>
 #include <iosfwd>
+#include <string>
 
 namespace scheme { namespace input
 {
     ///////////////////////////////////////////////////////////////////////////
     template <typename Char>
-    bool
-    parse_sexpr(std::basic_istream<Char>& is, utree& result);
+    bool parse_sexpr(
+        std::basic_istream<Char>& is,
+        utree& result,
+        std::string const& source_file = "");
 
     template <typename Char>
-    bool
-    parse_sexpr_list(std::basic_istream<Char>& is, utree& result);
+    bool parse_sexpr_list(
+        std::basic_istream<Char>& is,
+        utree& result,
+        std::string const& source_file = "");
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Range>
     typename boost::disable_if<
         boost::is_base_of<std::ios_base, Range>, bool>::type
-    parse_sexpr(Range const& rng, utree& result);
+    parse_sexpr(
+        Range const& rng,
+        utree& result,
+        std::string const& source_file = "");
 
     template <typename Range>
     typename boost::disable_if<
         boost::is_base_of<std::ios_base, Range>, bool>::type
-    parse_sexpr_list(Range const& rng, utree& result);
+    parse_sexpr_list(
+        Range const& rng,
+        utree& result,
+        std::string const& source_file = "");
 
     ///////////////////////////////////////////////////////////////////////////
-    bool parse_sexpr(utree const& in, utree& result);
-
-    bool parse_sexpr_list(utree const& in, utree& result);
+    bool parse_sexpr(
+        utree const& in,
+        utree& result,
+        std::string const& source_file = "");
+
+    bool parse_sexpr_list(
+        utree const& in,
+        utree& result,
+        std::string const& source_file = "");
 }}
 
 #endif
Modified: trunk/libs/spirit/example/scheme/input/parse_sexpr_impl.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/parse_sexpr_impl.hpp	(original)
+++ trunk/libs/spirit/example/scheme/input/parse_sexpr_impl.hpp	2010-04-17 11:26:07 EDT (Sat, 17 Apr 2010)
@@ -20,7 +20,10 @@
 {
     ///////////////////////////////////////////////////////////////////////////
     template <typename Char>
-    bool parse_sexpr(std::basic_istream<Char>& is, utree& result)
+    bool parse_sexpr(
+        std::basic_istream<Char>& is,
+        utree& result,
+        std::string const& source_file)
     {
         // no white space skipping in the stream!
         is.unsetf(std::ios::skipws);
@@ -35,7 +38,7 @@
         iterator_type first(sfirst);
         iterator_type last(slast);
 
-        scheme::input::sexpr<iterator_type> p;
+        scheme::input::sexpr<iterator_type> p(source_file);
         scheme::input::sexpr_white_space<iterator_type> ws;
 
         using boost::spirit::qi::phrase_parse;
@@ -44,7 +47,10 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Char>
-    bool parse_sexpr_list(std::basic_istream<Char>& is, utree& result)
+    bool parse_sexpr_list(
+        std::basic_istream<Char>& is,
+        utree& result,
+        std::string const& source_file)
     {
         // no white space skipping in the stream!
         is.unsetf(std::ios::skipws);
@@ -59,7 +65,7 @@
         iterator_type first(sfirst);
         iterator_type last(slast);
 
-        scheme::input::sexpr<iterator_type> p;
+        scheme::input::sexpr<iterator_type> p(source_file);
         scheme::input::sexpr_white_space<iterator_type> ws;
 
         using boost::spirit::qi::phrase_parse;
@@ -69,13 +75,16 @@
     ///////////////////////////////////////////////////////////////////////////
     template <typename Range>
     typename boost::disable_if<boost::is_base_of<std::ios_base, Range>, bool>::type
-    parse_sexpr(Range const& rng, utree& result)
+    parse_sexpr(
+        Range const& rng,
+        utree& result,
+        std::string const& source_file)
     {
         typedef
             line_pos_iterator<typename Range::const_iterator>
         iterator_type;
 
-        scheme::input::sexpr<iterator_type> p;
+        scheme::input::sexpr<iterator_type> p(source_file);
         scheme::input::sexpr_white_space<iterator_type> ws;
 
         iterator_type first(rng.begin());
@@ -87,13 +96,16 @@
 
     template <typename Range>
     typename boost::disable_if<boost::is_base_of<std::ios_base, Range>, bool>::type
-    parse_sexpr_list(Range const& rng, utree& result)
+    parse_sexpr_list(
+        Range const& rng,
+        utree& result,
+        std::string const& source_file)
     {
         typedef
             line_pos_iterator<typename Range::const_iterator>
         iterator_type;
 
-        scheme::input::sexpr<iterator_type> p;
+        scheme::input::sexpr<iterator_type> p(source_file);
         scheme::input::sexpr_white_space<iterator_type> ws;
 
         iterator_type first(rng.begin());
@@ -104,14 +116,20 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
-    bool parse_sexpr(utree const& in, utree& result)
+    bool parse_sexpr(
+        utree const& in,
+        utree& result,
+        std::string const& source_file)
     {
-        return parse_sexpr(in.as<utf8_string_range>(), result);
+        return parse_sexpr(in.as<utf8_string_range>(), result, source_file);
     }
 
-    bool parse_sexpr_list(utree const& in, utree& result)
+    bool parse_sexpr_list(
+        utree const& in,
+        utree& result,
+        std::string const& source_file)
     {
-        return parse_sexpr_list(in.as<utf8_string_range>(), result);
+        return parse_sexpr_list(in.as<utf8_string_range>(), result, source_file);
     }
 }}
 
Modified: trunk/libs/spirit/example/scheme/input/sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/sexpr.hpp	(original)
+++ trunk/libs/spirit/example/scheme/input/sexpr.hpp	2010-04-17 11:26:07 EDT (Sat, 17 Apr 2010)
@@ -66,8 +66,8 @@
         typename ErrorHandler = input::error_handler<Iterator> >
     struct sexpr : grammar<Iterator, sexpr_white_space<Iterator>, utree()>
     {
-        sexpr()
-          : sexpr::base_type(start), error_handler(ErrorHandler())
+        sexpr(std::string const& source_file = "")
+          : sexpr::base_type(start), error_handler(ErrorHandler(source_file))
         {
             real_parser<double, strict_real_policies<double> > strict_double;
             uint_parser<unsigned char, 16, 2, 2> hex2;
Modified: trunk/libs/spirit/example/scheme/support/line_pos_iterator.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/support/line_pos_iterator.hpp	(original)
+++ trunk/libs/spirit/example/scheme/support/line_pos_iterator.hpp	2010-04-17 11:26:07 EDT (Sat, 17 Apr 2010)
@@ -33,11 +33,11 @@
 
         line_pos_iterator()
           : line_pos_iterator::iterator_adaptor_(),
-            line(0), prev(0) {}
+            line(1), prev(0) {}
 
         explicit line_pos_iterator(Iterator base)
           : line_pos_iterator::iterator_adaptor_(base),
-            line(0), prev(0) {}
+            line(1), prev(0) {}
 
         std::size_t position() const
         {
Modified: trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp	(original)
+++ trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp	2010-04-17 11:26:07 EDT (Sat, 17 Apr 2010)
@@ -59,7 +59,7 @@
     }
 
     scheme::utree program;
-    BOOST_TEST(scheme::input::parse_sexpr_list(in, program));
+    BOOST_TEST(scheme::input::parse_sexpr_list(in, program, filename));
 
     scheme::environment env;
     scheme::build_basic_environment(env);