1 /*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 http://spirit.sourceforge.net/
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
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>
15 namespace boost { namespace spirit {
17 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
19 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
21 #pragma warning(disable:4512) //assignment operator could not be generated
24 ///////////////////////////////////////////////////////////////////////////
28 // The action class binds a parser with a user defined semantic
29 // action. Instances of action are never created manually. Instead,
30 // action objects are typically created indirectly through
31 // expression templates of the form:
35 // where p is a parser and f is a function or functor. The semantic
36 // action may be a function or a functor. When the parser is
37 // successful, the actor calls the scanner's action_policy policy
40 // scan.do_action(actor, attribute, first, last);
42 // passing in these information:
44 // actor: The action's function or functor
45 // attribute: The match (returned by the parser) object's
46 // attribute (see match.hpp)
47 // first: Iterator pointing to the start of the matching
48 // portion of the input
49 // last: Iterator pointing to one past the end of the
50 // matching portion of the input
52 // It is the responsibility of the scanner's action_policy policy to
53 // dispatch the function or functor as it sees fit. The expected
54 // function or functor signature depends on the parser being
55 // wrapped. In general, if the attribute type of the parser being
56 // wrapped is a nil_t, the function or functor expect the signature:
58 // void func(Iterator first, Iterator last); // functions
60 // struct ftor // functors
62 // void func(Iterator first, Iterator last) const;
65 // where Iterator is the type of the iterator that is being used and
66 // first and last are the iterators pointing to the matching portion
69 // If the attribute type of the parser being wrapped is not a nil_t,
70 // the function or functor usually expect the signature:
72 // void func(T val); // functions
74 // struct ftor // functors
76 // void func(T val) const;
79 // where T is the attribute type and val is the attribute value
80 // returned by the parser being wrapped.
82 ///////////////////////////////////////////////////////////////////////////
83 template <typename ParserT, typename ActionT>
84 class action : public unary<ParserT, parser<action<ParserT, ActionT> > >
88 typedef action<ParserT, ActionT> self_t;
89 typedef action_parser_category parser_category_t;
90 typedef unary<ParserT, parser<self_t> > base_t;
91 typedef ActionT predicate_t;
93 template <typename ScannerT>
96 typedef typename parser_result<ParserT, ScannerT>::type type;
99 action(ParserT const& p, ActionT const& a)
103 template <typename ScannerT>
104 typename parser_result<self_t, ScannerT>::type
105 parse(ScannerT const& scan) const
107 typedef typename ScannerT::iterator_t iterator_t;
108 typedef typename parser_result<self_t, ScannerT>::type result_t;
110 scan.at_end(); // allow skipper to take effect
111 iterator_t save = scan.first;
112 result_t hit = this->subject().parse(scan);
115 typename result_t::return_t val = hit.value();
116 scan.do_action(actor, val, save, scan.first);
121 ActionT const& predicate() const { return actor; }
128 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
132 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
134 }} // namespace BOOST_SPIRIT_CLASSIC_NS