zhangmeng
2021-07-02 056f71f24cefaf88f2a93714c6678c03ed5f1e0e
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
/*=============================================================================
    Copyright (c) 2002-2003 Hartmut Kaiser
    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)
=============================================================================*/
#ifndef BOOST_SPIRIT_LISTS_IPP
#define BOOST_SPIRIT_LISTS_IPP
 
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/meta/refactoring.hpp>
 
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
 
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
 
///////////////////////////////////////////////////////////////////////////////
//
//  list_parser_type class implementation
//
///////////////////////////////////////////////////////////////////////////////
struct no_list_endtoken { typedef no_list_endtoken embed_t; };
 
namespace impl {
 
///////////////////////////////////////////////////////////////////////////////
//
//  Refactor the original list item parser
//
///////////////////////////////////////////////////////////////////////////////
 
    //  match list with 'extended' syntax
    template <typename EndT>
    struct select_list_parse_refactor {
 
        template <
            typename ParserT, typename ScannerT,
            typename ItemT, typename DelimT
        >
        static typename parser_result<ParserT, ScannerT>::type
        parse(ScannerT const& scan, ParserT const& /*p*/,
            ItemT const &item, DelimT const &delim, EndT const &end)
        {
            typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
            const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
 
            return (
                    refactor_item_d[item - (end | delim)]
                >> *(delim >> refactor_item_d[item - (end | delim)])
                >> !(delim >> end)
            ).parse(scan);
        }
    };
 
    //  match list with 'normal' syntax (without an 'end' parser)
    template <>
    struct select_list_parse_refactor<no_list_endtoken> {
 
        template <
            typename ParserT, typename ScannerT,
            typename ItemT, typename DelimT
        >
        static typename parser_result<ParserT, ScannerT>::type
        parse(ScannerT const& scan, ParserT const& /*p*/,
            ItemT const &item, DelimT const &delim, no_list_endtoken const&)
        {
            typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
            const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
 
            return (
                    refactor_item_d[item - delim]
                >> *(delim >> refactor_item_d[item - delim])
            ).parse(scan);
        }
    };
 
///////////////////////////////////////////////////////////////////////////////
//
//  Do not refactor the original list item parser.
//
///////////////////////////////////////////////////////////////////////////////
 
    //  match list with 'extended' syntax
    template <typename EndT>
    struct select_list_parse_no_refactor {
 
        template <
            typename ParserT, typename ScannerT,
            typename ItemT, typename DelimT
        >
        static typename parser_result<ParserT, ScannerT>::type
        parse(ScannerT const& scan, ParserT const& /*p*/,
            ItemT const &item, DelimT const &delim, EndT const &end)
        {
            return (
                    (item - (end | delim))
                >> *(delim >> (item - (end | delim)))
                >> !(delim >> end)
            ).parse(scan);
        }
    };
 
    //  match list with 'normal' syntax (without an 'end' parser)
    template <>
    struct select_list_parse_no_refactor<no_list_endtoken> {
 
        template <
            typename ParserT, typename ScannerT,
            typename ItemT, typename DelimT
        >
        static typename parser_result<ParserT, ScannerT>::type
        parse(ScannerT const& scan, ParserT const& /*p*/,
            ItemT const &item, DelimT const &delim, no_list_endtoken const&)
        {
            return (
                    (item - delim)
                >> *(delim >> (item - delim))
            ).parse(scan);
        }
    };
 
    // the refactoring is handled by the refactoring parsers, so here there
    // is no need to pay attention to these issues.
 
    template <typename CategoryT>
    struct list_parser_type {
 
        template <
            typename ParserT, typename ScannerT,
            typename ItemT, typename DelimT, typename EndT
        >
        static typename parser_result<ParserT, ScannerT>::type
        parse(ScannerT const& scan, ParserT const& p,
              ItemT const &item, DelimT const &delim, EndT const &end)
        {
            return select_list_parse_refactor<EndT>::
                parse(scan, p, item, delim, end);
        }
    };
 
    template <>
    struct list_parser_type<plain_parser_category> {
 
        template <
            typename ParserT, typename ScannerT,
            typename ItemT, typename DelimT, typename EndT
        >
        static typename parser_result<ParserT, ScannerT>::type
        parse(ScannerT const& scan, ParserT const& p,
              ItemT const &item, DelimT const &delim, EndT const &end)
        {
            return select_list_parse_no_refactor<EndT>::
                parse(scan, p, item, delim, end);
        }
    };
 
}   // namespace impl
 
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
 
}} // namespace boost::spirit
 
#endif