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 : #ifndef BOOST_SPIRIT_ACTIONS_HPP 9 : #define BOOST_SPIRIT_ACTIONS_HPP 10 : 11 : #include <boost/spirit/home/classic/namespace.hpp> 12 : #include <boost/spirit/home/classic/core/parser.hpp> 13 : #include <boost/spirit/home/classic/core/composite/composite.hpp> 14 : #include <boost/core/ignore_unused.hpp> 15 : 16 : namespace boost { namespace spirit { 17 : 18 : BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 19 : 20 : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 21 : #pragma warning(push) 22 : #pragma warning(disable:4512) //assignment operator could not be generated 23 : #endif 24 : 25 : /////////////////////////////////////////////////////////////////////////// 26 : // 27 : // action class 28 : // 29 : // The action class binds a parser with a user defined semantic 30 : // action. Instances of action are never created manually. Instead, 31 : // action objects are typically created indirectly through 32 : // expression templates of the form: 33 : // 34 : // p[f] 35 : // 36 : // where p is a parser and f is a function or functor. The semantic 37 : // action may be a function or a functor. When the parser is 38 : // successful, the actor calls the scanner's action_policy policy 39 : // (see scanner.hpp): 40 : // 41 : // scan.do_action(actor, attribute, first, last); 42 : // 43 : // passing in these information: 44 : // 45 : // actor: The action's function or functor 46 : // attribute: The match (returned by the parser) object's 47 : // attribute (see match.hpp) 48 : // first: Iterator pointing to the start of the matching 49 : // portion of the input 50 : // last: Iterator pointing to one past the end of the 51 : // matching portion of the input 52 : // 53 : // It is the responsibility of the scanner's action_policy policy to 54 : // dispatch the function or functor as it sees fit. The expected 55 : // function or functor signature depends on the parser being 56 : // wrapped. In general, if the attribute type of the parser being 57 : // wrapped is a nil_t, the function or functor expect the signature: 58 : // 59 : // void func(Iterator first, Iterator last); // functions 60 : // 61 : // struct ftor // functors 62 : // { 63 : // void func(Iterator first, Iterator last) const; 64 : // }; 65 : // 66 : // where Iterator is the type of the iterator that is being used and 67 : // first and last are the iterators pointing to the matching portion 68 : // of the input. 69 : // 70 : // If the attribute type of the parser being wrapped is not a nil_t, 71 : // the function or functor usually expect the signature: 72 : // 73 : // void func(T val); // functions 74 : // 75 : // struct ftor // functors 76 : // { 77 : // void func(T val) const; 78 : // }; 79 : // 80 : // where T is the attribute type and val is the attribute value 81 : // returned by the parser being wrapped. 82 : // 83 : /////////////////////////////////////////////////////////////////////////// 84 : template <typename ParserT, typename ActionT> 85 : class action : public unary<ParserT, parser<action<ParserT, ActionT> > > 86 : { 87 : public: 88 : 89 : typedef action<ParserT, ActionT> self_t; 90 : typedef action_parser_category parser_category_t; 91 : typedef unary<ParserT, parser<self_t> > base_t; 92 : typedef ActionT predicate_t; 93 : 94 : template <typename ScannerT> 95 : struct result 96 : { 97 : typedef typename parser_result<ParserT, ScannerT>::type type; 98 : }; 99 : 100 0 : action(ParserT const& p, ActionT const& a) 101 : : base_t(p) 102 0 : , actor(a) {} 103 : 104 : template <typename ScannerT> 105 : typename parser_result<self_t, ScannerT>::type 106 0 : parse(ScannerT const& scan) const 107 : { 108 : typedef typename ScannerT::iterator_t iterator_t; 109 : typedef typename parser_result<self_t, ScannerT>::type result_t; 110 : 111 0 : ignore_unused(scan.at_end()); // allow skipper to take effect 112 0 : iterator_t save = scan.first; 113 0 : result_t hit = this->subject().parse(scan); 114 0 : if (hit) 115 : { 116 0 : typename result_t::return_t val = hit.value(); 117 0 : scan.do_action(actor, val, save, scan.first); 118 : } 119 0 : return hit; 120 : } 121 : 122 : ActionT const& predicate() const { return actor; } 123 : 124 : private: 125 : 126 : ActionT actor; 127 : }; 128 : 129 : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 130 : #pragma warning(pop) 131 : #endif 132 : 133 : BOOST_SPIRIT_CLASSIC_NAMESPACE_END 134 : 135 : }} // namespace BOOST_SPIRIT_CLASSIC_NS 136 : 137 : #endif