Boost logo

Boost-Commit :

From: hartmut.kaiser_at_[hidden]
Date: 2008-08-26 20:17:06


Author: hkaiser
Date: 2008-08-26 20:17:06 EDT (Tue, 26 Aug 2008)
New Revision: 48399
URL: http://svn.boost.org/trac/boost/changeset/48399

Log:
Spirit.Qi: Added confix parser
Added:
   trunk/boost/spirit/home/qi/auxiliary/confix.hpp (contents, props changed)
   trunk/libs/spirit/test/qi/config.cpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/home/qi/auxiliary.hpp | 1
   trunk/boost/spirit/home/qi/auxiliary/meta_grammar.hpp | 13 ++++++++++
   trunk/libs/spirit/test/Jamfile | 50 ++++++++++++++++++++-------------------
   3 files changed, 40 insertions(+), 24 deletions(-)

Modified: trunk/boost/spirit/home/qi/auxiliary.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/auxiliary.hpp (original)
+++ trunk/boost/spirit/home/qi/auxiliary.hpp 2008-08-26 20:17:06 EDT (Tue, 26 Aug 2008)
@@ -9,6 +9,7 @@
 #define BOOST_SPIRIT_STRING_FEB_03_2007_0355PM
 
 #include <boost/spirit/home/qi/auxiliary/none.hpp>
+#include <boost/spirit/home/qi/auxiliary/confix.hpp>
 #include <boost/spirit/home/qi/auxiliary/eps.hpp>
 #include <boost/spirit/home/qi/auxiliary/lazy.hpp>
 #include <boost/spirit/home/qi/auxiliary/functor.hpp>

Added: trunk/boost/spirit/home/qi/auxiliary/confix.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/auxiliary/confix.hpp 2008-08-26 20:17:06 EDT (Tue, 26 Aug 2008)
@@ -0,0 +1,127 @@
+// Copyright (c) 2001-2008 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_QI_CONFIX_AUG_26_2008_1012AM)
+#define BOOST_SPIRIT_QI_CONFIX_AUG_26_2008_1012AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/auxiliary/confix.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // the director for a confix() generated parser
+ struct confix_director
+ {
+ template <typename Component, typename Context, typename Iterator>
+ struct attribute
+ {
+ typedef typename
+ result_of::subject<Component>::type
+ subject_type;
+
+ typedef typename
+ traits::attribute_of<
+ qi::domain, subject_type, Context, Iterator>::type
+ type;
+ };
+
+ private:
+ ///////////////////////////////////////////////////////////////////////
+ template <
+ typename Iterator, typename Context
+ , typename Skipper, typename Expr>
+ static void parse_helper(
+ Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper, Expr const& e)
+ {
+ BOOST_MPL_ASSERT_MSG(
+ (spirit::traits::is_component<qi::domain, Expr>::value),
+ expression_is_not_convertible_to_a_parser, (Context, Expr));
+
+ typedef
+ typename result_of::as_component<qi::domain, Expr>::type
+ expr;
+
+ expr eg = spirit::as_component(qi::domain(), e);
+ typedef typename expr::director director;
+ director::parse(eg, first, last, context, skipper, unused);
+ }
+
+ template <typename Context, typename Expr>
+ static std::string what_helper(Expr const& e, Context& ctx)
+ {
+ typedef
+ typename result_of::as_component<qi::domain, Expr>::type
+ expr;
+
+ expr eg = spirit::as_component(qi::domain(), e);
+ typedef typename expr::director director;
+ return director::what(eg, ctx);
+ }
+
+ public:
+ ///////////////////////////////////////////////////////////////////////
+ template <
+ typename Component
+ , typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ static bool parse(
+ Component const& component
+ , Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr)
+ {
+ // parse the prefix
+ parse_helper(first, last, context, skipper,
+ spirit::detail::confix_extractor::prefix(
+ proto::arg_c<0>(spirit::argument1(component))));
+
+ // generate the embedded items
+ typedef typename
+ spirit::result_of::subject<Component>::type::director
+ director;
+ bool result = director::parse(spirit::subject(component),
+ first, last, context, skipper, attr);
+
+ // append the suffix
+ parse_helper(first, last, context, skipper,
+ spirit::detail::confix_extractor::suffix(
+ proto::arg_c<0>(spirit::argument1(component))));
+
+ return result;
+ }
+
+ template <typename Component, typename Context>
+ static std::string what(Component const& component, Context const& ctx)
+ {
+ std::string result = "confix(";
+
+ result += what_helper(spirit::detail::confix_extractor::prefix(
+ proto::arg_c<0>(spirit::argument1(component))), ctx);
+ result += ", ";
+
+ result += what_helper(spirit::detail::confix_extractor::suffix(
+ proto::arg_c<0>(spirit::argument1(component))), ctx);
+ result += ")[";
+
+ typedef typename
+ spirit::result_of::subject<Component>::type::director
+ director;
+ result += director::what(spirit::subject(component), ctx);
+ result += "]";
+
+ return result;
+ }
+ };
+
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/qi/auxiliary/meta_grammar.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/auxiliary/meta_grammar.hpp (original)
+++ trunk/boost/spirit/home/qi/auxiliary/meta_grammar.hpp 2008-08-26 20:17:06 EDT (Tue, 26 Aug 2008)
@@ -24,11 +24,14 @@
     ///////////////////////////////////////////////////////////////////////////
     // forwards
     ///////////////////////////////////////////////////////////////////////////
