liuxiaolong
2021-07-20 58d904a328c0d849769b483e901a0be9426b8209
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
/*=============================================================================
    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)
=============================================================================*/
#if !defined(BOOST_SPIRIT_FUNDAMENTAL_IPP)
#define BOOST_SPIRIT_FUNDAMENTAL_IPP
 
#include <boost/mpl/int.hpp>
 
namespace boost { namespace spirit {
 
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
 
namespace impl
{
    ///////////////////////////////////////////////////////////////////////////
    //
    //  Helper template for counting the number of nodes contained in a
    //  given parser type.
    //  All parser_category type parsers are counted as nodes.
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename CategoryT>
    struct nodes;
 
    template <>
    struct nodes<plain_parser_category> {
 
        template <typename ParserT, typename LeafCountT>
        struct count {
 
            BOOST_STATIC_CONSTANT(int, value = (LeafCountT::value + 1));
        };
    };
 
    template <>
    struct nodes<unary_parser_category> {
 
        template <typename ParserT, typename LeafCountT>
        struct count {
 
            typedef typename ParserT::subject_t             subject_t;
            typedef typename subject_t::parser_category_t   subject_category_t;
 
            BOOST_STATIC_CONSTANT(int, value = (nodes<subject_category_t>
                ::template count<subject_t, LeafCountT>::value + 1));
        };
    };
 
    template <>
    struct nodes<action_parser_category> {
 
        template <typename ParserT, typename LeafCountT>
        struct count {
 
            typedef typename ParserT::subject_t             subject_t;
            typedef typename subject_t::parser_category_t   subject_category_t;
 
            BOOST_STATIC_CONSTANT(int, value = (nodes<subject_category_t>
                ::template count<subject_t, LeafCountT>::value + 1));
        };
    };
 
    template <>
    struct nodes<binary_parser_category> {
 
        template <typename ParserT, typename LeafCountT>
        struct count {
 
            typedef typename ParserT::left_t                left_t;
            typedef typename ParserT::right_t               right_t;
            typedef typename left_t::parser_category_t      left_category_t;
            typedef typename right_t::parser_category_t     right_category_t;
 
            typedef count self_t;
 
            BOOST_STATIC_CONSTANT(int,
                leftcount = (nodes<left_category_t>
                    ::template count<left_t, LeafCountT>::value));
            BOOST_STATIC_CONSTANT(int,
                rightcount = (nodes<right_category_t>
                    ::template count<right_t, LeafCountT>::value));
            BOOST_STATIC_CONSTANT(int,
                value = ((self_t::leftcount) + (self_t::rightcount) + 1));
        };
    };
 
    ///////////////////////////////////////////////////////////////////////////
    //
    //  Helper template for counting the number of leaf nodes contained in a
    //  given parser type.
    //  Only plain_parser_category type parsers are counted as leaf nodes.
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename CategoryT>
    struct leafs;
 
    template <>
    struct leafs<plain_parser_category> {
 
        template <typename ParserT, typename LeafCountT>
        struct count {
 
            BOOST_STATIC_CONSTANT(int, value = (LeafCountT::value + 1));
        };
    };
 
    template <>
    struct leafs<unary_parser_category> {
 
        template <typename ParserT, typename LeafCountT>
        struct count {
 
            typedef typename ParserT::subject_t             subject_t;
            typedef typename subject_t::parser_category_t   subject_category_t;
 
            BOOST_STATIC_CONSTANT(int, value = (leafs<subject_category_t>
                ::template count<subject_t, LeafCountT>::value));
        };
    };
 
    template <>
    struct leafs<action_parser_category> {
 
        template <typename ParserT, typename LeafCountT>
        struct count {
 
            typedef typename ParserT::subject_t             subject_t;
            typedef typename subject_t::parser_category_t   subject_category_t;
 
            BOOST_STATIC_CONSTANT(int, value = (leafs<subject_category_t>
                ::template count<subject_t, LeafCountT>::value));
        };
    };
 
    template <>
    struct leafs<binary_parser_category> {
 
        template <typename ParserT, typename LeafCountT>
        struct count {
 
            typedef typename ParserT::left_t                left_t;
            typedef typename ParserT::right_t               right_t;
            typedef typename left_t::parser_category_t      left_category_t;
            typedef typename right_t::parser_category_t     right_category_t;
 
            typedef count self_t;
 
            BOOST_STATIC_CONSTANT(int,
                leftcount = (leafs<left_category_t>
                    ::template count<left_t, LeafCountT>::value));
            BOOST_STATIC_CONSTANT(int,
                rightcount = (leafs<right_category_t>
                    ::template count<right_t, LeafCountT>::value));
            BOOST_STATIC_CONSTANT(int,
                value = (self_t::leftcount + self_t::rightcount));
        };
    };
 
}   // namespace impl
 
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
 
}} // namespace boost::spirit
 
#endif // !defined(BOOST_SPIRIT_FUNDAMENTAL_IPP)