source: NonGTP/Boost/boost/spirit/core/composite/actions.hpp @ 857

Revision 857, 4.7 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Copyright (c) 1998-2003 Joel de Guzman
3    http://spirit.sourceforge.net/
4
5    Use, modification and distribution is subject to the Boost Software
6    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7    http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9#ifndef BOOST_SPIRIT_ACTIONS_HPP
10#define BOOST_SPIRIT_ACTIONS_HPP
11
12#include <boost/spirit/core/parser.hpp>
13#include <boost/spirit/core/composite/composite.hpp>
14
15namespace boost { namespace spirit {
16
17    ///////////////////////////////////////////////////////////////////////////
18    //
19    //  action class
20    //
21    //      The action class binds a parser with a user defined semantic
22    //      action. Instances of action are never created manually. Instead,
23    //      action objects are typically created indirectly through
24    //      expression templates of the form:
25    //
26    //          p[f]
27    //
28    //      where p is a parser and f is a function or functor. The semantic
29    //      action may be a function or a functor. When the parser is
30    //      successful, the actor calls the scanner's action_policy policy
31    //      (see scanner.hpp):
32    //
33    //          scan.do_action(actor, attribute, first, last);
34    //
35    //      passing in these information:
36    //
37    //          actor:        The action's function or functor
38    //          attribute:    The match (returned by the parser) object's
39    //                        attribute (see match.hpp)
40    //          first:        Iterator pointing to the start of the matching
41    //                        portion of the input
42    //          last:         Iterator pointing to one past the end of the
43    //                        matching portion of the input
44    //
45    //      It is the responsibility of the scanner's action_policy policy to
46    //      dispatch the function or functor as it sees fit. The expected
47    //      function or functor signature depends on the parser being
48    //      wrapped. In general, if the attribute type of the parser being
49    //      wrapped is a nil_t, the function or functor expect the signature:
50    //
51    //          void func(Iterator first, Iterator last); // functions
52    //
53    //          struct ftor // functors
54    //          {
55    //              void func(Iterator first, Iterator last) const;
56    //          };
57    //
58    //      where Iterator is the type of the iterator that is being used and
59    //      first and last are the iterators pointing to the matching portion
60    //      of the input.
61    //
62    //      If the attribute type of the parser being wrapped is not a nil_t,
63    //      the function or functor usually expect the signature:
64    //
65    //          void func(T val); // functions
66    //
67    //          struct ftor // functors
68    //          {
69    //              void func(T val) const;
70    //          };
71    //
72    //      where T is the attribute type and val is the attribute value
73    //      returned by the parser being wrapped.
74    //
75    ///////////////////////////////////////////////////////////////////////////
76    template <typename ParserT, typename ActionT>
77    class action : public unary<ParserT, parser<action<ParserT, ActionT> > >
78    {
79    public:
80
81        typedef action<ParserT, ActionT>        self_t;
82        typedef action_parser_category          parser_category_t;
83        typedef unary<ParserT, parser<self_t> > base_t;
84        typedef ActionT                         predicate_t;
85
86        template <typename ScannerT>
87        struct result
88        {
89            typedef typename parser_result<ParserT, ScannerT>::type type;
90        };
91
92        action(ParserT const& p, ActionT const& a)
93        : base_t(p)
94        , actor(a) {}
95
96        template <typename ScannerT>
97        typename parser_result<self_t, ScannerT>::type
98        parse(ScannerT const& scan) const
99        {
100            typedef typename ScannerT::iterator_t iterator_t;
101            typedef typename parser_result<self_t, ScannerT>::type result_t;
102
103            scan.at_end(); // allow skipper to take effect
104            iterator_t save = scan.first;
105            result_t hit = this->subject().parse(scan);
106            if (hit)
107            {
108                typename result_t::return_t val = hit.value();
109                scan.do_action(actor, val, save, scan.first);
110            }
111            return hit;
112        }
113
114        ActionT const& predicate() const { return actor; }
115
116    private:
117
118        ActionT actor;
119    };
120
121}} // namespace boost::spirit
122
123#endif
Note: See TracBrowser for help on using the repository browser.