source: NonGTP/Boost/boost/spirit/utility/impl/confix.ipp @ 857

Revision 857, 7.7 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Copyright (c) 2002-2003 Hartmut Kaiser
3    http://spirit.sourceforge.net/
4
5    Use, modification and distribution is subject to the Boost Software
6    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7    http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9#ifndef BOOST_SPIRIT_CONFIX_IPP
10#define BOOST_SPIRIT_CONFIX_IPP
11
12///////////////////////////////////////////////////////////////////////////////
13#include <boost/spirit/meta/refactoring.hpp>
14#include <boost/spirit/core/composite/impl/directives.ipp>
15
16///////////////////////////////////////////////////////////////////////////////
17namespace boost { namespace spirit {
18
19///////////////////////////////////////////////////////////////////////////////
20//
21//  Types to distinguish nested and non-nested confix parsers
22//
23///////////////////////////////////////////////////////////////////////////////
24struct is_nested {};
25struct non_nested {};
26
27///////////////////////////////////////////////////////////////////////////////
28//
29//  Types to distinguish between confix parsers, which are implicitly lexems
30//  and without this behaviour
31//
32///////////////////////////////////////////////////////////////////////////////
33struct is_lexeme {};
34struct non_lexeme {};
35
36///////////////////////////////////////////////////////////////////////////////
37//
38//  confix_parser_type class implementation
39//
40///////////////////////////////////////////////////////////////////////////////
41namespace impl {
42
43    ///////////////////////////////////////////////////////////////////////////
44    //  implicitly insert a lexeme_d into the parsing process
45
46    template <typename LexemeT>
47    struct select_confix_parse_lexeme;
48
49    template <>
50    struct select_confix_parse_lexeme<is_lexeme> {
51
52        template <typename ParserT, typename ScannerT>
53        static typename parser_result<ParserT, ScannerT>::type
54        parse(ParserT const& p, ScannerT const& scan)
55        {
56            typedef typename parser_result<ParserT, ScannerT>::type result_t;
57            return contiguous_parser_parse<result_t>(p, scan, scan);
58        }
59    };
60
61    template <>
62    struct select_confix_parse_lexeme<non_lexeme> {
63
64        template <typename ParserT, typename ScannerT>
65        static typename parser_result<ParserT, ScannerT>::type
66        parse(ParserT const& p, ScannerT const& scan)
67        {
68            return p.parse(scan);
69        }
70    };
71
72    ///////////////////////////////////////////////////////////////////////////
73    //  parse confix sequences with refactoring
74
75    template <typename NestedT>
76    struct select_confix_parse_refactor;
77
78    template <>
79    struct select_confix_parse_refactor<is_nested> {
80
81        template <
82            typename LexemeT, typename ParserT, typename ScannerT,
83            typename OpenT, typename ExprT, typename CloseT
84        >
85        static typename parser_result<ParserT, ScannerT>::type
86        parse(
87            LexemeT const &, ParserT const& this_, ScannerT const& scan,
88            OpenT const& open, ExprT const& expr, CloseT const& close)
89        {
90            typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
91            const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
92
93            return select_confix_parse_lexeme<LexemeT>::parse((
94                            open
95                        >>  (this_ | refactor_body_d[expr - close])
96                        >>  close
97                    ),  scan);
98        }
99    };
100
101    template <>
102    struct select_confix_parse_refactor<non_nested> {
103
104        template <
105            typename LexemeT, typename ParserT, typename ScannerT,
106            typename OpenT, typename ExprT, typename CloseT
107        >
108        static typename parser_result<ParserT, ScannerT>::type
109        parse(
110            LexemeT const &, ParserT const& /*this_*/, ScannerT const& scan,
111            OpenT const& open, ExprT const& expr, CloseT const& close)
112        {
113            typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
114            const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
115
116            return select_confix_parse_lexeme<LexemeT>::parse((
117                            open
118                        >>  refactor_body_d[expr - close]
119                        >>  close
120                    ),  scan);
121        }
122    };
123
124    ///////////////////////////////////////////////////////////////////////////
125    //  parse confix sequences without refactoring
126
127    template <typename NestedT>
128    struct select_confix_parse_no_refactor;
129
130    template <>
131    struct select_confix_parse_no_refactor<is_nested> {
132
133        template <
134            typename LexemeT, typename ParserT, typename ScannerT,
135            typename OpenT, typename ExprT, typename CloseT
136        >
137        static typename parser_result<ParserT, ScannerT>::type
138        parse(
139            LexemeT const &, ParserT const& this_, ScannerT const& scan,
140            OpenT const& open, ExprT const& expr, CloseT const& close)
141        {
142            return select_confix_parse_lexeme<LexemeT>::parse((
143                            open
144                        >>  (this_ | (expr - close))
145                        >>  close
146                    ),  scan);
147        }
148    };
149
150    template <>
151    struct select_confix_parse_no_refactor<non_nested> {
152
153        template <
154            typename LexemeT, typename ParserT, typename ScannerT,
155            typename OpenT, typename ExprT, typename CloseT
156        >
157        static typename parser_result<ParserT, ScannerT>::type
158        parse(
159            LexemeT const &, ParserT const & /*this_*/, ScannerT const& scan,
160            OpenT const& open, ExprT const& expr, CloseT const& close)
161        {
162            return select_confix_parse_lexeme<LexemeT>::parse((
163                            open
164                        >>  (expr - close)
165                        >>  close
166                    ),  scan);
167        }
168    };
169
170    // the refactoring is handled by the refactoring parsers, so here there
171    // is no need to pay attention to these issues.
172
173    template <typename CategoryT>
174    struct confix_parser_type {
175
176        template <
177            typename NestedT, typename LexemeT,
178            typename ParserT, typename ScannerT,
179            typename OpenT, typename ExprT, typename CloseT
180        >
181        static typename parser_result<ParserT, ScannerT>::type
182        parse(
183            NestedT const &, LexemeT const &lexeme,
184            ParserT const& this_, ScannerT const& scan,
185            OpenT const& open, ExprT const& expr, CloseT const& close)
186        {
187            return select_confix_parse_refactor<NestedT>::
188                parse(lexeme, this_, scan, open, expr, close);
189        }
190    };
191
192    template <>
193    struct confix_parser_type<plain_parser_category> {
194
195        template <
196            typename NestedT, typename LexemeT,
197            typename ParserT, typename ScannerT,
198            typename OpenT, typename ExprT, typename CloseT
199        >
200        static typename parser_result<ParserT, ScannerT>::type
201        parse(
202            NestedT const &, LexemeT const &lexeme,
203            ParserT const& this_, ScannerT const& scan,
204            OpenT const& open, ExprT const& expr, CloseT const& close)
205        {
206            return select_confix_parse_no_refactor<NestedT>::
207                parse(lexeme, this_, scan, open, expr, close);
208        }
209    };
210
211}   // namespace impl
212
213///////////////////////////////////////////////////////////////////////////////
214}} // namespace boost::spirit
215
216#endif
217
Note: See TracBrowser for help on using the repository browser.