• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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