PageRenderTime 27ms CodeModel.GetById 12ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/classic/meta/refactoring.hpp

http://hadesmem.googlecode.com/
C++ Header | 287 lines | 149 code | 51 blank | 87 comment | 0 complexity | ed0709f57774bd4b1ef837d82a6d6be1 MD5 | raw file
  1/*=============================================================================
  2    Copyright (c) 2002-2003 Hartmut Kaiser
  3    http://spirit.sourceforge.net/
  4
  5  Distributed under the Boost Software License, Version 1.0. (See accompanying
  6  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7=============================================================================*/
  8#ifndef BOOST_SPIRIT_REFACTORING_HPP
  9#define BOOST_SPIRIT_REFACTORING_HPP
 10
 11///////////////////////////////////////////////////////////////////////////////
 12#include <boost/static_assert.hpp>
 13#include <boost/spirit/home/classic/namespace.hpp>
 14#include <boost/spirit/home/classic/meta/as_parser.hpp>
 15#include <boost/spirit/home/classic/core/parser.hpp>
 16#include <boost/spirit/home/classic/core/composite/composite.hpp>
 17#include <boost/spirit/home/classic/meta/impl/refactoring.ipp>
 18
 19///////////////////////////////////////////////////////////////////////////////
 20namespace boost { namespace spirit {
 21
 22BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
 23
 24#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
 25#pragma warning(push)
 26#pragma warning(disable:4512) //assignment operator could not be generated
 27#endif
 28
 29///////////////////////////////////////////////////////////////////////////////
 30//
 31//  refactor_unary_parser class
 32//
 33//      This helper template allows to attach an unary operation to a newly
 34//      constructed parser, which combines the subject of the left operand of
 35//      the original given parser (BinaryT) with the right operand of the
 36//      original binary parser through the original binary operation and
 37//      rewraps the resulting parser with the original unary operator.
 38//
 39//      For instance given the parser:
 40//          *some_parser - another_parser
 41//
 42//      will be refactored to:
 43//          *(some_parser - another_parser)
 44//
 45//      If the parser to refactor is not a unary parser, no refactoring is done
 46//      at all.
 47//
 48//      The original parser should be a binary_parser_category parser,
 49//      else the compilation will fail
 50//
 51///////////////////////////////////////////////////////////////////////////////
 52
 53template <typename NestedT = non_nested_refactoring>
 54class refactor_unary_gen;
 55
 56template <typename BinaryT, typename NestedT = non_nested_refactoring>
 57class refactor_unary_parser :
 58    public parser<refactor_unary_parser<BinaryT, NestedT> > {
 59
 60public:
 61    //  the parser to refactor has to be at least a binary_parser_category
 62    //  parser
 63    BOOST_STATIC_ASSERT((
 64        boost::is_convertible<typename BinaryT::parser_category_t,
 65            binary_parser_category>::value
 66    ));
 67
 68    refactor_unary_parser(BinaryT const& binary_, NestedT const& nested_)
 69    : binary(binary_), nested(nested_) {}
 70
 71    typedef refactor_unary_parser<BinaryT, NestedT> self_t;
 72    typedef refactor_unary_gen<NestedT> parser_generator_t;
 73    typedef typename BinaryT::left_t::parser_category_t parser_category_t;
 74
 75    template <typename ScannerT>
 76    typename parser_result<self_t, ScannerT>::type
 77    parse(ScannerT const& scan) const
 78    {
 79        return impl::refactor_unary_type<NestedT>::
 80            parse(*this, scan, binary, nested);
 81    }
 82
 83private:
 84    typename as_parser<BinaryT>::type::embed_t binary;
 85    typename NestedT::embed_t nested;
 86};
 87
 88//////////////////////////////////
 89template <typename NestedT>
 90class refactor_unary_gen {
 91
 92public:
 93    typedef refactor_unary_gen<NestedT> embed_t;
 94
 95    refactor_unary_gen(NestedT const& nested_ = non_nested_refactoring())
 96    : nested(nested_) {}
 97
 98    template <typename ParserT>
 99    refactor_unary_parser<ParserT, NestedT>
100    operator[](parser<ParserT> const& subject) const
101    {
102        return refactor_unary_parser<ParserT, NestedT>
103            (subject.derived(), nested);
104    }
105
106private:
107    typename NestedT::embed_t nested;
108};
109
110const refactor_unary_gen<> refactor_unary_d = refactor_unary_gen<>();
111
112///////////////////////////////////////////////////////////////////////////////
113//
114//  refactor_action_parser class
115//
116//      This helper template allows to attach an action taken from the left
117//      operand of the given binary parser to a newly constructed parser,
118//      which combines the subject of the left operand of the original binary
119//      parser with the right operand of the original binary parser by means of
120//      the original binary operator parser.
121//
122//      For instance the parser:
123//          some_parser[some_attached_functor] - another_parser
124//
125//      will be refactored to:
126//          (some_parser - another_parser)[some_attached_functor]
127//
128//      If the left operand to refactor is not an action parser, no refactoring
129//      is done at all.
130//
131//      The original parser should be a binary_parser_category parser,
132//      else the compilation will fail
133//
134///////////////////////////////////////////////////////////////////////////////
135
136template <typename NestedT = non_nested_refactoring>
137class refactor_action_gen;
138
139template <typename BinaryT, typename NestedT = non_nested_refactoring>
140class refactor_action_parser :
141    public parser<refactor_action_parser<BinaryT, NestedT> > {
142
143public:
144    //  the parser to refactor has to be at least a binary_parser_category
145    //  parser
146    BOOST_STATIC_ASSERT((
147        boost::is_convertible<typename BinaryT::parser_category_t,
148            binary_parser_category>::value
149    ));
150
151    refactor_action_parser(BinaryT const& binary_, NestedT const& nested_)
152    : binary(binary_), nested(nested_) {}
153
154    typedef refactor_action_parser<BinaryT, NestedT> self_t;
155    typedef refactor_action_gen<NestedT> parser_generator_t;
156    typedef typename BinaryT::left_t::parser_category_t parser_category_t;
157
158    template <typename ScannerT>
159    typename parser_result<self_t, ScannerT>::type
160    parse(ScannerT const& scan) const
161    {
162        return impl::refactor_action_type<NestedT>::
163            parse(*this, scan, binary, nested);
164    }
165
166private:
167    typename as_parser<BinaryT>::type::embed_t binary;
168    typename NestedT::embed_t nested;
169};
170
171//////////////////////////////////
172template <typename NestedT>
173class refactor_action_gen {
174
175public:
176    typedef refactor_action_gen<NestedT> embed_t;
177
178    refactor_action_gen(NestedT const& nested_ = non_nested_refactoring())
179    : nested(nested_) {}
180
181    template <typename ParserT>
182    refactor_action_parser<ParserT, NestedT>
183    operator[](parser<ParserT> const& subject) const
184    {
185        return refactor_action_parser<ParserT, NestedT>
186            (subject.derived(), nested);
187    }
188
189private:
190    typename NestedT::embed_t nested;
191};
192
193const refactor_action_gen<> refactor_action_d = refactor_action_gen<>();
194
195///////////////////////////////////////////////////////////////////////////////
196//
197//  attach_action_parser class
198//
199//      This helper template allows to attach an action given separately
200//      to to all parsers, out of which the given parser is constructed and
201//      reconstructs a new parser having the same structure.
202//
203//      For instance the parser:
204//          (some_parser >> another_parser)[some_attached_functor]
205//
206//      will be refactored to:
207//          some_parser[some_attached_functor]
208//              >> another_parser[some_attached_functor]
209//
210//      The original parser should be a action_parser_category parser,
211//      else the compilation will fail
212//
213//      If the parser, to which the action is attached is not an binary parser,
214//      no refactoring is done at all.
215//
216///////////////////////////////////////////////////////////////////////////////
217
218template <typename NestedT = non_nested_refactoring>
219class attach_action_gen;
220
221template <typename ActionT, typename NestedT = non_nested_refactoring>
222class attach_action_parser :
223    public parser<attach_action_parser<ActionT, NestedT> > {
224
225public:
226    //  the parser to refactor has to be at least a action_parser_category
227    //  parser
228    BOOST_STATIC_ASSERT((
229        boost::is_convertible<typename ActionT::parser_category_t,
230            action_parser_category>::value
231    ));
232
233    attach_action_parser(ActionT const& actor_, NestedT const& nested_)
234    : actor(actor_), nested(nested_) {}
235
236    typedef attach_action_parser<ActionT, NestedT> self_t;
237    typedef attach_action_gen<NestedT> parser_generator_t;
238    typedef typename ActionT::parser_category_t parser_category_t;
239
240    template <typename ScannerT>
241    typename parser_result<self_t, ScannerT>::type
242    parse(ScannerT const& scan) const
243    {
244        return impl::attach_action_type<NestedT>::
245            parse(*this, scan, actor, nested);
246    }
247
248private:
249    typename as_parser<ActionT>::type::embed_t actor;
250    typename NestedT::embed_t nested;
251};
252
253//////////////////////////////////
254template <typename NestedT>
255class attach_action_gen {
256
257public:
258    typedef attach_action_gen<NestedT> embed_t;
259
260    attach_action_gen(NestedT const& nested_ = non_nested_refactoring())
261    : nested(nested_) {}
262
263    template <typename ParserT, typename ActionT>
264    attach_action_parser<action<ParserT, ActionT>, NestedT>
265    operator[](action<ParserT, ActionT> const& actor) const
266    {
267        return attach_action_parser<action<ParserT, ActionT>, NestedT>
268            (actor, nested);
269    }
270
271private:
272    typename NestedT::embed_t nested;
273};
274
275const attach_action_gen<> attach_action_d = attach_action_gen<>();
276
277#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
278#pragma warning(pop)
279#endif
280
281///////////////////////////////////////////////////////////////////////////////
282BOOST_SPIRIT_CLASSIC_NAMESPACE_END
283
284}} // namespace BOOST_SPIRIT_CLASSIC_NS
285
286#endif // BOOST_SPIRIT_REFACTORING_HPP
287