summaryrefslogtreecommitdiffstats
blob: 96b2dd79c59a8a9167b2991f98a6094db48748ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    Copyright (c) 2001 Daniel Nuffer
    Copyright (c) 2001 Bruce Florman
    Copyright (c) 2002 Raghavendra Satish
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_DIRECTIVES_IPP)
#define BOOST_SPIRIT_DIRECTIVES_IPP

///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/core/scanner/skipper.hpp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    template <typename BaseT>
    struct no_skipper_iteration_policy;

    template <typename BaseT>
    struct inhibit_case_iteration_policy;

    template <typename A, typename B>
    struct alternative;

    template <typename A, typename B>
    struct longest_alternative;

    template <typename A, typename B>
    struct shortest_alternative;

    namespace impl
    {
        template <typename RT, typename ST, typename ScannerT, typename BaseT>
        inline RT
        contiguous_parser_parse(
            ST const& s,
            ScannerT const& scan,
            skipper_iteration_policy<BaseT> const&)
        {
            typedef scanner_policies<
                no_skipper_iteration_policy<
                    BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
                BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
                BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
            > policies_t;

            scan.skip(scan);
            RT hit = s.parse(scan.change_policies(policies_t(scan)));
            // We will not do a post skip!!!
            return hit;
        }

        template <typename RT, typename ST, typename ScannerT, typename BaseT>
        inline RT
        contiguous_parser_parse(
            ST const& s,
            ScannerT const& scan,
            no_skipper_iteration_policy<BaseT> const&)
        {
            return s.parse(scan);
        }

        template <typename RT, typename ST, typename ScannerT>
        inline RT
        contiguous_parser_parse(
            ST const& s,
            ScannerT const& scan,
            iteration_policy const&)
        {
            return s.parse(scan);
        }

        template <
            typename RT,
            typename ParserT,
            typename ScannerT,
            typename BaseT>
        inline RT
        implicit_lexeme_parse(
            ParserT const& p,
            ScannerT const& scan,
            skipper_iteration_policy<BaseT> const&)
        {
            typedef scanner_policies<
                no_skipper_iteration_policy<
                    BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
                BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
                BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
            > policies_t;

            scan.skip(scan);
            RT hit = p.parse_main(scan.change_policies(policies_t(scan)));
            // We will not do a post skip!!!
            return hit;
        }

        template <
            typename RT,
            typename ParserT,
            typename ScannerT,
            typename BaseT>
        inline RT
        implicit_lexeme_parse(
            ParserT const& p,
            ScannerT const& scan,
            no_skipper_iteration_policy<BaseT> const&)
        {
            return p.parse_main(scan);
        }

        template <typename RT, typename ParserT, typename ScannerT>
        inline RT
        implicit_lexeme_parse(
            ParserT const& p,
            ScannerT const& scan,
            iteration_policy const&)
        {
            return p.parse_main(scan);
        }

        template <typename RT, typename ST, typename ScannerT>
        inline RT
        inhibit_case_parser_parse(
            ST const& s,
            ScannerT const& scan,
            iteration_policy const&)
        {
            typedef scanner_policies<
                inhibit_case_iteration_policy<
                    BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
                BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
                BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
            > policies_t;

            return s.parse(scan.change_policies(policies_t(scan)));
        }

        template <typename RT, typename ST, typename ScannerT, typename BaseT>
        inline RT
        inhibit_case_parser_parse(
            ST const& s,
            ScannerT const& scan,
            inhibit_case_iteration_policy<BaseT> const&)
        {
            return s.parse(scan);
        }

        template <typename T>
        struct to_longest_alternative
        {
            typedef T result_t;
            static result_t const&
            convert(T const& a)  //  Special (end) case
            { return a; }
        };

        template <typename A, typename B>
        struct to_longest_alternative<alternative<A, B> >
        {
            typedef typename to_longest_alternative<A>::result_t    a_t;
            typedef typename to_longest_alternative<B>::result_t    b_t;
            typedef longest_alternative<a_t, b_t>                   result_t;

            static result_t
            convert(alternative<A, B> const& alt) // Recursive case
            {
                return result_t(
                    to_longest_alternative<A>::convert(alt.left()),
                    to_longest_alternative<B>::convert(alt.right()));
            }
        };

        template <typename T>
        struct to_shortest_alternative
        {
            typedef T result_t;
            static result_t const&
            convert(T const& a) //  Special (end) case
            { return a; }
        };

        template <typename A, typename B>
        struct to_shortest_alternative<alternative<A, B> >
        {
            typedef typename to_shortest_alternative<A>::result_t   a_t;
            typedef typename to_shortest_alternative<B>::result_t   b_t;
            typedef shortest_alternative<a_t, b_t>                  result_t;

            static result_t
            convert(alternative<A, B> const& alt) //  Recursive case
            {
                return result_t(
                    to_shortest_alternative<A>::convert(alt.left()),
                    to_shortest_alternative<B>::convert(alt.right()));
            }
        };
    }

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace boost::spirit

#endif