]>
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 | #if !defined(BOOST_SPIRIT_PARSER_HPP) | |
9 | #define BOOST_SPIRIT_PARSER_HPP | |
10 | ||
11 | #include <boost/config.hpp> | |
12 | #include <boost/type_traits/remove_reference.hpp> | |
13 | #include <boost/spirit/home/classic/namespace.hpp> | |
14 | #include <boost/spirit/home/classic/core/scanner/scanner.hpp> | |
15 | #include <boost/spirit/home/classic/core/nil.hpp> | |
16 | ||
17 | namespace boost { namespace spirit { | |
18 | ||
19 | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
20 | ||
21 | template <typename ParserT, typename ActionT> | |
22 | class action; // forward declaration | |
23 | ||
24 | /////////////////////////////////////////////////////////////////////////// | |
25 | // | |
26 | // Parser categories | |
27 | // | |
28 | // Helper template classes to distinguish different types of | |
29 | // parsers. The following categories are the most generic. More | |
30 | // specific types may inherit from these. Each parser has a typedef | |
31 | // parser_category_t that defines its category. By default, if one | |
32 | // is not specified, it will inherit from the base parser class | |
33 | // which typedefs its parser_category_t as plain_parser_category. | |
34 | // | |
35 | // - plain parser has nothing special | |
36 | // - binary parser has subject a and b (e.g. alternative) | |
37 | // - unary parser has single subject (e.g. kleene star) | |
38 | // - action parser has an attached action parser | |
39 | // | |
40 | /////////////////////////////////////////////////////////////////////////// | |
41 | struct plain_parser_category {}; | |
42 | struct binary_parser_category : plain_parser_category {}; | |
43 | struct unary_parser_category : plain_parser_category {}; | |
44 | struct action_parser_category : unary_parser_category {}; | |
45 | ||
46 | /////////////////////////////////////////////////////////////////////////// | |
47 | // | |
48 | // parser_result metafunction | |
49 | // | |
50 | // Given a scanner type ScannerT and a parser type ParserT, the | |
51 | // parser_result metafunction provides the actual result of the | |
52 | // parser. | |
53 | // | |
54 | // Usage: | |
55 | // | |
56 | // typename parser_result<ParserT, ScannerT>::type | |
57 | // | |
58 | /////////////////////////////////////////////////////////////////////////// | |
59 | template <typename ParserT, typename ScannerT> | |
60 | struct parser_result | |
61 | { | |
62 | typedef typename boost::remove_reference<ParserT>::type parser_type; | |
63 | typedef typename parser_type::template result<ScannerT>::type type; | |
64 | }; | |
65 | ||
66 | /////////////////////////////////////////////////////////////////////////// | |
67 | // | |
68 | // parser class | |
69 | // | |
70 | // This class is a protocol base class for all parsers. This is | |
71 | // essentially an interface contract. The parser class does not | |
72 | // really know how to parse anything but instead relies on the | |
73 | // template parameter DerivedT (which obviously is assumed to be a | |
74 | // subclass) to do the actual parsing. | |
75 | // | |
76 | // Concrete sub-classes inheriting from parser must have a | |
77 | // corresponding member function parse(...) compatible with the | |
78 | // conceptual Interface: | |
79 | // | |
80 | // template <typename ScannerT> | |
81 | // RT parse(ScannerT const& scan) const; | |
82 | // | |
83 | // where RT is the desired return type of the parser and ScannerT | |
84 | // scan is the scanner (see scanner.hpp). | |
85 | // | |
86 | // Concrete sub-classes inheriting from parser in most cases need to | |
87 | // have a nested meta-function result that returns the result type | |
88 | // of the parser's parse member function, given a scanner type. The | |
89 | // meta-function has the form: | |
90 | // | |
91 | // template <typename ScannerT> | |
92 | // struct result | |
93 | // { | |
94 | // typedef RT type; | |
95 | // }; | |
96 | // | |
97 | // where RT is the desired return type of the parser. This is | |
98 | // usually, but not always, dependent on the template parameter | |
99 | // ScannerT. If a parser does not supply a result metafunction, a | |
100 | // default is provided by the base parser class. | |
101 | // | |
102 | // The parser's derived() member function returns a reference to the | |
103 | // parser as its derived object. | |
104 | // | |
105 | // An operator[] is provided. The operator returns a semantic action | |
106 | // handler (see actions.hpp). | |
107 | // | |
108 | // Each parser has a typedef embed_t. This typedef specifies how a | |
109 | // parser is embedded in a composite (see composite.hpp). By | |
110 | // default, if one is not specified, the parser will be embedded by | |
111 | // value. That is, a copy of the parser is placed as a member | |
112 | // variable of the composite. Most parsers are embedded by value. In | |
113 | // certain situations however, this is not desirable or possible. | |
114 | // | |
115 | /////////////////////////////////////////////////////////////////////////// | |
116 | template <typename DerivedT> | |
117 | struct parser | |
118 | { | |
119 | typedef DerivedT embed_t; | |
120 | typedef DerivedT derived_t; | |
121 | typedef plain_parser_category parser_category_t; | |
122 | ||
123 | template <typename ScannerT> | |
124 | struct result | |
125 | { | |
126 | typedef typename match_result<ScannerT, nil_t>::type type; | |
127 | }; | |
128 | ||
129 | DerivedT& derived() | |
130 | { | |
131 | return *static_cast<DerivedT*>(this); | |
132 | } | |
133 | ||
134 | DerivedT const& derived() const | |
135 | { | |
136 | return *static_cast<DerivedT const*>(this); | |
137 | } | |
138 | ||
139 | template <typename ActionT> | |
140 | action<DerivedT, ActionT> | |
141 | operator[](ActionT const& actor) const | |
142 | { | |
143 | return action<DerivedT, ActionT>(derived(), actor); | |
144 | } | |
145 | }; | |
146 | ||
147 | /////////////////////////////////////////////////////////////////////////// | |
148 | // | |
149 | // parse_info | |
150 | // | |
151 | // Results returned by the free parse functions: | |
152 | // | |
153 | // stop: points to the final parse position (i.e parsing | |
154 | // processed the input up to this point). | |
155 | // | |
156 | // hit: true if parsing is successful. This may be full: | |
157 | // the parser consumed all the input, or partial: | |
158 | // the parser consumed only a portion of the input. | |
159 | // | |
160 | // full: true when we have a full hit (i.e the parser | |
161 | // consumed all the input. | |
162 | // | |
163 | // length: The number of characters consumed by the parser. | |
164 | // This is valid only if we have a successful hit | |
165 | // (either partial or full). | |
166 | // | |
167 | /////////////////////////////////////////////////////////////////////////// | |
168 | template <typename IteratorT = char const*> | |
169 | struct parse_info | |
170 | { | |
171 | IteratorT stop; | |
172 | bool hit; | |
173 | bool full; | |
174 | std::size_t length; | |
175 | ||
176 | parse_info( | |
177 | IteratorT const& stop_ = IteratorT(), | |
178 | bool hit_ = false, | |
179 | bool full_ = false, | |
180 | std::size_t length_ = 0) | |
181 | : stop(stop_) | |
182 | , hit(hit_) | |
183 | , full(full_) | |
184 | , length(length_) {} | |
185 | ||
186 | template <typename ParseInfoT> | |
187 | parse_info(ParseInfoT const& pi) | |
188 | : stop(pi.stop) | |
189 | , hit(pi.hit) | |
190 | , full(pi.full) | |
191 | , length(pi.length) {} | |
192 | }; | |
193 | ||
194 | /////////////////////////////////////////////////////////////////////////// | |
195 | // | |
196 | // Generic parse function | |
197 | // | |
198 | /////////////////////////////////////////////////////////////////////////// | |
199 | template <typename IteratorT, typename DerivedT> | |
200 | parse_info<IteratorT> | |
201 | parse( | |
202 | IteratorT const& first, | |
203 | IteratorT const& last, | |
204 | parser<DerivedT> const& p); | |
205 | ||
206 | /////////////////////////////////////////////////////////////////////////// | |
207 | // | |
208 | // Parse function for null terminated strings | |
209 | // | |
210 | /////////////////////////////////////////////////////////////////////////// | |
211 | template <typename CharT, typename DerivedT> | |
212 | parse_info<CharT const*> | |
213 | parse( | |
214 | CharT const* str, | |
215 | parser<DerivedT> const& p); | |
216 | ||
217 | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
218 | ||
219 | }} // namespace BOOST_SPIRIT_CLASSIC_NS | |
220 | ||
221 | #endif | |
222 | ||
223 | #include <boost/spirit/home/classic/core/impl/parser.ipp> |