1 /*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 Copyright (c) 2003 Vaclav Vesely 4 http://spirit.sourceforge.net/ 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 #if !defined(BOOST_SPIRIT_DISTINCT_HPP) 10 #define BOOST_SPIRIT_DISTINCT_HPP 11 12 #include <boost/spirit/home/classic/core/parser.hpp> 13 #include <boost/spirit/home/classic/core/primitives/primitives.hpp> 14 #include <boost/spirit/home/classic/core/composite/operators.hpp> 15 #include <boost/spirit/home/classic/core/composite/directives.hpp> 16 #include <boost/spirit/home/classic/core/composite/epsilon.hpp> 17 #include <boost/spirit/home/classic/core/non_terminal/rule.hpp> 18 #include <boost/spirit/home/classic/utility/chset.hpp> 19 20 #include <boost/spirit/home/classic/utility/distinct_fwd.hpp> 21 22 namespace boost { 23 namespace spirit { 24 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 25 26 //----------------------------------------------------------------------------- 27 // distinct_parser class 28 29 template <typename CharT, typename TailT> 30 class distinct_parser 31 { 32 public: 33 typedef 34 contiguous< 35 sequence< 36 chseq<CharT const*>, 37 negated_empty_match_parser< 38 TailT 39 > 40 > 41 > 42 result_t; 43 distinct_parser()44 distinct_parser() 45 : tail(chset<CharT>()) 46 { 47 } 48 distinct_parser(parser<TailT> const & tail_)49 explicit distinct_parser(parser<TailT> const & tail_) 50 : tail(tail_.derived()) 51 { 52 } 53 distinct_parser(CharT const * letters)54 explicit distinct_parser(CharT const* letters) 55 : tail(chset_p(letters)) 56 { 57 } 58 operator ()(CharT const * str) const59 result_t operator()(CharT const* str) const 60 { 61 return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)]; 62 } 63 64 TailT tail; 65 }; 66 67 //----------------------------------------------------------------------------- 68 // distinct_directive class 69 70 template <typename CharT, typename TailT> 71 class distinct_directive 72 { 73 public: 74 template<typename ParserT> 75 struct result { 76 typedef 77 contiguous< 78 sequence< 79 ParserT, 80 negated_empty_match_parser< 81 TailT 82 > 83 > 84 > 85 type; 86 }; 87 distinct_directive()88 distinct_directive() 89 : tail(chset<CharT>()) 90 { 91 } 92 distinct_directive(CharT const * letters)93 explicit distinct_directive(CharT const* letters) 94 : tail(chset_p(letters)) 95 { 96 } 97 distinct_directive(parser<TailT> const & tail_)98 explicit distinct_directive(parser<TailT> const & tail_) 99 : tail(tail_.derived()) 100 { 101 } 102 103 template<typename ParserT> 104 typename result<typename as_parser<ParserT>::type>::type operator [](ParserT const & subject) const105 operator[](ParserT const &subject) const 106 { 107 return 108 lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)]; 109 } 110 111 TailT tail; 112 }; 113 114 //----------------------------------------------------------------------------- 115 // dynamic_distinct_parser class 116 117 template <typename ScannerT> 118 class dynamic_distinct_parser 119 { 120 public: 121 typedef typename ScannerT::value_t char_t; 122 123 typedef 124 rule< 125 typename no_actions_scanner< 126 typename lexeme_scanner<ScannerT>::type 127 >::type 128 > 129 tail_t; 130 131 typedef 132 contiguous< 133 sequence< 134 chseq<char_t const*>, 135 negated_empty_match_parser< 136 tail_t 137 > 138 > 139 > 140 result_t; 141 dynamic_distinct_parser()142 dynamic_distinct_parser() 143 : tail(nothing_p) 144 { 145 } 146 147 template<typename ParserT> dynamic_distinct_parser(parser<ParserT> const & tail_)148 explicit dynamic_distinct_parser(parser<ParserT> const & tail_) 149 : tail(tail_.derived()) 150 { 151 } 152 dynamic_distinct_parser(char_t const * letters)153 explicit dynamic_distinct_parser(char_t const* letters) 154 : tail(chset_p(letters)) 155 { 156 } 157 operator ()(char_t const * str) const158 result_t operator()(char_t const* str) const 159 { 160 return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)]; 161 } 162 163 tail_t tail; 164 }; 165 166 //----------------------------------------------------------------------------- 167 // dynamic_distinct_directive class 168 169 template <typename ScannerT> 170 class dynamic_distinct_directive 171 { 172 public: 173 typedef typename ScannerT::value_t char_t; 174 175 typedef 176 rule< 177 typename no_actions_scanner< 178 typename lexeme_scanner<ScannerT>::type 179 >::type 180 > 181 tail_t; 182 183 template<typename ParserT> 184 struct result { 185 typedef 186 contiguous< 187 sequence< 188 ParserT, 189 negated_empty_match_parser< 190 tail_t 191 > 192 > 193 > 194 type; 195 }; 196 dynamic_distinct_directive()197 dynamic_distinct_directive() 198 : tail(nothing_p) 199 { 200 } 201 202 template<typename ParserT> dynamic_distinct_directive(parser<ParserT> const & tail_)203 explicit dynamic_distinct_directive(parser<ParserT> const & tail_) 204 : tail(tail_.derived()) 205 { 206 } 207 dynamic_distinct_directive(char_t const * letters)208 explicit dynamic_distinct_directive(char_t const* letters) 209 : tail(chset_p(letters)) 210 { 211 } 212 213 template<typename ParserT> 214 typename result<typename as_parser<ParserT>::type>::type operator [](ParserT const & subject) const215 operator[](ParserT const &subject) const 216 { 217 return 218 lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)]; 219 } 220 221 tail_t tail; 222 }; 223 224 //----------------------------------------------------------------------------- 225 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 226 } // namespace spirit 227 } // namespace boost 228 229 #endif // !defined(BOOST_SPIRIT_DISTINCT_HPP) 230