1 /*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 Copyright (c) 2002-2003 Martin Wille 4 http://spirit.sourceforge.net/ 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 #ifndef BOOST_SPIRIT_EPSILON_HPP 10 #define BOOST_SPIRIT_EPSILON_HPP 11 12 //////////////////////////////////////////////////////////////////////////////// 13 #include <boost/spirit/home/classic/namespace.hpp> 14 #include <boost/spirit/home/classic/core/parser.hpp> 15 #include <boost/spirit/home/classic/meta/parser_traits.hpp> 16 #include <boost/spirit/home/classic/core/composite/composite.hpp> 17 #include <boost/spirit/home/classic/core/composite/no_actions.hpp> 18 19 //////////////////////////////////////////////////////////////////////////////// 20 namespace boost { namespace spirit { 21 22 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 23 24 /////////////////////////////////////////////////////////////////////////////// 25 // 26 // condition_parser class 27 // 28 // handles expresions of the form 29 // 30 // epsilon_p(cond) 31 // 32 // where cond is a function or a functor that returns a value suitable 33 // to be used in boolean context. The expression returns a parser that 34 // returns an empty match when the condition evaluates to true. 35 // 36 /////////////////////////////////////////////////////////////////////////////// 37 template <typename CondT, bool positive_ = true> 38 struct condition_parser : parser<condition_parser<CondT, positive_> > 39 { 40 typedef condition_parser<CondT, positive_> self_t; 41 42 // not explicit! (needed for implementation of if_p et al.) condition_parserboost::spirit::condition_parser43 condition_parser(CondT const& cond_) : cond(cond_) {} 44 45 template <typename ScannerT> 46 typename parser_result<self_t, ScannerT>::type parseboost::spirit::condition_parser47 parse(ScannerT const& scan) const 48 { 49 if (positive_ == bool(cond())) // allow cond to return int 50 return scan.empty_match(); 51 else 52 return scan.no_match(); 53 } 54 55 condition_parser<CondT, !positive_> negateboost::spirit::condition_parser56 negate() const 57 { return condition_parser<CondT, !positive_>(cond); } 58 59 private: 60 61 CondT cond; 62 }; 63 64 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \ 65 BOOST_WORKAROUND(BOOST_MSVC, == 1400) || \ 66 BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) 67 // VC 7.1, VC8 and Sun CC <= 5.8 do not support general 68 // expressions of non-type template parameters in instantiations 69 template <typename CondT> 70 inline condition_parser<CondT, false> operator ~(condition_parser<CondT,true> const & p)71 operator~(condition_parser<CondT, true> const& p) 72 { return p.negate(); } 73 74 template <typename CondT> 75 inline condition_parser<CondT, true> operator ~(condition_parser<CondT,false> const & p)76 operator~(condition_parser<CondT, false> const& p) 77 { return p.negate(); } 78 #else // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400 79 template <typename CondT, bool positive> 80 inline condition_parser<CondT, !positive> operator ~(condition_parser<CondT,positive> const & p)81 operator~(condition_parser<CondT, positive> const& p) 82 { return p.negate(); } 83 #endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400 84 85 /////////////////////////////////////////////////////////////////////////////// 86 // 87 // empty_match_parser class 88 // 89 // handles expressions of the form 90 // epsilon_p(subject) 91 // where subject is a parser. The expresion returns a composite 92 // parser that returns an empty match if the subject parser matches. 93 // 94 /////////////////////////////////////////////////////////////////////////////// 95 struct empty_match_parser_gen; 96 struct negated_empty_match_parser_gen; 97 98 template <typename SubjectT> 99 struct negated_empty_match_parser; // Forward declaration 100 101 template<typename SubjectT> 102 struct empty_match_parser 103 : unary<SubjectT, parser<empty_match_parser<SubjectT> > > 104 { 105 typedef empty_match_parser<SubjectT> self_t; 106 typedef unary<SubjectT, parser<self_t> > base_t; 107 typedef unary_parser_category parser_category_t; 108 typedef empty_match_parser_gen parser_genererator_t; 109 typedef self_t embed_t; 110 empty_match_parserboost::spirit::empty_match_parser111 explicit empty_match_parser(SubjectT const& p) : base_t(p) {} 112 113 template <typename ScannerT> 114 struct result 115 { typedef typename match_result<ScannerT, nil_t>::type type; }; 116 117 template <typename ScannerT> 118 typename parser_result<self_t, ScannerT>::type parseboost::spirit::empty_match_parser119 parse(ScannerT const& scan) const 120 { 121 typename ScannerT::iterator_t save(scan.first); 122 123 typedef typename no_actions_scanner<ScannerT>::policies_t 124 policies_t; 125 126 bool matches = this->subject().parse( 127 scan.change_policies(policies_t(scan))); 128 if (matches) 129 { 130 scan.first = save; // reset the position 131 return scan.empty_match(); 132 } 133 else 134 { 135 return scan.no_match(); 136 } 137 } 138 139 negated_empty_match_parser<SubjectT> negateboost::spirit::empty_match_parser140 negate() const 141 { return negated_empty_match_parser<SubjectT>(this->subject()); } 142 }; 143 144 template<typename SubjectT> 145 struct negated_empty_match_parser 146 : public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > > 147 { 148 typedef negated_empty_match_parser<SubjectT> self_t; 149 typedef unary<SubjectT, parser<self_t> > base_t; 150 typedef unary_parser_category parser_category_t; 151 typedef negated_empty_match_parser_gen parser_genererator_t; 152 negated_empty_match_parserboost::spirit::negated_empty_match_parser153 explicit negated_empty_match_parser(SubjectT const& p) : base_t(p) {} 154 155 template <typename ScannerT> 156 struct result 157 { typedef typename match_result<ScannerT, nil_t>::type type; }; 158 159 template <typename ScannerT> 160 typename parser_result<self_t, ScannerT>::type parseboost::spirit::negated_empty_match_parser161 parse(ScannerT const& scan) const 162 { 163 typename ScannerT::iterator_t save(scan.first); 164 165 typedef typename no_actions_scanner<ScannerT>::policies_t 166 policies_t; 167 168 bool matches = this->subject().parse( 169 scan.change_policies(policies_t(scan))); 170 if (!matches) 171 { 172 scan.first = save; // reset the position 173 return scan.empty_match(); 174 } 175 else 176 { 177 return scan.no_match(); 178 } 179 } 180 181 empty_match_parser<SubjectT> negateboost::spirit::negated_empty_match_parser182 negate() const 183 { return empty_match_parser<SubjectT>(this->subject()); } 184 }; 185 186 struct empty_match_parser_gen 187 { 188 template <typename SubjectT> 189 struct result 190 { typedef empty_match_parser<SubjectT> type; }; 191 192 template <typename SubjectT> 193 static empty_match_parser<SubjectT> generateboost::spirit::empty_match_parser_gen194 generate(parser<SubjectT> const& subject) 195 { return empty_match_parser<SubjectT>(subject.derived()); } 196 }; 197 198 struct negated_empty_match_parser_gen 199 { 200 template <typename SubjectT> 201 struct result 202 { typedef negated_empty_match_parser<SubjectT> type; }; 203 204 template <typename SubjectT> 205 static negated_empty_match_parser<SubjectT> generateboost::spirit::negated_empty_match_parser_gen206 generate(parser<SubjectT> const& subject) 207 { return negated_empty_match_parser<SubjectT>(subject.derived()); } 208 }; 209 210 ////////////////////////////// 211 template <typename SubjectT> 212 inline negated_empty_match_parser<SubjectT> operator ~(empty_match_parser<SubjectT> const & p)213 operator~(empty_match_parser<SubjectT> const& p) 214 { return p.negate(); } 215 216 template <typename SubjectT> 217 inline empty_match_parser<SubjectT> operator ~(negated_empty_match_parser<SubjectT> const & p)218 operator~(negated_empty_match_parser<SubjectT> const& p) 219 { return p.negate(); } 220 221 /////////////////////////////////////////////////////////////////////////////// 222 // 223 // epsilon_ parser and parser generator class 224 // 225 // Operates as primitive parser that always matches an empty sequence. 226 // 227 // Also operates as a parser generator. According to the type of the 228 // argument an instance of empty_match_parser<> (when the argument is 229 // a parser) or condition_parser<> (when the argument is not a parser) 230 // is returned by operator(). 231 // 232 /////////////////////////////////////////////////////////////////////////////// 233 namespace impl 234 { 235 template <typename SubjectT> 236 struct epsilon_selector 237 { 238 typedef typename as_parser<SubjectT>::type subject_t; 239 typedef typename 240 mpl::if_< 241 is_parser<subject_t> 242 ,empty_match_parser<subject_t> 243 ,condition_parser<subject_t> 244 >::type type; 245 }; 246 } 247 248 struct epsilon_parser : public parser<epsilon_parser> 249 { 250 typedef epsilon_parser self_t; 251 epsilon_parserboost::spirit::epsilon_parser252 epsilon_parser() {} 253 254 template <typename ScannerT> 255 typename parser_result<self_t, ScannerT>::type parseboost::spirit::epsilon_parser256 parse(ScannerT const& scan) const 257 { return scan.empty_match(); } 258 259 template <typename SubjectT> 260 typename impl::epsilon_selector<SubjectT>::type operator ()boost::spirit::epsilon_parser261 operator()(SubjectT const& subject) const 262 { 263 typedef typename impl::epsilon_selector<SubjectT>::type result_t; 264 return result_t(subject); 265 } 266 }; 267 268 epsilon_parser const epsilon_p = epsilon_parser(); 269 epsilon_parser const eps_p = epsilon_parser(); 270 271 /////////////////////////////////////////////////////////////////////////////// 272 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 273 274 }} // namespace BOOST_SPIRIT_CLASSIC_NS 275 276 #endif 277