+ struct main_meta_grammar;
+
     struct none;
     struct eps_parser;
     struct semantic_predicate;
     struct lazy_parser;
     struct functor_director;
+ struct confix_director;
 
     struct eol_director;
     struct eoi_director;
@@ -50,19 +53,29 @@
     // none, eps and eps(f)
     struct auxiliary_meta_grammar1
       : proto::or_<
+ // none
             meta_grammar::empty_terminal_rule<
                 qi::domain, tag::none, none>
+ // eps
           , meta_grammar::empty_terminal_rule<
                 qi::domain, tag::eps, eps_parser>
+ // eps()
           , meta_grammar::function1_rule<
                 qi::domain, tag::eps, semantic_predicate>
+ // lazy()
           , meta_grammar::function1_rule<
                 qi::domain, tag::lazy, lazy_parser>
+ // functor parser
           , meta_grammar::terminal_rule<
                 qi::domain
               , functor_holder<proto::_, proto::_>
               , functor_director
>
+ // confix(..., ...)[...]
+ , meta_grammar::subscript_rule<
+ qi::domain, tag::confix<proto::_, proto::_>,
+ confix_director, main_meta_grammar
+ >
>
     {
     };

Modified: trunk/libs/spirit/test/Jamfile
==============================================================================
--- trunk/libs/spirit/test/Jamfile (original)
+++ trunk/libs/spirit/test/Jamfile 2008-08-26 20:17:06 EDT (Tue, 26 Aug 2008)
@@ -20,40 +20,41 @@
 
     # run Qi tests
     [ run qi/actions.cpp : : : : ]
+ [ run qi/alternative.cpp : : : : ]
+ [ run qi/and_predicate.cpp : : : : ]
+ [ run qi/binary.cpp : : : : ]
     [ run qi/char.cpp : : : : ]
     [ run qi/char_class.cpp : : : : ]
- [ run qi/lit.cpp : : : : ]
- [ run qi/int.cpp : : : : ]
- [ run qi/uint.cpp : : : : ]
- [ run qi/real.cpp : : : : ]
+ [ run qi/confix.cpp : : : : ]
+ [ run qi/debug.cpp : : : : ]
+ [ run qi/difference.cpp : : : : ]
+ [ run qi/end.cpp : : : : ]
     [ run qi/eps.cpp : : : : ]
- [ run qi/none.cpp : : : : ]
+ [ run qi/expect.cpp : : : : ]
+ [ run qi/functor.cpp : : : : ]
+ [ run qi/grammar.cpp : : : : ]
+ [ run qi/int.cpp : : : : ]
+ [ run qi/kleene.cpp : : : : ]
     [ run qi/lazy.cpp : : : : ]
- [ run qi/tst.cpp : : : : ]
- [ run qi/symbols.cpp : : : : ]
- [ run qi/range_run.cpp : : : : ]
- [ run qi/no_case.cpp : : : : ]
     [ run qi/lexeme.cpp : : : : ]
- [ run qi/raw.cpp : : : : ]
- [ run qi/sequence.cpp : : : : ]
- [ run qi/alternative.cpp : : : : ]
- [ run qi/sequential_or.cpp : : : : ]
- [ run qi/permutation.cpp : : : : ]
- [ run qi/difference.cpp : : : : ]
+ [ run qi/lit.cpp : : : : ]
     [ run qi/list.cpp : : : : ]
+ [ run qi/no_case.cpp : : : : ]
+ [ run qi/none.cpp : : : : ]
+ [ run qi/not_predicate.cpp : : : : ]
     [ run qi/optional.cpp : : : : ]
