| /*============================================================================= |
| Copyright (c) 1998-2002 Joel de Guzman |
| http://spirit.sourceforge.net/ |
| |
| Distributed under the Boost Software License, Version 1.0. (See accompanying |
| file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| =============================================================================*/ |
| #if !defined(BOOST_SPIRIT_SCANNER_HPP) |
| #define BOOST_SPIRIT_SCANNER_HPP |
| |
| #include <iterator> |
| #include <boost/config.hpp> |
| #include <boost/spirit/home/classic/namespace.hpp> |
| #include <boost/spirit/home/classic/core/match.hpp> |
| #include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp> |
| #include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits |
| |
| #include <boost/spirit/home/classic/core/scanner/scanner_fwd.hpp> |
| |
| namespace boost { namespace spirit { |
| |
| BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // iteration_policy class |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| struct iteration_policy |
| { |
| template <typename ScannerT> |
| void |
| advance(ScannerT const& scan) const |
| { |
| ++scan.first; |
| } |
| |
| template <typename ScannerT> |
| bool at_end(ScannerT const& scan) const |
| { |
| return scan.first == scan.last; |
| } |
| |
| template <typename T> |
| T filter(T ch) const |
| { |
| return ch; |
| } |
| |
| template <typename ScannerT> |
| typename ScannerT::ref_t |
| get(ScannerT const& scan) const |
| { |
| return *scan.first; |
| } |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // match_policy class |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| struct match_policy |
| { |
| template <typename T> |
| struct result { typedef match<T> type; }; |
| |
| const match<nil_t> |
| no_match() const |
| { |
| return match<nil_t>(); |
| } |
| |
| const match<nil_t> |
| empty_match() const |
| { |
| return match<nil_t>(0, nil_t()); |
| } |
| |
| template <typename AttrT, typename IteratorT> |
| match<AttrT> |
| create_match( |
| std::size_t length, |
| AttrT const& val, |
| IteratorT const& /*first*/, |
| IteratorT const& /*last*/) const |
| { |
| return match<AttrT>(length, val); |
| } |
| |
| template <typename MatchT, typename IteratorT> |
| void group_match( |
| MatchT& /*m*/, |
| parser_id const& /*id*/, |
| IteratorT const& /*first*/, |
| IteratorT const& /*last*/) const {} |
| |
| template <typename Match1T, typename Match2T> |
| void concat_match(Match1T& l, Match2T const& r) const |
| { |
| l.concat(r); |
| } |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // match_result class |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename MatchPolicyT, typename T> |
| struct match_result |
| { |
| typedef typename MatchPolicyT::template result<T>::type type; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // action_policy class |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename AttrT> |
| struct attributed_action_policy |
| { |
| template <typename ActorT, typename IteratorT> |
| static void |
| call( |
| ActorT const& actor, |
| AttrT& val, |
| IteratorT const&, |
| IteratorT const&) |
| { |
| actor(val); |
| } |
| }; |
| |
| ////////////////////////////////// |
| template <> |
| struct attributed_action_policy<nil_t> |
| { |
| template <typename ActorT, typename IteratorT> |
| static void |
| call( |
| ActorT const& actor, |
| nil_t, |
| IteratorT const& first, |
| IteratorT const& last) |
| { |
| actor(first, last); |
| } |
| }; |
| |
| ////////////////////////////////// |
| struct action_policy |
| { |
| template <typename ActorT, typename AttrT, typename IteratorT> |
| void |
| do_action( |
| ActorT const& actor, |
| AttrT& val, |
| IteratorT const& first, |
| IteratorT const& last) const |
| { |
| attributed_action_policy<AttrT>::call(actor, val, first, last); |
| } |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // scanner_policies class |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| template < |
| typename IterationPolicyT, |
| typename MatchPolicyT, |
| typename ActionPolicyT> |
| struct scanner_policies : |
| public IterationPolicyT, |
| public MatchPolicyT, |
| public ActionPolicyT |
| { |
| typedef IterationPolicyT iteration_policy_t; |
| typedef MatchPolicyT match_policy_t; |
| typedef ActionPolicyT action_policy_t; |
| |
| scanner_policies( |
| IterationPolicyT const& i_policy = IterationPolicyT(), |
| MatchPolicyT const& m_policy = MatchPolicyT(), |
| ActionPolicyT const& a_policy = ActionPolicyT()) |
| : IterationPolicyT(i_policy) |
| , MatchPolicyT(m_policy) |
| , ActionPolicyT(a_policy) {} |
| |
| template <typename ScannerPoliciesT> |
| scanner_policies(ScannerPoliciesT const& policies) |
| : IterationPolicyT(policies) |
| , MatchPolicyT(policies) |
| , ActionPolicyT(policies) {} |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // scanner_policies_base class: the base class of all scanners |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| struct scanner_base {}; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // scanner class |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| template < |
| typename IteratorT, |
| typename PoliciesT> |
| class scanner : public PoliciesT, public scanner_base |
| { |
| public: |
| |
| typedef IteratorT iterator_t; |
| typedef PoliciesT policies_t; |
| |
| typedef typename boost::detail:: |
| iterator_traits<IteratorT>::value_type value_t; |
| typedef typename boost::detail:: |
| iterator_traits<IteratorT>::reference ref_t; |
| typedef typename boost:: |
| call_traits<IteratorT>::param_type iter_param_t; |
| |
| scanner( |
| IteratorT& first_, |
| iter_param_t last_, |
| PoliciesT const& policies = PoliciesT()) |
| : PoliciesT(policies), first(first_), last(last_) |
| { |
| at_end(); |
| } |
| |
| scanner(scanner const& other) |
| : PoliciesT(other), first(other.first), last(other.last) {} |
| |
| scanner(scanner const& other, IteratorT& first_) |
| : PoliciesT(other), first(first_), last(other.last) {} |
| |
| template <typename PoliciesT1> |
| scanner(scanner<IteratorT, PoliciesT1> const& other) |
| : PoliciesT(other), first(other.first), last(other.last) {} |
| |
| bool |
| at_end() const |
| { |
| typedef typename PoliciesT::iteration_policy_t iteration_policy_type; |
| return iteration_policy_type::at_end(*this); |
| } |
| |
| value_t |
| operator*() const |
| { |
| typedef typename PoliciesT::iteration_policy_t iteration_policy_type; |
| return iteration_policy_type::filter(iteration_policy_type::get(*this)); |
| } |
| |
| scanner const& |
| operator++() const |
| { |
| typedef typename PoliciesT::iteration_policy_t iteration_policy_type; |
| iteration_policy_type::advance(*this); |
| return *this; |
| } |
| |
| template <typename PoliciesT2> |
| struct rebind_policies |
| { |
| typedef scanner<IteratorT, PoliciesT2> type; |
| }; |
| |
| template <typename PoliciesT2> |
| scanner<IteratorT, PoliciesT2> |
| change_policies(PoliciesT2 const& policies) const |
| { |
| return scanner<IteratorT, PoliciesT2>(first, last, policies); |
| } |
| |
| template <typename IteratorT2> |
| struct rebind_iterator |
| { |
| typedef scanner<IteratorT2, PoliciesT> type; |
| }; |
| |
| template <typename IteratorT2> |
| scanner<IteratorT2, PoliciesT> |
| change_iterator(IteratorT2 const& first_, IteratorT2 const &last_) const |
| { |
| return scanner<IteratorT2, PoliciesT>(first_, last_, *this); |
| } |
| |
| IteratorT& first; |
| IteratorT const last; |
| |
| private: |
| |
| scanner& |
| operator=(scanner const& other); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // rebind_scanner_policies class |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename ScannerT, typename PoliciesT> |
| struct rebind_scanner_policies |
| { |
| typedef typename ScannerT::template |
| rebind_policies<PoliciesT>::type type; |
| }; |
| |
| ////////////////////////////////// |
| template <typename ScannerT, typename IteratorT> |
| struct rebind_scanner_iterator |
| { |
| typedef typename ScannerT::template |
| rebind_iterator<IteratorT>::type type; |
| }; |
| |
| BOOST_SPIRIT_CLASSIC_NAMESPACE_END |
| |
| }} |
| |
| #endif |