1 /*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 http://spirit.sourceforge.net/ 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 =============================================================================*/ 8 #if !defined(BOOST_SPIRIT_SKIPPER_HPP) 9 #define BOOST_SPIRIT_SKIPPER_HPP 10 11 /////////////////////////////////////////////////////////////////////////////// 12 #include <cctype> 13 14 #include <boost/spirit/home/classic/namespace.hpp> 15 #include <boost/spirit/home/classic/core/scanner/scanner.hpp> 16 #include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp> 17 18 #include <boost/spirit/home/classic/core/scanner/skipper_fwd.hpp> 19 20 namespace boost { namespace spirit { 21 22 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 23 24 /////////////////////////////////////////////////////////////////////////// 25 // 26 // skipper_iteration_policy class 27 // 28 /////////////////////////////////////////////////////////////////////////// 29 template <typename BaseT> 30 struct skipper_iteration_policy : public BaseT 31 { 32 typedef BaseT base_t; 33 skipper_iteration_policyboost::spirit::skipper_iteration_policy34 skipper_iteration_policy() 35 : BaseT() {} 36 37 template <typename PolicyT> skipper_iteration_policyboost::spirit::skipper_iteration_policy38 skipper_iteration_policy(PolicyT const& other) 39 : BaseT(other) {} 40 41 template <typename ScannerT> 42 void advanceboost::spirit::skipper_iteration_policy43 advance(ScannerT const& scan) const 44 { 45 BaseT::advance(scan); 46 scan.skip(scan); 47 } 48 49 template <typename ScannerT> 50 bool at_endboost::spirit::skipper_iteration_policy51 at_end(ScannerT const& scan) const 52 { 53 scan.skip(scan); 54 return BaseT::at_end(scan); 55 } 56 57 template <typename ScannerT> 58 void skipboost::spirit::skipper_iteration_policy59 skip(ScannerT const& scan) const 60 { 61 while (!BaseT::at_end(scan) && impl::isspace_(BaseT::get(scan))) 62 BaseT::advance(scan); 63 } 64 }; 65 66 /////////////////////////////////////////////////////////////////////////// 67 // 68 // no_skipper_iteration_policy class 69 // 70 /////////////////////////////////////////////////////////////////////////// 71 template <typename BaseT> 72 struct no_skipper_iteration_policy : public BaseT 73 { 74 typedef BaseT base_t; 75 no_skipper_iteration_policyboost::spirit::no_skipper_iteration_policy76 no_skipper_iteration_policy() 77 : BaseT() {} 78 79 template <typename PolicyT> no_skipper_iteration_policyboost::spirit::no_skipper_iteration_policy80 no_skipper_iteration_policy(PolicyT const& other) 81 : BaseT(other) {} 82 83 template <typename ScannerT> 84 void skipboost::spirit::no_skipper_iteration_policy85 skip(ScannerT const& /*scan*/) const {} 86 }; 87 88 /////////////////////////////////////////////////////////////////////////// 89 // 90 // skip_parser_iteration_policy class 91 // 92 /////////////////////////////////////////////////////////////////////////// 93 namespace impl 94 { 95 template <typename ST, typename ScannerT, typename BaseT> 96 void 97 skipper_skip( 98 ST const& s, 99 ScannerT const& scan, 100 skipper_iteration_policy<BaseT> const&); 101 102 template <typename ST, typename ScannerT, typename BaseT> 103 void 104 skipper_skip( 105 ST const& s, 106 ScannerT const& scan, 107 no_skipper_iteration_policy<BaseT> const&); 108 109 template <typename ST, typename ScannerT> 110 void 111 skipper_skip( 112 ST const& s, 113 ScannerT const& scan, 114 iteration_policy const&); 115 } 116 117 template <typename ParserT, typename BaseT> 118 class skip_parser_iteration_policy : public skipper_iteration_policy<BaseT> 119 { 120 public: 121 122 typedef skipper_iteration_policy<BaseT> base_t; 123 skip_parser_iteration_policy(ParserT const & skip_parser,base_t const & base=base_t ())124 skip_parser_iteration_policy( 125 ParserT const& skip_parser, 126 base_t const& base = base_t()) 127 : base_t(base), subject(skip_parser) {} 128 129 template <typename PolicyT> skip_parser_iteration_policy(PolicyT const & other)130 skip_parser_iteration_policy(PolicyT const& other) 131 : base_t(other), subject(other.skipper()) {} 132 133 template <typename ScannerT> 134 void skip(ScannerT const & scan) const135 skip(ScannerT const& scan) const 136 { 137 impl::skipper_skip(subject, scan, scan); 138 } 139 140 ParserT const& skipper() const141 skipper() const 142 { 143 return subject; 144 } 145 146 private: 147 148 ParserT const& subject; 149 }; 150 151 /////////////////////////////////////////////////////////////////////////////// 152 // 153 // Free parse functions using the skippers 154 // 155 /////////////////////////////////////////////////////////////////////////////// 156 template <typename IteratorT, typename ParserT, typename SkipT> 157 parse_info<IteratorT> 158 parse( 159 IteratorT const& first, 160 IteratorT const& last, 161 parser<ParserT> const& p, 162 parser<SkipT> const& skip); 163 164 /////////////////////////////////////////////////////////////////////////////// 165 // 166 // Parse function for null terminated strings using the skippers 167 // 168 /////////////////////////////////////////////////////////////////////////////// 169 template <typename CharT, typename ParserT, typename SkipT> 170 parse_info<CharT const*> 171 parse( 172 CharT const* str, 173 parser<ParserT> const& p, 174 parser<SkipT> const& skip); 175 176 /////////////////////////////////////////////////////////////////////////////// 177 // 178 // phrase_scanner_t and wide_phrase_scanner_t 179 // 180 // The most common scanners. Use these typedefs when you need 181 // a scanner that skips white spaces. 182 // 183 /////////////////////////////////////////////////////////////////////////////// 184 typedef skipper_iteration_policy<> iter_policy_t; 185 typedef scanner_policies<iter_policy_t> scanner_policies_t; 186 typedef scanner<char const*, scanner_policies_t> phrase_scanner_t; 187 typedef scanner<wchar_t const*, scanner_policies_t> wide_phrase_scanner_t; 188 189 /////////////////////////////////////////////////////////////////////////////// 190 191 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 192 193 }} // namespace BOOST_SPIRIT_CLASSIC_NS 194 195 #include <boost/spirit/home/classic/core/scanner/impl/skipper.ipp> 196 #endif 197 198