$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r55168 - in trunk/libs/spirit/repository: example/qi test test/qi
From: hartmut.kaiser_at_[hidden]
Date: 2009-07-30 14:42:20
Author: hkaiser
Date: 2009-07-25 21:19:22 EDT (Sat, 25 Jul 2009)
New Revision: 55168
URL: http://svn.boost.org/trac/boost/changeset/55168
Log:
Spirit: Added qi::distinct parser tests and examples
Added:
   trunk/libs/spirit/repository/example/qi/distinct.cpp   (contents, props changed)
   trunk/libs/spirit/repository/test/qi/distinct.cpp   (contents, props changed)
   trunk/libs/spirit/repository/test/qi/test.hpp   (contents, props changed)
Text files modified: 
   trunk/libs/spirit/repository/test/CMakeLists.txt |     1 +                                       
   trunk/libs/spirit/repository/test/Jamfile        |     1 +                                       
   2 files changed, 2 insertions(+), 0 deletions(-)
Added: trunk/libs/spirit/repository/example/qi/distinct.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/example/qi/distinct.cpp	2009-07-25 21:19:22 EDT (Sat, 25 Jul 2009)
@@ -0,0 +1,60 @@
+//  Copyright (c) 2001-2009 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)
+
+//  The purpose of this example is to demonstrate different use cases for the
+//  distinct parser.
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+//[qi_distinct_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_distinct.hpp>
+//]
+
+//[qi_distinct_namespace
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+using boost::spirit::repository::distinct;
+//]
+
+int main()
+{
+    //[qi_distinct_declare_ident
+    {
+        std::string str("declare ident");
+        std::string::iterator first(str.begin());
+        bool r = qi::phrase_parse(first, str.end()
+          , distinct(alnum | '_')["declare"] >> -lit("--") >> +(alnum | '_')
+          , space);
+        BOOST_ASSERT(r && first == str.end());
+    }
+    //]
+
+    //[qi_distinct_declare__ident
+    {
+        std::string str("declare--ident");
+        std::string::iterator first(str.begin());
+        bool r = qi::phrase_parse(first, str.end()
+          , distinct(alnum | '_')["declare"] >> -lit("--") >> +(alnum | '_')
+          , space);
+        BOOST_ASSERT(r && first == str.end());
+    }
+    //]
+
+    //[qi_distinct_declare_ident_error
+    {
+        std::string str("declare-ident");
+        std::string::iterator first(str.begin());
+        bool r = qi::phrase_parse(first, str.end()
+          , distinct(alnum | '_')["declare"] >> -lit("--") >> +(alnum | '_')
+          , space);
+        BOOST_ASSERT(!r && first == str.begin());
+    }
+    //]
+
+    return 0;
+}
Modified: trunk/libs/spirit/repository/test/CMakeLists.txt
==============================================================================
--- trunk/libs/spirit/repository/test/CMakeLists.txt	(original)
+++ trunk/libs/spirit/repository/test/CMakeLists.txt	2009-07-25 21:19:22 EDT (Sat, 25 Jul 2009)
@@ -19,6 +19,7 @@
 ENDIF(CMAKE_COMPILER_IS_GNUCC)
 
 # run Qi repository tests
+boost_test_run(qi_repo_distinct qi/distinct.cpp COMPILE_FLAGS ${test_compile_flags})
 
 # run Karma repository tests
 boost_test_run(karma_repo_confix karma/confix.cpp COMPILE_FLAGS ${test_compile_flags})
Modified: trunk/libs/spirit/repository/test/Jamfile
==============================================================================
--- trunk/libs/spirit/repository/test/Jamfile	(original)
+++ trunk/libs/spirit/repository/test/Jamfile	2009-07-25 21:19:22 EDT (Sat, 25 Jul 2009)
@@ -22,6 +22,7 @@
     test-suite spirit_v2_repository :
 
     # run Qi repository tests
+    [ run qi/distinct.cpp                   : : : : qi_repo_distinct ]
 
     # run Karma repository tests
     [ run karma/confix.cpp                  : : : : karma_repo_confix ]
