1 // Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey 2 // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ 3 4 #ifndef TAO_PEGTL_NORMAL_HPP 5 #define TAO_PEGTL_NORMAL_HPP 6 7 #include <utility> 8 9 #include "apply_mode.hpp" 10 #include "config.hpp" 11 #include "nothing.hpp" 12 #include "parse_error.hpp" 13 #include "rewind_mode.hpp" 14 15 #include "internal/demangle.hpp" 16 #include "internal/dusel_mode.hpp" 17 #include "internal/duseltronik.hpp" 18 #include "internal/has_apply.hpp" 19 #include "internal/has_apply0.hpp" 20 #include "internal/skip_control.hpp" 21 22 namespace tao 23 { 24 namespace TAO_PEGTL_NAMESPACE 25 { 26 template< typename Rule > 27 struct normal 28 { 29 template< typename Input, typename... States > starttao::TAO_PEGTL_NAMESPACE::normal30 static void start( const Input& /*unused*/, States&&... /*unused*/ ) noexcept 31 { 32 } 33 34 template< typename Input, typename... States > successtao::TAO_PEGTL_NAMESPACE::normal35 static void success( const Input& /*unused*/, States&&... /*unused*/ ) noexcept 36 { 37 } 38 39 template< typename Input, typename... States > failuretao::TAO_PEGTL_NAMESPACE::normal40 static void failure( const Input& /*unused*/, States&&... /*unused*/ ) noexcept 41 { 42 } 43 44 template< typename Input, typename... States > raisetao::TAO_PEGTL_NAMESPACE::normal45 static void raise( const Input& in, States&&... /*unused*/ ) 46 { 47 throw parse_error( "parse error matching " + internal::demangle< Rule >(), in ); 48 } 49 50 template< template< typename... > class Action, typename Input, typename... States > apply0tao::TAO_PEGTL_NAMESPACE::normal51 static auto apply0( const Input& /*unused*/, States&&... st ) 52 -> decltype( Action< Rule >::apply0( st... ) ) 53 { 54 return Action< Rule >::apply0( st... ); 55 } 56 57 template< template< typename... > class Action, typename Iterator, typename Input, typename... States > applytao::TAO_PEGTL_NAMESPACE::normal58 static auto apply( const Iterator& begin, const Input& in, States&&... st ) 59 -> decltype( Action< Rule >::apply( std::declval< typename Input::action_t >(), st... ) ) 60 { 61 const typename Input::action_t action_input( begin, in ); 62 return Action< Rule >::apply( action_input, st... ); 63 } 64 65 template< apply_mode A, 66 rewind_mode M, 67 template< typename... > class Action, 68 template< typename... > class Control, 69 typename Input, 70 typename... States > matchtao::TAO_PEGTL_NAMESPACE::normal71 static bool match( Input& in, States&&... st ) 72 { 73 constexpr char use_control = !internal::skip_control< Rule >::value; 74 constexpr char use_action = use_control && ( A == apply_mode::ACTION ) && ( !is_nothing< Action, Rule >::value ); 75 constexpr char use_apply_void = use_action && internal::has_apply< Action< Rule >, void, typename Input::action_t, States... >::value; 76 constexpr char use_apply_bool = use_action && internal::has_apply< Action< Rule >, bool, typename Input::action_t, States... >::value; 77 constexpr char use_apply0_void = use_action && internal::has_apply0< Action< Rule >, void, States... >::value; 78 constexpr char use_apply0_bool = use_action && internal::has_apply0< Action< Rule >, bool, States... >::value; 79 static_assert( !use_action || use_apply_bool || use_apply_void || use_apply0_bool || use_apply0_void, "actions not disabled but no apply() or apply0() found" ); 80 static_assert( use_apply_void + use_apply_bool + use_apply0_void + use_apply0_bool < 2, "both apply() and apply0() defined" ); 81 constexpr auto mode = static_cast< dusel_mode >( use_control + use_apply_void + 2 * use_apply_bool + 3 * use_apply0_void + 4 * use_apply0_bool ); 82 return internal::duseltronik< Rule, A, M, Action, Control, mode >::match( in, st... ); 83 } 84 }; 85 86 } // namespace TAO_PEGTL_NAMESPACE 87 88 } // namespace tao 89 90 #endif 91