]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
11fdf7f2 | 14 | #include <boost/core/ignore_unused.hpp> |
7c673cae FG |
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 | action(ParserT const& p, ActionT const& a) | |
101 | : base_t(p) | |
102 | , actor(a) {} | |
103 | ||
104 | template <typename ScannerT> | |
105 | typename parser_result<self_t, ScannerT>::type | |
106 | 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 | ||
11fdf7f2 | 111 | ignore_unused(scan.at_end()); // allow skipper to take effect |
7c673cae FG |
112 | iterator_t save = scan.first; |
113 | result_t hit = this->subject().parse(scan); | |
114 | if (hit) | |
115 | { | |
116 | typename result_t::return_t val = hit.value(); | |
117 | scan.do_action(actor, val, save, scan.first); | |
118 | } | |
119 | 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 |