Added: trunk/libs/spirit/repository/test/qi/distinct.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/test/qi/distinct.cpp	2009-07-25 21:19:22 EDT (Sat, 25 Jul 2009)
@@ -0,0 +1,108 @@
+//  Copyright (c) 2001-2009 Hartmut Kaiser
+//  Copyright (c) 2001-2009 Joel de Guzman
+//  Copyright (c) 2003 Vaclav Vesely
+// 
+//  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/mpl/print.hpp>
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/qi_nonterminal.hpp>
+#include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_action.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+
+#include <boost/spirit/repository/include/qi_distinct.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+using namespace boost;
+
+///////////////////////////////////////////////////////////////////////////////
+//[qi_distinct_encapsulation
+namespace distinct
+{
+    namespace spirit = boost::spirit;
+    namespace ascii = boost::spirit::ascii;
+    namespace repo = boost::spirit::repository;
+
+    // Define metafunctions allowing to compute the type of the distinct()
+    // and ascii::char_() constructs
+    namespace traits
+    {
+        // Metafunction allowing to get the type of any repository::distinct(...) 
+        // construct
+        template <typename Tail>
+        struct distinct_spec
+        {
+            using namespace boost::spirit;
+            typedef typename spirit::result_of::terminal<
+                repository::tag::distinct(Tail)
+            >::type type;
+        };
+
+        // Metafunction allowing to get the type of any ascii::char_(...) construct
+        template <typename String>
+        struct char__spec
+        {
+            typedef typename spirit::result_of::terminal<
+                spirit::tag::ascii::char_(String)
+            >::type type;
+        };
+    };
+
+    // Define a helper function allowing to create a distinct() construct from 
+    // an arbitrary tail parser
+    template <typename Tail>
+    inline typename traits::distinct_spec<Tail>::type
+    distinct_spec(Tail const& tail)
+    {
+        return repo::distinct(tail);
+    }
+
+    // Define a helper function allowing to create a ascii::char_() construct 
+    // from an arbitrary string representation
+    template <typename String>
+    inline typename traits::char__spec<String>::type
+    char__spec(String const& str)
+    {
+        return ascii::char_(str);
+    }
+
+    // the following constructs the type of a distinct_spec holding 
+    // charset("0-9a-zA-Z_") as its tail parser
+    typedef traits::char__spec<std::string>::type charset_tag_type;
+    typedef traits::distinct_spec<charset_tag_type>::type keyword_tag_type;
+
+    // Define a new Qi keyword directive usable as a shortcut for a
+    // repository::distinct(char_(std::string("0-9a-zA-Z_")))
+    std::string const keyword_spec("0-9a-zA-Z_");
+    keyword_tag_type const keyword = distinct_spec(char__spec(keyword_spec)); 
+}
+//]
+
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+    using namespace spirit_test;
+    using namespace boost::spirit;
+
+    {
+        using namespace boost::spirit::ascii;
+
+        qi::rule<char const*, space_type> r;
+        r = distinct::keyword["declare"] >> -lit(':') >> distinct::keyword["ident"];
+
+        BOOST_TEST(test("declare ident", r, space));
+        BOOST_TEST(test("declare:ident", r, space));
+        BOOST_TEST(test("declare: ident", r, space));
+        BOOST_TEST(!test("declareident", r, space));
+    }
+
+    return boost::report_errors();
+}
+
Added: trunk/libs/spirit/repository/test/qi/test.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/test/qi/test.hpp	2009-07-25 21:19:22 EDT (Sat, 25 Jul 2009)
@@ -0,0 +1,103 @@
+/*=============================================================================
+    Copyright (c) 2001-2009 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)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM)
+#define BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM
+
+#include <boost/spirit/include/qi_parse.hpp>
+#include <boost/spirit/include/qi_what.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/foreach.hpp>
+#include <iostream>
+
+namespace spirit_test
+{
+    template <typename Char, typename Parser>
+    bool test(Char const* in, Parser const& p, bool full_match = true)
+    {
+        // we don't care about the result of the "what" function.
+        // we only care that all parsers have it:
+        boost::spirit::qi::what(p);
+
+        Char const* last = in;
+        while (*last)
+            last++;
+        return boost::spirit::qi::parse(in, last, p)
+            && (!full_match || (in == last));
+    }
+
+    template <typename Char, typename Parser, typename Skipper>
+    bool test(Char const* in, Parser const& p
+        , Skipper const& s, bool full_match = true)
+    {
+        // we don't care about the result of the "what" function.
+        // we only care that all parsers have it:
+        boost::spirit::qi::what(p);
+
+        Char const* last = in;
+        while (*last)
+            last++;
+        return boost::spirit::qi::phrase_parse(in, last, p, s)
+            && (!full_match || (in == last));
+    }
+
+    template <typename Char, typename Parser, typename Attr>
+    bool test_attr(Char const* in, Parser const& p
+        , Attr& attr, bool full_match = true)
+    {
+        // we don't care about the result of the "what" function.
+        // we only care that all parsers have it:
+        boost::spirit::qi::what(p);
+
+        Char const* last = in;
+        while (*last)
+            last++;
+        return boost::spirit::qi::parse(in, last, p, attr)
+            && (!full_match || (in == last));
+    }
+
+    template <typename Char, typename Parser, typename Attr, typename Skipper>
+    bool test_attr(Char const* in, Parser const& p
+        , Attr& attr, Skipper const& s, bool full_match = true)
+    {
+        // we don't care about the result of the "what" function.
+        // we only care that all parsers have it:
+        boost::spirit::qi::what(p);
+
+        Char const* last = in;
+        while (*last)
+            last++;
+        return boost::spirit::qi::phrase_parse(in, last, p, s, attr)
+            && (!full_match || (in == last));
+    }
+
+    struct printer
+    {
+        typedef boost::spirit::utf8_string string;
+
+        void element(string const& tag, string const& value, int depth) const
+        {
+            for (int i = 0; i < (depth*4); ++i) // indent to depth
+                std::cout << ' ';
+
+            std::cout << "tag: " << tag;
+            if (value != "")
+                std::cout << ", value: " << value;
+            std::cout << std::endl;
+        }
+    };
+
+    void print_info(boost::spirit::info const& what)
+    {
+        using boost::spirit::basic_info_walker;
+
+        printer pr;
+        basic_info_walker<printer> walker(pr, what.tag, 0);
+        boost::apply_visitor(walker, what.value);
+    }
+}
+
+#endif