• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Abel Sinkovics (abel@sinkovics.hu)  2011.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5 
6 #include <boost/metaparse/foldl_reject_incomplete.hpp>
7 #include <boost/metaparse/foldl_reject_incomplete1.hpp>
8 #include <boost/metaparse/lit_c.hpp>
9 #include <boost/metaparse/transform.hpp>
10 #include <boost/metaparse/one_char_except_c.hpp>
11 #include <boost/metaparse/one_of.hpp>
12 #include <boost/metaparse/always_c.hpp>
13 #include <boost/metaparse/build_parser.hpp>
14 #include <boost/metaparse/middle_of.hpp>
15 #include <boost/metaparse/entire_input.hpp>
16 #include <boost/metaparse/string.hpp>
17 
18 #include <boost/detail/iterator.hpp>
19 #include <boost/xpressive/xpressive.hpp>
20 
21 #include <boost/mpl/bool.hpp>
22 #include <boost/mpl/string.hpp>
23 
24 using boost::metaparse::foldl_reject_incomplete;
25 using boost::metaparse::foldl_reject_incomplete1;
26 using boost::metaparse::lit_c;
27 using boost::metaparse::transform;
28 using boost::metaparse::build_parser;
29 using boost::metaparse::one_of;
30 using boost::metaparse::always_c;
31 using boost::metaparse::middle_of;
32 using boost::metaparse::one_char_except_c;
33 using boost::metaparse::entire_input;
34 
35 using boost::mpl::c_str;
36 using boost::mpl::true_;
37 using boost::mpl::false_;
38 
39 using boost::xpressive::sregex;
40 using boost::xpressive::as_xpr;
41 
42 /*
43  * Results of parsing
44  */
45 
46 template <class T>
47 struct has_value
48 {
49   typedef T type;
50   static const sregex value;
51 };
52 
53 template <class T>
54 const sregex has_value<T>::value = T::run();
55 
56 struct r_epsilon : has_value<r_epsilon>
57 {
runr_epsilon58   static sregex run()
59   {
60     return as_xpr("");
61   }
62 };
63 
64 struct r_any_char : has_value<r_any_char>
65 {
runr_any_char66   static sregex run()
67   {
68     return boost::xpressive::_;
69   }
70 };
71 
72 struct r_char_lit
73 {
74   template <class C>
75   struct apply : has_value<apply<C> >
76   {
runr_char_lit::apply77     static sregex run()
78     {
79       return as_xpr(C::type::value);
80     }
81   };
82 };
83 
84 struct r_append
85 {
86   template <class A, class B>
87   struct apply : has_value<apply<B, A> >
88   {
runr_append::apply89     static sregex run()
90     {
91       return A::type::run() >> B::type::run();
92     }
93   };
94 };
95 
96 /*
97  * The grammar
98  *
99  * regexp ::= (bracket_expr | non_bracket_expr)*
100  * non_bracket_expr ::= '.' | char_lit
101  * bracket_expr ::= '(' regexp ')'
102  * char_lit ::= any character except: . ( )
103  */
104 
105 typedef
106   foldl_reject_incomplete1<
107     one_of<
108       always_c<'.', r_any_char>,
109       transform<one_char_except_c<'.', '(', ')'>, r_char_lit>
110     >,
111     r_epsilon,
112     r_append
113   >
114   non_bracket_expr;
115 
116 typedef middle_of<lit_c<'('>, non_bracket_expr, lit_c<')'> > bracket_expr;
117 
118 typedef
119   foldl_reject_incomplete<
120     one_of<bracket_expr, non_bracket_expr>,
121     r_epsilon,
122     r_append
123   >
124   regexp;
125 
126 typedef build_parser<entire_input<regexp> > regexp_parser;
127 
test_string(const std::string & s)128 void test_string(const std::string& s)
129 {
130   using boost::xpressive::regex_match;
131   using boost::xpressive::smatch;
132   using boost::mpl::apply_wrap1;
133 
134   using std::cout;
135   using std::endl;
136 
137 #if BOOST_METAPARSE_STD < 2011
138   typedef boost::metaparse::string<'.','(','b','c',')'> regexp;
139 #else
140   typedef BOOST_METAPARSE_STRING(".(bc)") regexp;
141 #endif
142 
143   const sregex re = apply_wrap1<regexp_parser, regexp>::type::value;
144   smatch w;
145 
146   cout
147     << s << (regex_match(s, w, re) ? " matches " : " doesn't match ")
148     << c_str<regexp>::type::value
149     << endl;
150 }
151 
main()152 int main()
153 {
154   test_string("abc");
155   test_string("aba");
156 }
157 
158 
159