1/*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 http://spirit.sourceforge.net/ 4 5 Use, modification and distribution is subject to the Boost Software 6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8============================================================================*/ 9#if !defined(BOOST_SPIRIT_SKIPPER_IPP) 10#define BOOST_SPIRIT_SKIPPER_IPP 11 12/////////////////////////////////////////////////////////////////////////////// 13namespace boost { namespace spirit { 14 15BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 16 17 struct space_parser; 18 template <typename BaseT> 19 struct no_skipper_iteration_policy; 20 21 namespace impl 22 { 23 template <typename ST, typename ScannerT, typename BaseT> 24 inline void 25 skipper_skip( 26 ST const& s, 27 ScannerT const& scan, 28 skipper_iteration_policy<BaseT> const&) 29 { 30 typedef scanner_policies< 31 no_skipper_iteration_policy< 32 BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, 33 BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, 34 BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t 35 > policies_t; 36 37 scanner<BOOST_DEDUCED_TYPENAME ScannerT::iterator_t, policies_t> 38 scan2(scan.first, scan.last, policies_t(scan)); 39 typedef typename ScannerT::iterator_t iterator_t; 40 41 for (;;) 42 { 43 iterator_t save = scan.first; 44 if (!s.parse(scan2)) 45 { 46 scan.first = save; 47 break; 48 } 49 } 50 } 51 52 template <typename ST, typename ScannerT, typename BaseT> 53 inline void 54 skipper_skip( 55 ST const& s, 56 ScannerT const& scan, 57 no_skipper_iteration_policy<BaseT> const&) 58 { 59 for (;;) 60 { 61 typedef typename ScannerT::iterator_t iterator_t; 62 iterator_t save = scan.first; 63 if (!s.parse(scan)) 64 { 65 scan.first = save; 66 break; 67 } 68 } 69 } 70 71 template <typename ST, typename ScannerT> 72 inline void 73 skipper_skip( 74 ST const& s, 75 ScannerT const& scan, 76 iteration_policy const&) 77 { 78 for (;;) 79 { 80 typedef typename ScannerT::iterator_t iterator_t; 81 iterator_t save = scan.first; 82 if (!s.parse(scan)) 83 { 84 scan.first = save; 85 break; 86 } 87 } 88 } 89 90 template <typename SkipT> 91 struct phrase_parser 92 { 93 template <typename IteratorT, typename ParserT> 94 static parse_info<IteratorT> 95 parse( 96 IteratorT const& first_, 97 IteratorT const& last, 98 ParserT const& p, 99 SkipT const& skip) 100 { 101 typedef skip_parser_iteration_policy<SkipT> it_policy_t; 102 typedef scanner_policies<it_policy_t> scan_policies_t; 103 typedef scanner<IteratorT, scan_policies_t> scanner_t; 104 105 it_policy_t iter_policy(skip); 106 scan_policies_t policies(iter_policy); 107 IteratorT first = first_; 108 scanner_t scan(first, last, policies); 109 match<nil_t> hit = p.parse(scan); 110 return parse_info<IteratorT>( 111 first, hit, hit && (first == last), 112 hit.length()); 113 } 114 }; 115 116 template <> 117 struct phrase_parser<space_parser> 118 { 119 template <typename IteratorT, typename ParserT> 120 static parse_info<IteratorT> 121 parse( 122 IteratorT const& first_, 123 IteratorT const& last, 124 ParserT const& p, 125 space_parser const&) 126 { 127 typedef skipper_iteration_policy<> it_policy_t; 128 typedef scanner_policies<it_policy_t> scan_policies_t; 129 typedef scanner<IteratorT, scan_policies_t> scanner_t; 130 131 IteratorT first = first_; 132 scanner_t scan(first, last); 133 match<nil_t> hit = p.parse(scan); 134 return parse_info<IteratorT>( 135 first, hit, hit && (first == last), 136 hit.length()); 137 } 138 }; 139 } 140 141 /////////////////////////////////////////////////////////////////////////// 142 // 143 // Free parse functions using the skippers 144 // 145 /////////////////////////////////////////////////////////////////////////// 146 template <typename IteratorT, typename ParserT, typename SkipT> 147 inline parse_info<IteratorT> 148 parse( 149 IteratorT const& first, 150 IteratorT const& last, 151 parser<ParserT> const& p, 152 parser<SkipT> const& skip) 153 { 154 return impl::phrase_parser<SkipT>:: 155 parse(first, last, p.derived(), skip.derived()); 156 } 157 158 /////////////////////////////////////////////////////////////////////////// 159 // 160 // Parse function for null terminated strings using the skippers 161 // 162 /////////////////////////////////////////////////////////////////////////// 163 template <typename CharT, typename ParserT, typename SkipT> 164 inline parse_info<CharT const*> 165 parse( 166 CharT const* str, 167 parser<ParserT> const& p, 168 parser<SkipT> const& skip) 169 { 170 CharT const* last = str; 171 while (*last) 172 last++; 173 return parse(str, last, p, skip); 174 } 175 176BOOST_SPIRIT_CLASSIC_NAMESPACE_END 177 178}} // namespace boost::spirit 179 180#endif 181 182