- [ run qi/kleene.cpp : : : : ]
+ [ run qi/permutation.cpp : : : : ]
     [ run qi/plus.cpp : : : : ]
- [ run qi/and_predicate.cpp : : : : ]
- [ run qi/not_predicate.cpp : : : : ]
- [ run qi/expect.cpp : : : : ]
+ [ run qi/range_run.cpp : : : : ]
+ [ run qi/raw.cpp : : : : ]
+ [ run qi/real.cpp : : : : ]
     [ run qi/rule.cpp : : : : ]
- [ run qi/grammar.cpp : : : : ]
- [ run qi/functor.cpp : : : : ]
+ [ run qi/sequence.cpp : : : : ]
+ [ run qi/sequential_or.cpp : : : : ]
+ [ run qi/symbols.cpp : : : : ]
+ [ run qi/tst.cpp : : : : ]
+ [ run qi/uint.cpp : : : : ]
     [ run qi/match_manip.cpp : : : : ]
- [ run qi/binary.cpp : : : : ]
- [ run qi/debug.cpp : : : : ]
- [ run qi/end.cpp : : : : ]
 
     [ compile-fail qi/grammar_fail.cpp : : ]
     [ compile-fail qi/rule_fail.cpp : : ]
@@ -65,6 +66,7 @@
     [ run karma/case_handling.cpp : : : : ]
     [ run karma/center_alignment.cpp : : : : ]
     [ run karma/char.cpp : : : : karma_char ]
+ [ run karma/confix.cpp : : : : karma_confix ]
     [ run karma/delimiter.cpp : : : : ]
     [ run karma/eol.cpp : : : : karma_eol ]
     [ run karma/eps.cpp : : : : karma_eps ]

Added: trunk/libs/spirit/test/qi/config.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/test/qi/config.cpp 2008-08-26 20:17:06 EDT (Tue, 26 Aug 2008)
@@ -0,0 +1,71 @@
+/*=============================================================================
+ Copyright (c) 2001-2007 Joel de Guzman
+ Copyright (c) 2001-2008 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/qi_auxiliary.hpp>
+#include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_parse.hpp>
+#include <boost/spirit/include/support_argument.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+namespace html
+{
+ ///////////////////////////////////////////////////////////////////////////////
+ // define a HTML tag helper generator
+ template <typename Char, typename Traits, typename Allocator>
+ inline boost::spirit::confix_spec<std::basic_string<Char, Traits, Allocator> >
+ tag (std::basic_string<Char, Traits, Allocator> const& tagname)
+ {
+ typedef std::basic_string<Char, Traits, Allocator> string_type;
+ return boost::spirit::confix_spec<string_type>(
+ string_type("<") + tagname + ">", string_type("</") + tagname + ">");
+ }
+
+ inline boost::spirit::confix_spec<std::string>
+ tag (char const* tagname)
+ {
+ return tag(std::string(tagname));
+ }
+
+ typedef boost::spirit::confix_spec<std::string> html_tag_type;
+
+ html_tag_type const ol = tag("ol");
+}
+
+int
+main()
+{
+ using spirit_test::test;
+ using namespace boost::spirit;
+ using namespace boost::spirit::ascii;
+
+ {
+ BOOST_TEST(test("<tag>10</tag>", confix("<tag>", "</tag>")[int_]));
+ BOOST_TEST(test(L"<tag>10</tag>", confix(L"<tag>", L"</tag>")[int_]));
+ BOOST_TEST(test("//10\n", confix(lit("//"), eol)[int_]));
+ BOOST_TEST(test(L"//10\n", confix(wlit("//"), eol)[int_]));
+ BOOST_TEST(test("<ol>10</ol>", html::ol[int_]));
+ BOOST_TEST(test(L"<ol>10</ol>", html::ol[int_]));
+ }
+
+ {
+ BOOST_TEST(test(" <tag> 10 </tag>", confix("<tag>", "</tag>")[int_],
+ ascii::space));
+ BOOST_TEST(test(L" <tag> 10 </tag>", confix(L"<tag>", L"</tag>")[int_],
+ ascii::space));
+ BOOST_TEST(test("// 10 \n", confix(lit("//"), eol)[int_], ascii::space));
+ BOOST_TEST(test(L"// 10 \n", confix(wlit("//"), eol)[int_], ascii::space));
+ BOOST_TEST(test(" <ol> 10 </ol>", html::ol[int_], ascii::space));
+ BOOST_TEST(test(L" <ol> 10 </ol>", html::ol[int_], ascii::space));
+ }
+
+ return boost::report_errors();
+}


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