Line data Source code
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 : 34 0 : skipper_iteration_policy() 35 : : BaseT() {} 36 : 37 : template <typename PolicyT> 38 0 : skipper_iteration_policy(PolicyT const& other) 39 : : BaseT(other) {} 40 : 41 : template <typename ScannerT> 42 : void 43 0 : advance(ScannerT const& scan) const 44 : { 45 0 : BaseT::advance(scan); 46 0 : scan.skip(scan); 47 : } 48 : 49 : template <typename ScannerT> 50 : bool 51 0 : at_end(ScannerT const& scan) const 52 : { 53 0 : scan.skip(scan); 54 0 : return BaseT::at_end(scan); 55 : } 56 : 57 : template <typename ScannerT> 58 : void 59 : 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 : 76 : no_skipper_iteration_policy() 77 : : BaseT() {} 78 : 79 : template <typename PolicyT> 80 0 : no_skipper_iteration_policy(PolicyT const& other) 81 0 : : BaseT(other) {} 82 : 83 : template <typename ScannerT> 84 : void 85 0 : 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 : 124 0 : skip_parser_iteration_policy( 125 : ParserT const& skip_parser, 126 : base_t const& base = base_t()) 127 0 : : base_t(base), subject(skip_parser) {} 128 : 129 : template <typename PolicyT> 130 0 : skip_parser_iteration_policy(PolicyT const& other) 131 0 : : base_t(other), subject(other.skipper()) {} 132 : 133 : template <typename ScannerT> 134 : void 135 0 : skip(ScannerT const& scan) const 136 : { 137 0 : impl::skipper_skip(subject, scan, scan); 138 : } 139 : 140 : ParserT const& 141 0 : 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 :