1/*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 Copyright (c) 2001 Daniel Nuffer 4 Copyright (c) 2001 Bruce Florman 5 Copyright (c) 2002 Raghavendra Satish 6 http://spirit.sourceforge.net/ 7 8 Use, modification and distribution is subject to the Boost Software 9 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 10 http://www.boost.org/LICENSE_1_0.txt) 11=============================================================================*/ 12#if !defined(BOOST_SPIRIT_DIRECTIVES_IPP) 13#define BOOST_SPIRIT_DIRECTIVES_IPP 14 15/////////////////////////////////////////////////////////////////////////////// 16#include <boost/spirit/home/classic/core/scanner/skipper.hpp> 17 18namespace boost { namespace spirit { 19 20BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 21 22 template <typename BaseT> 23 struct no_skipper_iteration_policy; 24 25 template <typename BaseT> 26 struct inhibit_case_iteration_policy; 27 28 template <typename A, typename B> 29 struct alternative; 30 31 template <typename A, typename B> 32 struct longest_alternative; 33 34 template <typename A, typename B> 35 struct shortest_alternative; 36 37 namespace impl 38 { 39 template <typename RT, typename ST, typename ScannerT, typename BaseT> 40 inline RT 41 contiguous_parser_parse( 42 ST const& s, 43 ScannerT const& scan, 44 skipper_iteration_policy<BaseT> const&) 45 { 46 typedef scanner_policies< 47 no_skipper_iteration_policy< 48 BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, 49 BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, 50 BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t 51 > policies_t; 52 53 scan.skip(scan); 54 RT hit = s.parse(scan.change_policies(policies_t(scan))); 55 // We will not do a post skip!!! 56 return hit; 57 } 58 59 template <typename RT, typename ST, typename ScannerT, typename BaseT> 60 inline RT 61 contiguous_parser_parse( 62 ST const& s, 63 ScannerT const& scan, 64 no_skipper_iteration_policy<BaseT> const&) 65 { 66 return s.parse(scan); 67 } 68 69 template <typename RT, typename ST, typename ScannerT> 70 inline RT 71 contiguous_parser_parse( 72 ST const& s, 73 ScannerT const& scan, 74 iteration_policy const&) 75 { 76 return s.parse(scan); 77 } 78 79 template < 80 typename RT, 81 typename ParserT, 82 typename ScannerT, 83 typename BaseT> 84 inline RT 85 implicit_lexeme_parse( 86 ParserT const& p, 87 ScannerT const& scan, 88 skipper_iteration_policy<BaseT> const&) 89 { 90 typedef scanner_policies< 91 no_skipper_iteration_policy< 92 BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, 93 BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, 94 BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t 95 > policies_t; 96 97 scan.skip(scan); 98 RT hit = p.parse_main(scan.change_policies(policies_t(scan))); 99 // We will not do a post skip!!! 100 return hit; 101 } 102 103 template < 104 typename RT, 105 typename ParserT, 106 typename ScannerT, 107 typename BaseT> 108 inline RT 109 implicit_lexeme_parse( 110 ParserT const& p, 111 ScannerT const& scan, 112 no_skipper_iteration_policy<BaseT> const&) 113 { 114 return p.parse_main(scan); 115 } 116 117 template <typename RT, typename ParserT, typename ScannerT> 118 inline RT 119 implicit_lexeme_parse( 120 ParserT const& p, 121 ScannerT const& scan, 122 iteration_policy const&) 123 { 124 return p.parse_main(scan); 125 } 126 127 template <typename RT, typename ST, typename ScannerT> 128 inline RT 129 inhibit_case_parser_parse( 130 ST const& s, 131 ScannerT const& scan, 132 iteration_policy const&) 133 { 134 typedef scanner_policies< 135 inhibit_case_iteration_policy< 136 BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, 137 BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, 138 BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t 139 > policies_t; 140 141 return s.parse(scan.change_policies(policies_t(scan))); 142 } 143 144 template <typename RT, typename ST, typename ScannerT, typename BaseT> 145 inline RT 146 inhibit_case_parser_parse( 147 ST const& s, 148 ScannerT const& scan, 149 inhibit_case_iteration_policy<BaseT> const&) 150 { 151 return s.parse(scan); 152 } 153 154 template <typename T> 155 struct to_longest_alternative 156 { 157 typedef T result_t; 158 static result_t const& 159 convert(T const& a) // Special (end) case 160 { return a; } 161 }; 162 163 template <typename A, typename B> 164 struct to_longest_alternative<alternative<A, B> > 165 { 166 typedef typename to_longest_alternative<A>::result_t a_t; 167 typedef typename to_longest_alternative<B>::result_t b_t; 168 typedef longest_alternative<a_t, b_t> result_t; 169 170 static result_t 171 convert(alternative<A, B> const& alt) // Recursive case 172 { 173 return result_t( 174 to_longest_alternative<A>::convert(alt.left()), 175 to_longest_alternative<B>::convert(alt.right())); 176 } 177 }; 178 179 template <typename T> 180 struct to_shortest_alternative 181 { 182 typedef T result_t; 183 static result_t const& 184 convert(T const& a) // Special (end) case 185 { return a; } 186 }; 187 188 template <typename A, typename B> 189 struct to_shortest_alternative<alternative<A, B> > 190 { 191 typedef typename to_shortest_alternative<A>::result_t a_t; 192 typedef typename to_shortest_alternative<B>::result_t b_t; 193 typedef shortest_alternative<a_t, b_t> result_t; 194 195 static result_t 196 convert(alternative<A, B> const& alt) // Recursive case 197 { 198 return result_t( 199 to_shortest_alternative<A>::convert(alt.left()), 200 to_shortest_alternative<B>::convert(alt.right())); 201 } 202 }; 203 } 204 205BOOST_SPIRIT_CLASSIC_NAMESPACE_END 206 207}} // namespace boost::spirit 208 209#endif 210 211