Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77428 - in trunk/libs/spirit/repository: doc/qi test/qi
From: joel_at_[hidden]
Date: 2012-03-20 06:19:31


Author: djowel
Date: 2012-03-20 06:19:28 EDT (Tue, 20 Mar 2012)
New Revision: 77428
URL: http://svn.boost.org/trac/boost/changeset/77428

Log:
teajay's keyword patches
Text files modified:
   trunk/libs/spirit/repository/doc/qi/keywords.qbk | 26 ++--
   trunk/libs/spirit/repository/doc/qi/kwd.qbk | 29 ++++-
   trunk/libs/spirit/repository/test/qi/keywords.cpp | 201 +++++++++++++++++++++++++++++++--------
   3 files changed, 191 insertions(+), 65 deletions(-)

Modified: trunk/libs/spirit/repository/doc/qi/keywords.qbk
==============================================================================
--- trunk/libs/spirit/repository/doc/qi/keywords.qbk (original)
+++ trunk/libs/spirit/repository/doc/qi/keywords.qbk 2012-03-20 06:19:28 EDT (Tue, 20 Mar 2012)
@@ -11,8 +11,8 @@
 
 [heading Description]
 
-The keyword list operator, `kwd("k1")[a] / kwd("k2")[b]`, works tightly with the kwd, ikwd directives
-to effeciently match keyword lists. As long as one of the keywords specified through the kwd or ikwd directive
+The keyword list operator, `kwd("k1")[a] / kwd("k2")[b]`, works tightly with the kwd, ikwd, dkwd and idkwd directives
+to effeciently match keyword lists. As long as one of the keywords specified through the kwd, ikwd, dkwd or idkwd directive
 matches, the keyword will be immediatly followed by the the keyword's associated subject parser.
 The parser will continue parsing input as long as the one of the keywords and it's associated parser succeed.
 Writing :
@@ -47,31 +47,27 @@
 a: A, b: A -->(kwd(k1)[a] / kwd(k2)[b]): tuple<A, A>``]]
 ]
 
-[note The keyword list parser works tightly with the kwd and ikwd directives
+[note The keyword list parser works tightly with the kwd, ikwd, dkwd and idkwd directives
       and can't be used without it. A compile time error will warn you
       of any mistakes. This parser collects all the kwd directives and
- extracts the keyword literals from the directives to internaly
- build a Ternary Search Tree (TST) to effectively parse the keywords.
- Because you we can't mix character types inside a TST you must take
- care not to mix wide strings with normal strings in the keyword you supply
+ extracts the keyword literals or parsers from the directives to internaly
+ build a Ternary Search Tree (TST) and permutation loop (for complex parsers)
+ to effectively parse the keywords.
+ Because you can't mix character types inside a TST you must take
+ care not to mix wide strings with normal strings in the keywords you supply
       to a keyword list. Should it happen the compiler will trap the mistake for you.]
 
 [note The kwd directive also works a bit like the repeat directive
       and can be used to formulate additional contraints on the number of
- times a keyword can occur while parsing a keyword list.]
+ times a keyword can or must occur while parsing a keyword list.]
       
-[note The kwd and ikwd directives can be mixed inside a keyword list. This has
+[note The kwd, dkwd and ikwd, idkwd directives can be mixed inside a keyword list. This has
       however a small overhead and should be avoided when possible.]
 
 [heading Complexity]
 
 [:The overall complexity of the keyword list parser is defined by the
-sum of the complexities of its elements. The complexity of the
-keyword list itself is determined by the complexity of the internal TST contents :
-
-O(log n+k)
-
-Where k is the length of the string to be searched in a TST with n strings.]
+sum of the complexities of its elements.]
 
 [heading Example]
 

Modified: trunk/libs/spirit/repository/doc/qi/kwd.qbk
==============================================================================
--- trunk/libs/spirit/repository/doc/qi/kwd.qbk (original)
+++ trunk/libs/spirit/repository/doc/qi/kwd.qbk 2012-03-20 06:19:28 EDT (Tue, 20 Mar 2012)
@@ -1,7 +1,7 @@
 [/==============================================================================
- Copyright (C) 2001-2011 Joel de Guzman
- Copyright (C) 2001-2011 Hartmut Kaiser
- Copyright (C) 2011 Thomas Bernard
+ Copyright (C) 2001-2012 Joel de Guzman
+ Copyright (C) 2001-2012 Hartmut Kaiser
+ Copyright (C) 2011-2012 Thomas Bernard
 
     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)
