Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2003 Hartmut Kaiser
|
Chris@16
|
3 http://spirit.sourceforge.net/
|
Chris@16
|
4
|
Chris@16
|
5 Use, modification and distribution is subject to the Boost Software
|
Chris@16
|
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 =============================================================================*/
|
Chris@16
|
9 #ifndef BOOST_SPIRIT_SELECT_IPP
|
Chris@16
|
10 #define BOOST_SPIRIT_SELECT_IPP
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/spirit/home/classic/core/parser.hpp>
|
Chris@16
|
13 #include <boost/spirit/home/classic/core/composite/composite.hpp>
|
Chris@16
|
14 #include <boost/spirit/home/classic/meta/as_parser.hpp>
|
Chris@16
|
15
|
Chris@16
|
16 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
17 namespace boost { namespace spirit {
|
Chris@16
|
18
|
Chris@16
|
19 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
Chris@16
|
20
|
Chris@16
|
21 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
22 namespace impl {
|
Chris@16
|
23
|
Chris@16
|
24 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
25 template <typename ParserT>
|
Chris@16
|
26 struct as_embedded_parser : public as_parser<ParserT>
|
Chris@16
|
27 {
|
Chris@16
|
28 typedef typename as_parser<ParserT>::type::derived_t::embed_t type;
|
Chris@16
|
29 };
|
Chris@16
|
30
|
Chris@16
|
31 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
32
|
Chris@16
|
33 // no implementation here to catch unknown BehaviourT template arguments
|
Chris@16
|
34 template <typename ResultT, typename BehaviourT>
|
Chris@16
|
35 struct select_match_gen;
|
Chris@16
|
36
|
Chris@16
|
37 // implementation for the select_default_no_fail behaviour
|
Chris@16
|
38 template <typename ResultT>
|
Chris@16
|
39 struct select_match_gen<ResultT, select_default_no_fail> {
|
Chris@16
|
40
|
Chris@16
|
41 template <typename ScannerT>
|
Chris@16
|
42 static ResultT
|
Chris@16
|
43 do_ (ScannerT const &scan)
|
Chris@16
|
44 {
|
Chris@16
|
45 return scan.create_match(0, -1, scan.first, scan.first);
|
Chris@16
|
46 }
|
Chris@16
|
47 };
|
Chris@16
|
48
|
Chris@16
|
49 // implementation for the select_default_fail behaviour
|
Chris@16
|
50 template <typename ResultT>
|
Chris@16
|
51 struct select_match_gen<ResultT, select_default_fail> {
|
Chris@16
|
52
|
Chris@16
|
53 template <typename ScannerT>
|
Chris@16
|
54 static ResultT
|
Chris@16
|
55 do_ (ScannerT const &scan)
|
Chris@16
|
56 {
|
Chris@16
|
57 return scan.no_match();
|
Chris@16
|
58 }
|
Chris@16
|
59 };
|
Chris@16
|
60
|
Chris@16
|
61 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
62 template <int N, typename ResultT, typename TupleT, typename BehaviourT>
|
Chris@16
|
63 struct parse_tuple_element {
|
Chris@16
|
64
|
Chris@16
|
65 BOOST_STATIC_CONSTANT(int, index = (TupleT::length - N));
|
Chris@16
|
66
|
Chris@16
|
67 template <typename ScannerT>
|
Chris@16
|
68 static ResultT
|
Chris@16
|
69 do_(TupleT const &t, ScannerT const &scan)
|
Chris@16
|
70 {
|
Chris@16
|
71 typedef typename ::phoenix::tuple_element<index, TupleT>::type parser_t;
|
Chris@16
|
72 typedef typename ScannerT::iterator_t iterator_t;
|
Chris@16
|
73 typedef typename parser_result<parser_t, ScannerT>::type result_t;
|
Chris@16
|
74
|
Chris@16
|
75 iterator_t save(scan.first);
|
Chris@16
|
76 result_t result(t[::phoenix::tuple_index<index>()].parse(scan));
|
Chris@16
|
77
|
Chris@16
|
78 if (result) {
|
Chris@16
|
79 return scan.create_match(result.length(), TupleT::length - N,
|
Chris@16
|
80 save, scan.first);
|
Chris@16
|
81 }
|
Chris@16
|
82 scan.first = save; // reset the input stream
|
Chris@16
|
83 return parse_tuple_element<N-1, ResultT, TupleT, BehaviourT>::
|
Chris@16
|
84 do_(t, scan);
|
Chris@16
|
85 }
|
Chris@16
|
86 };
|
Chris@16
|
87
|
Chris@16
|
88 template <typename ResultT, typename TupleT, typename BehaviourT>
|
Chris@16
|
89 struct parse_tuple_element<1, ResultT, TupleT, BehaviourT> {
|
Chris@16
|
90
|
Chris@16
|
91 BOOST_STATIC_CONSTANT(int, index = (TupleT::length - 1));
|
Chris@16
|
92
|
Chris@16
|
93 template <typename ScannerT>
|
Chris@16
|
94 static ResultT
|
Chris@16
|
95 do_(TupleT const &t, ScannerT const &scan)
|
Chris@16
|
96 {
|
Chris@16
|
97 typedef typename ::phoenix::tuple_element<index, TupleT>::type parser_t;
|
Chris@16
|
98 typedef typename ScannerT::iterator_t iterator_t;
|
Chris@16
|
99 typedef typename parser_result<parser_t, ScannerT>::type result_t;
|
Chris@16
|
100
|
Chris@16
|
101 iterator_t save(scan.first);
|
Chris@16
|
102 result_t result(t[::phoenix::tuple_index<index>()].parse(scan));
|
Chris@16
|
103
|
Chris@16
|
104 if (result) {
|
Chris@16
|
105 return scan.create_match(result.length(), TupleT::length - 1,
|
Chris@16
|
106 save, scan.first);
|
Chris@16
|
107 }
|
Chris@16
|
108 scan.first = save; // reset the input stream
|
Chris@16
|
109 return select_match_gen<ResultT, BehaviourT>::do_(scan);
|
Chris@16
|
110 }
|
Chris@16
|
111 };
|
Chris@16
|
112
|
Chris@16
|
113 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
114 } // namespace impl
|
Chris@16
|
115
|
Chris@16
|
116 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
Chris@16
|
117
|
Chris@16
|
118 }} // namespace boost::spirit
|
Chris@16
|
119
|
Chris@16
|
120 #endif // BOOST_SPIRIT_SELECT_IPP
|