Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:01:54

0001 /*=============================================================================
0002     Copyright (c) 1998-2003 Joel de Guzman
0003     Copyright (c) 2002-2003 Martin Wille
0004     http://spirit.sourceforge.net/
0005 
0006   Distributed under the Boost Software License, Version 1.0. (See accompanying
0007   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 =============================================================================*/
0009 #ifndef BOOST_SPIRIT_EPSILON_HPP
0010 #define BOOST_SPIRIT_EPSILON_HPP
0011 
0012 ////////////////////////////////////////////////////////////////////////////////
0013 #include <boost/spirit/home/classic/namespace.hpp>
0014 #include <boost/spirit/home/classic/core/parser.hpp>
0015 #include <boost/spirit/home/classic/meta/parser_traits.hpp>
0016 #include <boost/spirit/home/classic/core/composite/composite.hpp>
0017 #include <boost/spirit/home/classic/core/composite/no_actions.hpp>
0018 
0019 #if defined(BOOST_MSVC)
0020 # pragma warning(push)
0021 # pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
0022 #endif
0023 
0024 ////////////////////////////////////////////////////////////////////////////////
0025 namespace boost { namespace spirit {
0026 
0027 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0028 
0029 ///////////////////////////////////////////////////////////////////////////////
0030 //
0031 //  condition_parser class
0032 //
0033 //      handles expressions of the form
0034 //
0035 //          epsilon_p(cond)
0036 //
0037 //      where cond is a function or a functor that returns a value suitable
0038 //      to be used in boolean context. The expression returns a parser that
0039 //      returns an empty match when the condition evaluates to true.
0040 //
0041 ///////////////////////////////////////////////////////////////////////////////
0042     template <typename CondT, bool positive_ = true>
0043     struct condition_parser : parser<condition_parser<CondT, positive_> >
0044     {
0045         typedef condition_parser<CondT, positive_> self_t;
0046 
0047         // not explicit! (needed for implementation of if_p et al.)
0048         condition_parser(CondT const& cond_) : cond(cond_) {}
0049 
0050         template <typename ScannerT>
0051         typename parser_result<self_t, ScannerT>::type
0052         parse(ScannerT const& scan) const
0053         {
0054             if (positive_ == bool(cond())) // allow cond to return int
0055                 return scan.empty_match();
0056             else
0057                 return scan.no_match();
0058         }
0059 
0060         condition_parser<CondT, !positive_>
0061         negate() const
0062         { return condition_parser<CondT, !positive_>(cond); }
0063 
0064     private:
0065 
0066         CondT cond;
0067     };
0068 
0069 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \
0070     BOOST_WORKAROUND(BOOST_MSVC, == 1400) || \
0071     BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
0072 // VC 7.1, VC8 and Sun CC <= 5.8 do not support general
0073 // expressions of non-type template parameters in instantiations
0074     template <typename CondT>
0075     inline condition_parser<CondT, false>
0076     operator~(condition_parser<CondT, true> const& p)
0077     { return p.negate(); }
0078 
0079     template <typename CondT>
0080     inline condition_parser<CondT, true>
0081     operator~(condition_parser<CondT, false> const& p)
0082     { return p.negate(); }
0083 #else // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400
0084     template <typename CondT, bool positive>
0085     inline condition_parser<CondT, !positive>
0086     operator~(condition_parser<CondT, positive> const& p)
0087     { return p.negate(); }
0088 #endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400
0089 
0090 ///////////////////////////////////////////////////////////////////////////////
0091 //
0092 //  empty_match_parser class
0093 //
0094 //      handles expressions of the form
0095 //          epsilon_p(subject)
0096 //      where subject is a parser. The expression returns a composite
0097 //      parser that returns an empty match if the subject parser matches.
0098 //
0099 ///////////////////////////////////////////////////////////////////////////////
0100     struct empty_match_parser_gen;
0101     struct negated_empty_match_parser_gen;
0102 
0103     template <typename SubjectT>
0104     struct negated_empty_match_parser; // Forward declaration
0105 
0106     template<typename SubjectT>
0107     struct empty_match_parser
0108     : unary<SubjectT, parser<empty_match_parser<SubjectT> > >
0109     {
0110         typedef empty_match_parser<SubjectT>        self_t;
0111         typedef unary<SubjectT, parser<self_t> >    base_t;
0112         typedef unary_parser_category               parser_category_t;
0113         typedef empty_match_parser_gen              parser_genererator_t;
0114         typedef self_t embed_t;
0115 
0116         explicit empty_match_parser(SubjectT const& p) : base_t(p) {}
0117 
0118         template <typename ScannerT>
0119         struct result
0120         { typedef typename match_result<ScannerT, nil_t>::type type; };
0121 
0122         template <typename ScannerT>
0123         typename parser_result<self_t, ScannerT>::type
0124         parse(ScannerT const& scan) const
0125         {
0126             typename ScannerT::iterator_t save(scan.first);
0127             
0128             typedef typename no_actions_scanner<ScannerT>::policies_t
0129                 policies_t;
0130 
0131             bool matches = this->subject().parse(
0132                 scan.change_policies(policies_t(scan)));
0133             if (matches)
0134             {
0135                 scan.first = save; // reset the position
0136                 return scan.empty_match();
0137             }
0138             else
0139             {
0140                 return scan.no_match();
0141             }
0142         }
0143 
0144         negated_empty_match_parser<SubjectT>
0145         negate() const
0146         { return negated_empty_match_parser<SubjectT>(this->subject()); }
0147     };
0148 
0149     template<typename SubjectT>
0150     struct negated_empty_match_parser
0151     : public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > >
0152     {
0153         typedef negated_empty_match_parser<SubjectT>    self_t;
0154         typedef unary<SubjectT, parser<self_t> >        base_t;
0155         typedef unary_parser_category                   parser_category_t;
0156         typedef negated_empty_match_parser_gen          parser_genererator_t;
0157 
0158         explicit negated_empty_match_parser(SubjectT const& p) : base_t(p) {}
0159 
0160         template <typename ScannerT>
0161         struct result
0162         { typedef typename match_result<ScannerT, nil_t>::type type; };
0163 
0164         template <typename ScannerT>
0165         typename parser_result<self_t, ScannerT>::type
0166         parse(ScannerT const& scan) const
0167         {
0168             typename ScannerT::iterator_t save(scan.first);
0169 
0170             typedef typename no_actions_scanner<ScannerT>::policies_t
0171                 policies_t;
0172 
0173             bool matches = this->subject().parse(
0174                 scan.change_policies(policies_t(scan)));
0175             if (!matches)
0176             {
0177                 scan.first = save; // reset the position
0178                 return scan.empty_match();
0179             }
0180             else
0181             {
0182                 return scan.no_match();
0183             }
0184         }
0185 
0186         empty_match_parser<SubjectT>
0187         negate() const
0188         { return empty_match_parser<SubjectT>(this->subject()); }
0189     };
0190 
0191     struct empty_match_parser_gen
0192     {
0193         template <typename SubjectT>
0194         struct result
0195         { typedef empty_match_parser<SubjectT> type; };
0196 
0197         template <typename SubjectT>
0198         static empty_match_parser<SubjectT>
0199         generate(parser<SubjectT> const& subject)
0200         { return empty_match_parser<SubjectT>(subject.derived()); }
0201     };
0202 
0203     struct negated_empty_match_parser_gen
0204     {
0205         template <typename SubjectT>
0206         struct result
0207         { typedef negated_empty_match_parser<SubjectT> type; };
0208 
0209         template <typename SubjectT>
0210         static negated_empty_match_parser<SubjectT>
0211         generate(parser<SubjectT> const& subject)
0212         { return negated_empty_match_parser<SubjectT>(subject.derived()); }
0213     };
0214 
0215     //////////////////////////////
0216     template <typename SubjectT>
0217     inline negated_empty_match_parser<SubjectT>
0218     operator~(empty_match_parser<SubjectT> const& p)
0219     { return p.negate(); }
0220 
0221     template <typename SubjectT>
0222     inline empty_match_parser<SubjectT>
0223     operator~(negated_empty_match_parser<SubjectT> const& p)
0224     { return p.negate(); }
0225 
0226 ///////////////////////////////////////////////////////////////////////////////
0227 //
0228 //  epsilon_ parser and parser generator class
0229 //
0230 //      Operates as primitive parser that always matches an empty sequence.
0231 //
0232 //      Also operates as a parser generator. According to the type of the
0233 //      argument an instance of empty_match_parser<> (when the argument is
0234 //      a parser) or condition_parser<> (when the argument is not a parser)
0235 //      is returned by operator().
0236 //
0237 ///////////////////////////////////////////////////////////////////////////////
0238     namespace impl
0239     {
0240         template <typename SubjectT>
0241         struct epsilon_selector
0242         {
0243             typedef typename as_parser<SubjectT>::type subject_t;
0244             typedef typename
0245                 mpl::if_<
0246                     is_parser<subject_t>
0247                     ,empty_match_parser<subject_t>
0248                     ,condition_parser<subject_t>
0249                 >::type type;
0250         };
0251     }
0252 
0253     struct epsilon_parser : public parser<epsilon_parser>
0254     {
0255         typedef epsilon_parser self_t;
0256 
0257         epsilon_parser() {}
0258 
0259         template <typename ScannerT>
0260         typename parser_result<self_t, ScannerT>::type
0261         parse(ScannerT const& scan) const
0262         { return scan.empty_match(); }
0263 
0264         template <typename SubjectT>
0265         typename impl::epsilon_selector<SubjectT>::type
0266         operator()(SubjectT const& subject) const
0267         {
0268             typedef typename impl::epsilon_selector<SubjectT>::type result_t;
0269             return result_t(subject);
0270         }
0271     };
0272 
0273     epsilon_parser const epsilon_p = epsilon_parser();
0274     epsilon_parser const eps_p = epsilon_parser();
0275 
0276 ///////////////////////////////////////////////////////////////////////////////
0277 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0278 
0279 }} // namespace BOOST_SPIRIT_CLASSIC_NS
0280 
0281 #ifdef BOOST_MSVC
0282 # pragma warning (pop)
0283 #endif
0284 
0285 #endif