@@ -11,7 +11,7 @@
 
 [heading Description]
 
-The `kwd[]` and `ikwd[]` provide a powerful and flexible mechanism for parsing keyword
+The `kwd[]`, `dkwd[]` and `ikwd[]`, `idkwd[]` provide a powerful and flexible mechanism for parsing keyword
 based input. It works in conjuction with the / operator to create an effective
 keyword parsing loop. The keyword parsing loop doesn't require the
 keywords to appear in a defined order in the input but also provides the possibility
@@ -22,6 +22,17 @@
 keywords, but be aware that this has a small overhead. It should be prefered not to
 mix the kwd and ikwd directives.
 
+The dkwd and idkwd provide a mechanism to pase distinct keywords. These directives require
+that the skipper successeds parsing input right after the keyword part.
+
+dkwd("keyword1")['='>>int_]
+
+is equivalent to:
+
+lit("keyword1") >> skipper+ >> '=' >> int_
+
+All the keyword directives can be mixed inside a keyword list.
+
 The kwd directive is very similar to the repeat directive in that it enables to enforce
 keyword occurence constraints but also provides very interesting speed improvement
 over the pure EBNF syntax or the Nabialek-Trick.
@@ -42,6 +53,7 @@
 ]
 
 For non case sensitive keywords use the ikwd directive.
+If distinct keyword parsing is required, use the dkwd and idkwd directive instead.
 
 [heading Parameters]
 
@@ -54,8 +66,8 @@
     [[`max`] [Int representing the maximum number of times the keyword must be repeated.]]
 ]
 
-All three parameters can be arbitrarily complex parsers themselves.
-
+The keyword as well as the subject parameters can be any valid spirit parser.
+The parameter n, min and max are integer constants.
 
 [heading Attributes]
 
@@ -81,11 +93,14 @@
 parser. The complexity of the keyword list construct `kwd` itself is O(N), where N is the number
 of repetitions executed.
 
-The complexity of the keyword list itself determined by the complexity of the internal TST contents :
+In the case where all the keywords are strings, the complexity of the keyword list itself determined by the complexity of the internal TST contents :
 
 O(log n+k)
 
 Where k is the length of the string to be searched in a TST with n strings.
+
+When the keywords used are complex parsers, then the complexity is the sum of the sub parser complexities.
+
 ]
 
 [heading Example]

Modified: trunk/libs/spirit/repository/test/qi/keywords.cpp
==============================================================================
--- trunk/libs/spirit/repository/test/qi/keywords.cpp (original)
+++ trunk/libs/spirit/repository/test/qi/keywords.cpp 2012-03-20 06:19:28 EDT (Tue, 20 Mar 2012)
@@ -17,6 +17,7 @@
 #include <boost/spirit/include/qi_numeric.hpp>
 #include <boost/spirit/include/qi_directive.hpp>
 #include <boost/spirit/include/qi_action.hpp>
+#include <boost/spirit/include/qi_nonterminal.hpp>
 #include <boost/spirit/include/support_argument.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
@@ -30,20 +31,20 @@
 
 struct x_attr
 {
-
+
 };
 
-namespace boost { namespace spirit { namespace traits
+namespace boost { namespace spirit { namespace traits
 {
-
-
+
+
     template <>
     struct container_value<x_attr>
     {
         typedef char type; // value type of container
     };
 
-
+
     template <>
     struct push_back_container<x_attr, char>
     {
@@ -53,7 +54,7 @@
             return true;
         }
     };
-}}}
+}}}
 
 int
 main()
@@ -64,6 +65,7 @@
     using namespace boost::spirit::ascii;
     using boost::spirit::repository::kwd;
     using boost::spirit::repository::ikwd;
+ using boost::spirit::repository::dkwd;
     using boost::spirit::qi::inf;
     using boost::spirit::qi::omit;
     using boost::spirit::qi::int_;
