summaryrefslogtreecommitdiff
path: root/boost/spirit/home/x3/core/parse.hpp
blob: 21162409d8010d51d2e8cbe061783bacf6f5b2e5 (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
/*=============================================================================
    Copyright (c) 2001-2014 Joel de Guzman

    Distributed under 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_X3_PARSE_APRIL_16_2006_0442PM)
#define BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM

#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/iterator/iterator_concepts.hpp>

namespace boost { namespace spirit { namespace x3
{
    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser, typename Attribute>
    inline bool
    parse_main(
        Iterator& first
      , Iterator last
      , Parser const& p
      , Attribute& attr)
    {
        // Make sure the iterator is at least a readable forward traversal iterator.
        // If you got a compilation error here, then you are using a weaker iterator
        // while calling this function, you need to supply a readable forward traversal
        // iterator instead.
        BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>));
        BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>));

        // If you get an error no matching function for call to 'as_parser'
        // here, then p is not a parser or there is no suitable conversion
        // from p to a parser.
        return as_parser(p).parse(first, last, unused, unused, attr);
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser, typename Attribute>
    inline bool
    parse(
        Iterator& first
      , Iterator last
      , Parser const& p
      , Attribute& attr)
    {
        return parse_main(first, last, p, attr);
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser, typename Attribute>
    inline bool
    parse(
        Iterator const& first_
      , Iterator last
      , Parser const& p
      , Attribute& attr)
    {
        Iterator first = first_;
        return parse_main(first, last, p, attr);
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser>
    inline bool
    parse(
        Iterator& first
      , Iterator last
      , Parser const& p)
    {
        return parse_main(first, last, p, unused);
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser>
    inline bool
    parse(
        Iterator const& first_
      , Iterator last
      , Parser const& p)
    {
        Iterator first = first_;
        return parse_main(first, last, p, unused);
    }

    ///////////////////////////////////////////////////////////////////////////
    enum class skip_flag
    {
        post_skip,      // force post-skipping in phrase_parse()
        dont_post_skip  // inhibit post-skipping in phrase_parse()
    };

    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
    inline bool
    phrase_parse_main(
        Iterator& first
      , Iterator last
      , Parser const& p
      , Skipper const& s
      , Attribute& attr
      , skip_flag post_skip = skip_flag::post_skip)
    {
        // Make sure the iterator is at least a readable forward traversal iterator.
        // If you got a compilation error here, then you are using a weaker iterator
        // while calling this function, you need to supply a readable forward traversal
        // iterator instead.
        BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>));
        BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>));
        
        static_assert(!std::is_same<Skipper, unused_type>::value,
            "Error! Skipper cannot be unused_type.");

        // If you get an error no matching function for call to 'as_parser'
        // here, for either p or s, then p or s is not a parser or there is
        // no suitable conversion from p to a parser.
        auto skipper_ctx = make_context<skipper_tag>(as_parser(s));
        bool r = as_parser(p).parse(first, last, skipper_ctx, unused, attr);
        if (post_skip == skip_flag::post_skip)
            x3::skip_over(first, last, skipper_ctx);
        return r;
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
    inline bool
    phrase_parse(
        Iterator& first
      , Iterator last
      , Parser const& p
      , Skipper const& s
      , Attribute& attr
      , skip_flag post_skip = skip_flag::post_skip)
    {
        return phrase_parse_main(first, last, p, s, attr, post_skip);
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
    inline bool
    phrase_parse(
        Iterator const& first_
      , Iterator last
      , Parser const& p
      , Skipper const& s
      , Attribute& attr
      , skip_flag post_skip = skip_flag::post_skip)
    {
        Iterator first = first_;
        return phrase_parse_main(first, last, p, s, attr, post_skip);
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser, typename Skipper>
    inline bool
    phrase_parse(
        Iterator& first
      , Iterator last
      , Parser const& p
      , Skipper const& s
      , skip_flag post_skip = skip_flag::post_skip)
    {
        return phrase_parse_main(first, last, p, s, unused, post_skip);
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename Iterator, typename Parser, typename Skipper>
    inline bool
    phrase_parse(
        Iterator const& first_
      , Iterator last
      , Parser const& p
      , Skipper const& s
      , skip_flag post_skip = skip_flag::post_skip)
    {
        Iterator first = first_;
        return phrase_parse_main(first, last, p, s, unused, post_skip);
    }
    
    ///////////////////////////////////////////////////////////////////////////
    template <typename Skipper>
    struct phrase_parse_context
    {
        typedef decltype(
            make_context<skipper_tag>(as_parser(std::declval<Skipper>())))
        type;
    };
}}}

#endif