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