@@ -71,48 +73,57 @@
     using boost::spirit::qi::_1;
     using boost::spirit::qi::lexeme;
 
+
     {
-
+
         // no constraints
         boost::fusion::vector<char,char,int> data;
- BOOST_TEST( test_attr("c=1 a=a", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], data, space));
- BOOST_TEST( test("a=a c=1", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( test_attr("c=1 a=a", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], data, space));
+ BOOST_TEST( boost::fusion::at_c<0>(data) == 'a' );
+ BOOST_TEST( boost::fusion::at_c<1>(data) == 0 );
+ BOOST_TEST( boost::fusion::at_c<2>(data) == 1 );
+
+ BOOST_TEST( test("a=a c=1", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+
+ BOOST_TEST( test("", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
 
         // Exact
- BOOST_TEST(test("a=a b=b c=1", kwd("a",1)[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
- BOOST_TEST(test("a=a b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space));
- BOOST_TEST(!test("b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space));
-
- // Min - Max
- BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
- BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
- BOOST_TEST(test("a=g a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
- BOOST_TEST(!test("a=f a=e b=c b=e a=p c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
+ BOOST_TEST(test("a=a b=b c=1", kwd("a",1)[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST(test("a=a b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST(!test("b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space));
+
+ // Min - Max
+ BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
+ BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
+ BOOST_TEST(test("a=g a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
+ BOOST_TEST(!test("a=f a=e b=c b=e a=p c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space));
 
         // Min - inf
- BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
- BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
- BOOST_TEST(test("a=f a=f a=g b=c b=e c=1 a=e", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
+ BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
+ BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
+ BOOST_TEST(test("a=f a=f a=g b=c b=e c=1 a=e", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space ));
     }
 
     { // Single keyword, empty string
- BOOST_TEST(test(" ", kwd("aad")[char_],space));
- BOOST_TEST(test("aad E ", kwd("aad")[char_],space));
- //BOOST_TEST(test("AaD E ", ikwd("aad")[char_],space));
-
+ BOOST_TEST(test(" ", kwd("aad")[char_],space));
+ // Single keyword
+ BOOST_TEST(test("aad E ", kwd("aad")[char_],space));
+ // Single no case keyword
+ BOOST_TEST(test("AaD E ", ikwd("aad")[char_],space));
+
     }
-
+
     {
         // Vector container
         boost::fusion::vector<std::vector<int>,std::vector<int>,std::vector<int> > data;
- BOOST_TEST(test_attr(" a=1 b=2 b=5 c=3",kwd("a")[ '=' > int_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] , data, space)
- && (boost::fusion::at_c<0>(data).size()==1)
+ BOOST_TEST(test_attr(" a=1 b=2 b=5 c=3",kwd("a")[ '=' > int_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] , data, space)
+ && (boost::fusion::at_c<0>(data).size()==1)
                     && (boost::fusion::at_c<0>(data)[0]==1)
-
+
                     &&(boost::fusion::at_c<1>(data).size()==2)
                     &&(boost::fusion::at_c<1>(data)[0]==2)
                     &&(boost::fusion::at_c<1>(data)[1]==5)
-
+
                     &&(boost::fusion::at_c<2>(data).size()==1)
                     &&(boost::fusion::at_c<2>(data)[0]==3)
             );
@@ -120,35 +131,139 @@
 
     {
         // no_case test
- BOOST_TEST( test("B=a c=1 a=E", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space));
- BOOST_TEST( test("B=a c=1 a=e", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space));
- BOOST_TEST( !test("B=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
- BOOST_TEST( test("b=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
- BOOST_TEST( !test("A=a c=1 a=E", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
- BOOST_TEST( test("A=a c=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
- BOOST_TEST( !test("A=a C=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( test("B=a c=1 a=E", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space));
+ BOOST_TEST( test("B=a c=1 a=e", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space));
+ BOOST_TEST( !test("B=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( test("b=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( !test("A=a c=1 a=E", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( test("A=a c=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST( !test("A=a C=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space));
+ }
+
+ {
+ // iterator restoration
+ BOOST_TEST( test("a=a c=1 ba=d", (kwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) > lit("ba=") > char_, space));
+ BOOST_TEST( test("A=a c=1 ba=d", (ikwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) > lit("ba=") > char_, space));
+ }
+
+ { // actions
+ namespace phx = boost::phoenix;
+
+ std::vector<int> v;
+ BOOST_TEST(test("b=2 c=4", kwd("b")['=' > int_][phx::ref(v)=_1] / kwd("c")[ '=' > int_ ],space) &&
+ v[0] == 2 );
+ }
+
+
+ {
+ // no constraints
+ boost::fusion::vector<char,char,int> data;
+ BOOST_TEST( test_attr("c,1,2=1 2,b=a", kwd( char_ >> lit(',') >> int_ )[ '=' >> char_] / kwd(int_ >> lit(',') >> char_)[ '=' >> char_] / kwd(char_ >> lit(',') >> int_ >> lit(',') >> int_)['=' >> int_], data, space));
+ BOOST_TEST( boost::fusion::at_c<0>(data) == 0 );
+ BOOST_TEST( boost::fusion::at_c<1>(data) == 'a');
+ BOOST_TEST( boost::fusion::at_c<2>(data) == 1 );
+
+ BOOST_TEST( test("2,b=a c,1,2=1", kwd( char_ >> ',' >> int_ )[ '=' >> char_] / kwd(int_ >> ',' >> char_)[ '=' >> char_] / kwd(char_ >> ',' >> int_ >> ',' >> int_)['=' >> int_], space));
+
+ BOOST_TEST( test("", kwd( char_ >> ',' >> int_ )[ '=' >> char_] / kwd(int_ >> ',' >> char_)[ '=' >> char_] / kwd(char_ >> ',' >> int_ >> ',' >> int_)['=' >> int_], space));
+
+ // Exact
+ BOOST_TEST(test("7a=a 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'))[ '=' >> char_] / kwd(int_ >> lit('c'))['=' >> int_], space));
+ BOOST_TEST(test("7a=a 3b=d 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'),2)[ '=' >> char_] / kwd(int_ >>'c')['=' >> int_], space));
+ BOOST_TEST(!test("7a=a 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'),2)[ '=' >> char_] / kwd(int_ >>'c')['=' >> int_], space));
+
+ // Min - Max
+ BOOST_TEST(test("6a=f 2b=c 3b=e 1c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,2)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
+ BOOST_TEST(!test("1b=c 6b=e 2c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,1)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
+ BOOST_TEST(test("4a=g 7a=f 2b=c 1b=e 4c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,2)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
+ BOOST_TEST(!test("1a=f a=e 2b=c 5b=e 6a=p 67c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,1)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space));
+
+ // Min - inf
+ BOOST_TEST(test("41a=f 44b=c 12b=e 45c=1", kwd(int_ >> "a",1,inf)[ '=' >> char_] / kwd(int_ >> "b",0,inf)[ '=' >> char_] / kwd(int_ >> "c",1,inf)['=' >> int_], space ));
+ BOOST_TEST(!test("31b=c 55b=e 2c=1", kwd("a",1,inf)[ '=' >> char_] / kwd("b",0,inf)[ '=' >> char_] / kwd("c",1,inf)['=' >> int_], space ));
+ BOOST_TEST(test("12a=f 45a=f 12a=g 1b=c 7b=e 12c=1 6a=e", kwd(int_ >> "a",1,inf)[ '=' >> char_] / kwd(int_ >> "b",0,inf)[ '=' >> char_] / kwd(int_ >> "c",1,inf)['=' >> int_], space ));
+
+ }
+
+ {
+
+ // Vector container
+ boost::fusion::vector<std::vector<int>,std::vector<int>,std::vector<int> > data;
+ BOOST_TEST(test_attr(" 41a=1 4b=2 12b=5 5c=3",kwd(int_ >> "a")[ '=' >> int_] / kwd(int_ >> "b")[ '=' >> int_] / kwd(int_ >> "c")['=' >> int_] , data, space)
+ && (boost::fusion::at_c<0>(data).size()==1)
+ && (boost::fusion::at_c<0>(data)[0]==1)
+
+ &&(boost::fusion::at_c<1>(data).size()==2)
+ &&(boost::fusion::at_c<1>(data)[0]==2)
+ &&(boost::fusion::at_c<1>(data)[1]==5)
+
+ &&(boost::fusion::at_c<2>(data).size()==1)
+ &&(boost::fusion::at_c<2>(data)[0]==3)
+ );
+
+
+
+ }
+
+ {
+ // no_case test
+ BOOST_TEST( test("12B=a 5c=1 1a=E", no_case[kwd(int_ >> "a")[ "=E" ] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_]], space));
+ BOOST_TEST( test("5B=a 2c=1 5a=e", no_case[kwd(int_ >> "a")[ "=E" ] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_]], space));
+ BOOST_TEST( !test("1B=a 8c=1 1A=E", no_case[kwd(int_ >> "a")[ '=' >> char_]] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
+ BOOST_TEST( test("2b=a 6c=1 5A=E", no_case[kwd(int_ >> "a")[ '=' >> char_]] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
+ BOOST_TEST( !test("1A=a 5c=1 1a=E", kwd(int_ >> "a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
+ BOOST_TEST( test("A=a 23c=1 a=E", ikwd("a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
+ BOOST_TEST( !test("A=a 21C=1 a=E", ikwd("a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space));
     }
-
+
     {
         // iterator restoration
- BOOST_TEST( test("a=a c=1 ba=d", (kwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) | lit("ba=") > char_, space));
- BOOST_TEST( test("A=a c=1 ba=d", (ikwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) | lit("ba=") > char_, space));
+ BOOST_TEST( test("4a=a c4=1 ba=d", (kwd(int_ >> "a")[ '=' >> char_] / kwd("b" >> int_)[ '=' >> int_] / kwd("c" >> int_ )['=' >> int_] ) >> lit("ba=") >> char_, space));
     }
 
     { // actions
         namespace phx = boost::phoenix;
 
         std::vector<int> v;
- BOOST_TEST(test("b=2 c=4", kwd("b")['=' > int_][phx::ref(v)=_1] / kwd("c")[ '=' > int_ ],space) &&
+ BOOST_TEST(test("b4=2 c1=4", kwd("b" >> int_)['=' >> int_][phx::ref(v)=_1] / kwd("c" >> int_)[ '=' >> int_ ],space) &&
             v[0] == 2 );
     }
 
+ {
+ // complex keyword single test
+ int result=0;
+
+ BOOST_TEST( test_attr("(a,1) = 3214", kwd( '(' >> char_ >> ',' >> int_ >> ')' )['=' >> int_], result, space) );
+ BOOST_TEST(result==3214);
+ }
+ {
+ // Mixed complex keyword loop
+ boost::fusion::vector<int,int,int> data;
+
+ BOOST_TEST( test_attr("(a,1) = 3214 b += 2 hello 10 (a,2)=31", kwd( '(' >> char_ >> ',' >> int_ >> ')' )['=' >> int_] / kwd("hello")[int_] / kwd("b")["+=" >> int_], data, space) );
+ BOOST_TEST( boost::fusion::at_c<0>(data) == 31);
+ BOOST_TEST( boost::fusion::at_c<1>(data) == 10);
+ BOOST_TEST( boost::fusion::at_c<2>(data) == 2);
+ }
+
+ // dkwd and idkwd
+ {
+ BOOST_TEST( test("a =a", dkwd("a")[ '=' > char_] , space));
+ BOOST_TEST( !test("a=a", dkwd("a")[ '=' > char_] , space));
+ BOOST_TEST(test("a =a b =b c=1", dkwd("a",1)[ '=' > char_] / dkwd("b",1,2)[ '=' > char_] / kwd("c")['=' > int_], space));
+ BOOST_TEST(!test("a=a b=b c =1", dkwd("a",1)[ '=' > char_] / dkwd("b",1,2)[ '=' > char_] / kwd("c")['=' > int_], space));
+
+ BOOST_TEST(test("a =a b =b b =d c=1", dkwd("a",1,inf)[ '=' > char_] / dkwd("b",2,inf)[ '=' > char_] / kwd("c")['=' > int_], space));
+
+ }
+
     { // attribute customization
-
+
         x_attr x;
 // test_attr("a = b c = d", kwd("a")['=' > char_] / kwd("c")['=' > char_], x);
     }
 
- return boost::report_errors();
+
+ 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