1 // Copyright (c) 2020 Dr. Colin Hirsch and Daniel Frey
2 // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/
3 
4 #ifndef TAO_PEGTL_CONTRIB_ANALYZE_TRAITS_HPP
5 #define TAO_PEGTL_CONTRIB_ANALYZE_TRAITS_HPP
6 
7 #include <type_traits>
8 
9 #include "../ascii.hpp"
10 #include "../config.hpp"
11 #include "../rules.hpp"
12 #include "../type_list.hpp"
13 
14 #include "forward.hpp"
15 
16 namespace TAO_PEGTL_NAMESPACE
17 {
18    namespace internal
19    {
20       enum class analyze_type
21       {
22          any,  // Consumption-on-success is always true; assumes bounded repetition of conjunction of sub-rules.
23          opt,  // Consumption-on-success not necessarily true; assumes bounded repetition of conjunction of sub-rules.
24          seq,  // Consumption-on-success depends on consumption of (non-zero bounded repetition of) conjunction of sub-rules.
25          sor   // Consumption-on-success depends on consumption of (non-zero bounded repetition of) disjunction of sub-rules.
26       };
27 
28    }  // namespace internal
29 
30    template< typename... Rules >
31    struct analyze_any_traits
32    {
33       static constexpr internal::analyze_type type_v = internal::analyze_type::any;
34       using subs_t = type_list< Rules... >;
35    };
36 
37    template< typename... Rules >
38    struct analyze_opt_traits
39    {
40       static constexpr internal::analyze_type type_v = internal::analyze_type::opt;
41       using subs_t = type_list< Rules... >;
42    };
43 
44    template< typename... Rules >
45    struct analyze_seq_traits
46    {
47       static constexpr internal::analyze_type type_v = internal::analyze_type::seq;
48       using subs_t = type_list< Rules... >;
49    };
50 
51    template< typename... Rules >
52    struct analyze_sor_traits
53    {
54       static constexpr internal::analyze_type type_v = internal::analyze_type::sor;
55       using subs_t = type_list< Rules... >;
56    };
57 
58    template< typename Name, template< typename... > class Action, typename... Rules >
59    struct analyze_traits< Name, internal::action< Action, Rules... > >
60       : analyze_traits< Name, typename seq< Rules... >::rule_t >
61    {};
62 
63    template< typename Name, typename Peek >
64    struct analyze_traits< Name, internal::any< Peek > >
65       : analyze_any_traits<>
66    {};
67 
68    template< typename Name, typename... Actions >
69    struct analyze_traits< Name, internal::apply< Actions... > >
70       : analyze_opt_traits<>
71    {};
72 
73    template< typename Name, typename... Actions >
74    struct analyze_traits< Name, internal::apply0< Actions... > >
75       : analyze_opt_traits<>
76    {};
77 
78    template< typename Name, typename... Rules >
79    struct analyze_traits< Name, internal::at< Rules... > >
80       : analyze_traits< Name, typename opt< Rules... >::rule_t >
81    {};
82 
83    template< typename Name >
84    struct analyze_traits< Name, internal::bof >
85       : analyze_opt_traits<>
86    {};
87 
88    template< typename Name >
89    struct analyze_traits< Name, internal::bol >
90       : analyze_opt_traits<>
91    {};
92 
93    template< typename Name, unsigned Cnt >
94    struct analyze_traits< Name, internal::bytes< Cnt > >
95       : std::conditional_t< ( Cnt != 0 ), analyze_any_traits<>, analyze_opt_traits<> >
96    {};
97 
98    template< typename Name, template< typename... > class Control, typename... Rules >
99    struct analyze_traits< Name, internal::control< Control, Rules... > >
100       : analyze_traits< Name, typename seq< Rules... >::rule_t >
101    {};
102 
103    template< typename Name, typename... Rules >
104    struct analyze_traits< Name, internal::disable< Rules... > >
105       : analyze_traits< Name, typename seq< Rules... >::rule_t >
106    {};
107 
108    template< typename Name >
109    struct analyze_traits< Name, internal::discard >
110       : analyze_opt_traits<>
111    {};
112 
113    template< typename Name, typename... Rules >
114    struct analyze_traits< Name, internal::enable< Rules... > >
115       : analyze_traits< Name, typename seq< Rules... >::rule_t >
116    {};
117 
118    template< typename Name >
119    struct analyze_traits< Name, internal::eof >
120       : analyze_opt_traits<>
121    {};
122 
123    template< typename Name >
124    struct analyze_traits< Name, internal::eol >
125       : analyze_any_traits<>
126    {};
127 
128    template< typename Name >
129    struct analyze_traits< Name, internal::eolf >
130       : analyze_opt_traits<>
131    {};
132 
133    template< typename Name >
134    struct analyze_traits< Name, internal::failure >
135       : analyze_any_traits<>
136    {};
137 
138    template< typename Name, typename Rule, typename... Actions >
139    struct analyze_traits< Name, internal::if_apply< Rule, Actions... > >
140       : analyze_traits< Name, typename Rule::rule_t >
141    {};
142 
143    template< typename Name, typename Cond, typename... Rules >
144    struct analyze_traits< Name, internal::if_must< true, Cond, Rules... > >
145       : analyze_traits< Name, typename opt< Cond, Rules... >::rule_t >
146    {};
147 
148    template< typename Name, typename Cond, typename... Rules >
149    struct analyze_traits< Name, internal::if_must< false, Cond, Rules... > >
150       : analyze_traits< Name, typename seq< Cond, Rules... >::rule_t >
151    {};
152 
153    template< typename Name, typename Cond, typename Then, typename Else >
154    struct analyze_traits< Name, internal::if_then_else< Cond, Then, Else > >
155       : analyze_traits< Name, typename sor< seq< Cond, Then >, Else >::rule_t >
156    {};
157 
158    template< typename Name, char... Cs >
159    struct analyze_traits< Name, internal::istring< Cs... > >
160       : std::conditional_t< ( sizeof...( Cs ) != 0 ), analyze_any_traits<>, analyze_opt_traits<> >
161    {};
162 
163    template< typename Name, typename... Rules >
164    struct analyze_traits< Name, internal::must< Rules... > >
165       : analyze_traits< Name, typename seq< Rules... >::rule_t >
166    {};
167 
168    template< typename Name, typename... Rules >
169    struct analyze_traits< Name, internal::not_at< Rules... > >
170       : analyze_traits< Name, typename opt< Rules... >::rule_t >
171    {};
172 
173    template< typename Name, internal::result_on_found R, typename Peek, typename Peek::data_t... Cs >
174    struct analyze_traits< Name, internal::one< R, Peek, Cs... > >
175       : analyze_any_traits<>
176    {};
177 
178    template< typename Name, typename Rule, typename... Rules >
179    struct analyze_traits< Name, internal::opt< Rule, Rules... > >
180       : analyze_opt_traits< Rule, Rules... >
181    {};
182 
183    template< typename Name, typename... Rules >
184    struct analyze_traits< Name, internal::plus< Rules... > >
185       : analyze_traits< Name, typename seq< Rules..., opt< Name > >::rule_t >
186    {};
187 
188    template< typename Name, typename T >
189    struct analyze_traits< Name, internal::raise< T > >
190       : analyze_any_traits<>
191    {};
192 
193    template< typename Name, internal::result_on_found R, typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi >
194    struct analyze_traits< Name, internal::range< R, Peek, Lo, Hi > >
195       : analyze_any_traits<>
196    {};
197 
198    template< typename Name, typename Peek, typename Peek::data_t... Cs >
199    struct analyze_traits< Name, internal::ranges< Peek, Cs... > >
200       : analyze_any_traits<>
201    {};
202 
203    template< typename Name, typename Head, typename... Rules >
204    struct analyze_traits< Name, internal::rematch< Head, Rules... > >
205       : analyze_traits< Name, typename sor< Head, sor< seq< Rules, any >... > >::rule_t >  // TODO: Correct (enough)?
206    {};
207 
208    template< typename Name, unsigned Cnt, typename... Rules >
209    struct analyze_traits< Name, internal::rep< Cnt, Rules... > >
210       : analyze_traits< Name, std::conditional_t< ( Cnt != 0 ), typename seq< Rules... >::rule_t, typename opt< Rules... >::rule_t > >
211    {};
212 
213    template< typename Name, unsigned Min, unsigned Max, typename... Rules >
214    struct analyze_traits< Name, internal::rep_min_max< Min, Max, Rules... > >
215       : analyze_traits< Name, std::conditional_t< ( Min != 0 ), typename seq< Rules... >::rule_t, typename opt< Rules... >::rule_t > >
216    {};
217 
218    template< typename Name, unsigned Max, typename... Rules >
219    struct analyze_traits< Name, internal::rep_opt< Max, Rules... > >
220       : analyze_traits< Name, typename opt< Rules... >::rule_t >
221    {};
222 
223    template< typename Name, unsigned Amount >
224    struct analyze_traits< Name, internal::require< Amount > >
225       : analyze_opt_traits<>
226    {};
227 
228    template< typename Name, typename Rule, typename... Rules >
229    struct analyze_traits< Name, internal::seq< Rule, Rules... > >
230       : analyze_seq_traits< Rule, Rules... >
231    {};
232 
233    template< typename Name, typename Rule, typename... Rules >
234    struct analyze_traits< Name, internal::sor< Rule, Rules... > >
235       : analyze_sor_traits< Rule, Rules... >
236    {};
237 
238    template< typename Name, typename... Rules >
239    struct analyze_traits< Name, internal::star< Rules... > >
240       : analyze_traits< Name, typename opt< Rules..., Name >::rule_t >
241    {};
242 
243    template< typename Name, typename State, typename... Rules >
244    struct analyze_traits< Name, internal::state< State, Rules... > >
245       : analyze_traits< Name, typename seq< Rules... >::rule_t >
246    {};
247 
248    template< typename Name, char... Cs >
249    struct analyze_traits< Name, internal::string< Cs... > >
250       : std::conditional_t< ( sizeof...( Cs ) != 0 ), analyze_any_traits<>, analyze_opt_traits<> >
251    {};
252 
253    template< typename Name >
254    struct analyze_traits< Name, internal::success >
255       : analyze_opt_traits<>
256    {};
257 
258    template< typename Name, typename Exception, typename... Rules >
259    struct analyze_traits< Name, internal::try_catch_type< Exception, Rules... > >
260       : analyze_traits< Name, typename seq< Rules... >::rule_t >
261    {};
262 
263    template< typename Name, typename Cond >
264    struct analyze_traits< Name, internal::until< Cond > >
265       : analyze_traits< Name, typename Cond::rule_t >
266    {};
267 
268    template< typename Name, typename Cond, typename... Rules >
269    struct analyze_traits< Name, internal::until< Cond, Rules... > >
270       : analyze_traits< Name, typename seq< star< Rules... >, Cond >::rule_t >
271    {};
272 
273 }  // namespace TAO_PEGTL_NAMESPACE
274 
275 #endif
276