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