Boost logo

Boost-Commit :

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


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