]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/============================================================================== |
2 | Copyright (C) 2001-2011 Joel de Guzman | |
3 | Copyright (C) 2001-2011 Hartmut Kaiser | |
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 | ||
9 | [section:string String Generators] | |
10 | ||
11 | This module includes different string oriented generators allowing to output | |
12 | character sequences. It includes the `symbols` generator and variants of the | |
13 | `string` generator. | |
14 | ||
15 | [heading Module Header] | |
16 | ||
17 | // forwards to <boost/spirit/home/karma/string.hpp> | |
18 | #include <boost/spirit/include/karma_string.hpp> | |
19 | ||
20 | Also, see __include_structure__. | |
21 | ||
22 | [section:string String Generators (`string`, `lit`)] | |
23 | ||
24 | [heading Description] | |
25 | ||
26 | The string generators described in this section are: | |
27 | ||
28 | The `string` generator emits a string of characters. The `string` generator | |
29 | is implicitly verbatim: the `delimit` parser is not applied in between | |
30 | characters of the string. The `string` generator has an associated | |
31 | __karma_char_encoding_namespace__. This is needed when doing basic operations | |
32 | such as forcing lower or upper case. Examples: | |
33 | ||
34 | string("Hello") | |
35 | string(L"Hello") | |
36 | string(s) // s is a std::string | |
37 | ||
38 | `lit`, like `string`, also emits a string of characters. The main | |
39 | difference is that `lit` does not consumes an attribute. A plain | |
40 | string like `"hello"` or a `std::basic_string` is equivalent to a `lit`. | |
41 | Examples: | |
42 | ||
43 | "Hello" | |
44 | lit("Hello") | |
45 | lit(L"Hello") | |
46 | lit(s) // s is a std::string | |
47 | ||
48 | [heading Header] | |
49 | ||
50 | // forwards to <boost/spirit/home/karma/string/lit.hpp> | |
51 | #include <boost/spirit/include/karma_string.hpp> | |
52 | ||
53 | Also, see __include_structure__. | |
54 | ||
55 | [heading Namespace] | |
56 | ||
57 | [table | |
58 | [[Name]] | |
59 | [[`boost::spirit::lit // alias: boost::spirit::karma::lit`]] | |
60 | [[`ns::string`]] | |
61 | ] | |
62 | ||
63 | In the table above, `ns` represents a __karma_char_encoding_namespace__ used by the | |
64 | corresponding string generator. | |
65 | ||
66 | [heading Model of] | |
67 | ||
68 | [:__primitive_generator_concept__] | |
69 | ||
70 | [variablelist Notation | |
71 | [[`s`] [Character-class specific string (See __char_class_types__), | |
72 | or a __karma_lazy_argument__ that evaluates to a | |
73 | character-class specific string value]] | |
74 | [[`S`] [The type of a character-class specific string `s`.]] | |
75 | [[`ns`] [A __karma_char_encoding_namespace__.]]] | |
76 | ||
77 | [heading Expression Semantics] | |
78 | ||
79 | Semantics of an expression is defined only where it differs from, or is | |
80 | not defined in __primitive_generator_concept__. | |
81 | ||
82 | [table | |
83 | [[Expression] [Description]] | |
84 | [[`s`] [Generate the string literal `s`. This generator | |
85 | never fails (unless the underlying output stream | |
86 | reports an error).]] | |
87 | [[`lit(s)`] [Generate the string literal `s`. This generator | |
88 | never fails (unless the underlying output stream | |
89 | reports an error).]] | |
90 | [[`ns::string`] [Generate the string provided by a mandatory | |
91 | attribute interpreted in the character set defined | |
92 | by `ns`. This generator never fails (unless the | |
93 | underlying output stream reports an error).]] | |
94 | [[`ns::string(s)`] [Generate the string `s` as provided by the | |
95 | immediate literal value the generator is initialized | |
96 | from. If this generator has an associated attribute | |
97 | it succeeds only if the attribute is equal | |
98 | to the immediate literal (unless the underlying | |
99 | output stream reports an error). Otherwise this | |
100 | generator fails and does not generate any output.]] | |
101 | ] | |
102 | ||
103 | [note The generators `lit(s)` and `string(s)` can be initialized either | |
104 | using a string literal value (i.e. `"abc"`), or using a | |
105 | `std::basic_string<char_type, ...>`, where `char_type` is the required | |
106 | value type of the underlying character sequence.] | |
107 | ||
108 | [caution The generator `string(s)` up to version 2.4.1 of Spirit has an | |
109 | undocumented feature. Given argument `s` generator succeds as long as | |
110 | `s` is a prefix of given attribute. This problem has been fixed in | |
111 | Spirit V2.4.2.] | |
112 | ||
113 | [heading Attributes] | |
114 | ||
115 | [table | |
116 | [[Expression] [Attribute]] | |
117 | [[`s`] [__unused__]] | |
118 | [[`lit(s)`] [__unused__]] | |
119 | [[`ns::string`] [`S`, attribute is mandatory (otherwise compilation | |
120 | will fail)]] | |
121 | [[`ns::string(s)`] [`S`, attribute is optional, if it is supplied, the | |
122 | generator compares the attribute with `s` and | |
123 | succeeds only if both are equal, failing otherwise]] | |
124 | ] | |
125 | ||
126 | [note In addition to their usual attribute of type `S` all listed generators | |
127 | accept an instance of a `boost::optional<S>` as well. If the | |
128 | `boost::optional<>` is initialized (holds a value) the generators behave | |
129 | as if their attribute was an instance of `S` and emit the value stored | |
130 | in the `boost::optional<>`. Otherwise the generators will fail.] | |
131 | ||
132 | [heading Complexity] | |
133 | ||
134 | [:O(N), where N is the number of characters emitted by the string generator] | |
135 | ||
136 | [heading Example] | |
137 | ||
138 | [note The test harness for the example(s) below is presented in the | |
139 | __karma_basics_examples__ section.] | |
140 | ||
141 | Some includes: | |
142 | ||
143 | [reference_karma_includes] | |
144 | ||
145 | Some using declarations: | |
146 | ||
147 | [reference_karma_using_declarations_string] | |
148 | ||
149 | Basic usage of `string` generators: | |
150 | ||
151 | [reference_karma_string] | |
152 | ||
153 | [endsect] | |
154 | ||
155 | [/------------------------------------------------------------------------------] | |
156 | [section:symbols Symbols Generator (`symbols`)] | |
157 | ||
158 | [heading Description] | |
159 | ||
160 | The class `symbols` implements an 'inverse' symbol table: an associative | |
161 | container (or map) of key-value pairs where the values are (most of the time) | |
162 | strings. It maps the value to be generated (the key) to any other value which | |
163 | will be emitted instead of the original key. | |
164 | ||
165 | The Karma symbol table class `symbols` is-a generator, an instance of which may | |
166 | be used anywhere in the grammar specification. It is an example of a | |
167 | dynamic generator. A dynamic generator is characterized by its ability to | |
168 | modify its behavior at run time. Initially, an empty symbols object | |
169 | will emit nothing. At any time, symbols may be added, thus, dynamically | |
170 | altering its behavior. | |
171 | ||
172 | [heading Header] | |
173 | ||
174 | // forwards to <boost/spirit/home/karma/string/symbols.hpp> | |
175 | #include <boost/spirit/include/karma_symbols.hpp> | |
176 | ||
177 | Also, see __include_structure__. | |
178 | ||
179 | [heading Namespace] | |
180 | ||
181 | [table | |
182 | [[Name]] | |
183 | [[`boost::spirit::karma::symbols`]] | |
184 | ] | |
185 | ||
186 | [heading Synopsis] | |
187 | ||
188 | template <typename Attrib, typename T, typename Lookup | |
189 | , typename CharEncoding, typename Tag> | |
190 | struct symbols; | |
191 | ||
192 | [heading Template parameters] | |
193 | ||
194 | [table | |
195 | [[Parameter] [Description] [Default]] | |
196 | [[`Attrib`] [The type of the original attribute to be used as | |
197 | the key into the symbol generator (the symbol).] [`char`]] | |
198 | [[`T`] [The data type associated | |
199 | with each key.] [__unused_type__]] | |
200 | [[`Lookup`] [The symbol search implementation] | |
201 | [if T is `unused_type`, `std::set<Attrib>`, | |
202 | and `std::map<Attrib, T>` otherwise]] | |
203 | [[`CharEncoding`] [Used for character set selection, normally not | |
204 | used by end user.] [__unused_type__]] | |
205 | [[`Tag`] [Used for character set selection, normally not | |
206 | used by end user.] [__unused_type__]] | |
207 | ] | |
208 | ||
209 | [heading Model of] | |
210 | ||
211 | [:__primitive_generator_concept__] | |
212 | ||
213 | [variablelist Notation | |
214 | [[`Sym`] [A `symbols` type.]] | |
215 | [[`Attrib`] [An attribute type.]] | |
216 | [[`T`] [A data type.]] | |
217 | [[`sym`, `sym2`][`symbols` objects.]] | |
218 | [[`sseq`] [An __stl__ container of strings.]] | |
219 | [[`dseq`] [An __stl__ container of data with `value_type` `T`.]] | |
220 | [[`s1`...`sN`] [A __string__.]] | |
221 | [[`d1`...`dN`] [Objects of type `T`.]] | |
222 | [[`f`] [A callable function or function object.]] | |
223 | [[`f`, `l`] [`ForwardIterator` first/last pair.]] | |
224 | ] | |
225 | ||
226 | [heading Expression Semantics] | |
227 | ||
228 | Semantics of an expression is defined only where it differs from, or is not | |
229 | defined in __primitive_generator_concept__. | |
230 | ||
231 | [table | |
232 | [[Expression] [Semantics]] | |
233 | [[`Sym()`] [Construct an empty symbols object instance named `"symbols"`.]] | |
234 | [[`Sym(name)`] [Construct an empty symbols object instance named `name`.]] | |
235 | [[`Sym(sym2)`] [Copy construct a symbols from `sym2` (Another `symbols` object).]] | |
236 | [[`Sym(sseq)`] [Construct symbols from `sseq` (An __stl__ container of | |
237 | symbols of type `Attrib`) named `"symbols"`.]] | |
238 | [[`Sym(sseq, name)`] [Construct symbols from `sseq` (an __stl__ container of | |
239 | symbols of type `Attrib`) named `name`.]] | |
240 | [[`Sym(sseq, dseq)`] [Construct symbols from `sseq` and `dseq` | |
241 | (An __stl__ container of symbols of type `Attrib` and an | |
242 | __stl__ container of data with `value_type` `T`) | |
243 | which is named `"symbols"`.]] | |
244 | [[`Sym(sseq, dseq, name)`] [Construct symbols from `sseq` and `dseq` | |
245 | (An __stl__ container of symbols of type `Attrib` and an | |
246 | __stl__ container of data with `value_type` `T`) | |
247 | which is named `name`.]] | |
248 | [[`sym = sym2`] [Assign `sym2` to `sym`.]] | |
249 | [[`sym = s1, s2, ..., sN`] [Assign one or more symbols (`s1`...`sN`) to `sym`. The | |
250 | associated data values of type `T` are default constructed.]] | |
251 | [[`sym += s1, s2, ..., sN`] [Add one or more symbols (`s1`...`sN`) to `sym`. The | |
252 | associated data values of type `T` are default constructed.]] | |
253 | [[`sym.add(s1)(s2)...(sN)`] [Add one or more symbols (`s1`...`sN`) to `sym`. The | |
254 | associated data values of type `T` are default constructed.]] | |
255 | [[`sym.add(s1, d1)(s2, d2)...(sN, dN)`] | |
256 | [Add one or more symbols (`s1`...`sN`) | |
257 | with associated data (`d1`...`dN`) to `sym`.]] | |
258 | [[`sym -= s1, s2, ..., sN`] [Remove one or more symbols (`s1`...`sN`) from `sym`.]] | |
259 | [[`sym.remove(s1)(s2)...(sN)`] [Remove one or more symbols (`s1`...`sN`) from `sym`.]] | |
260 | [[`sym.clear()`] [Erase all of the symbols in `sym`.]] | |
261 | [[`sym.at(s)`] [Return a reference to the object associated | |
262 | with symbol, `s`. If `sym` does not already | |
263 | contain such an object, `at` inserts the default | |
264 | object `T()`.]] | |
265 | [[`sym.find(s)`] [Return a pointer to the object associated | |
266 | with symbol, `s`. If `sym` does not already | |
267 | contain such an object, `find` returns a null | |
268 | pointer.]] | |
269 | [[`sym.for_each(f)`] [For each symbol in `sym` `s` invoke | |
270 | `f(typename Lookup::value_type)`.]] | |
271 | [[`sym.name()`] [Retrieve the current name of the symbols object.]] | |
272 | [[`sym.name(name)`] [Set the current name of the symbols object to be `name`.]] | |
273 | ] | |
274 | ||
275 | The symbols generator uses the supplied attribute as the key to be looked up | |
276 | in the internal associative container. If the key exists the generator emits | |
277 | the associated value and succeeds (unless the underlying output stream reports | |
278 | an error). If the value type stored in the symbol generator is __unused_type__ | |
279 | it will emit the key instead. If the key does not exist the generator fails | |
280 | while not emitting anything. | |
281 | ||
282 | [heading Attributes] | |
283 | ||
284 | The attribute of `symbol<Attrib, T>` is `Attrib`. | |
285 | ||
286 | If the supplied attribute is a __fusion__ sequence, then the symbol table | |
287 | generator will use the first element of that __fusion__ sequence as the key | |
288 | to be used for lookup. The type of that first element needs to be convertible | |
289 | to `Attrib`. In this case the second element of the __fusion__ sequence is used | |
290 | as the attribute while calling a generator derived from the value stored in the | |
291 | symbol table for the found entry. | |
292 | ||
293 | If the supplied attribute is a container type (__customize_is_container__ | |
294 | resolves to `mpl::true_`), then the symbol table generator will use the first | |
295 | element stored in that container as the key to be used for lookup. The | |
296 | `value_type` (returned by __customize_container_value__) has to be convertible | |
297 | to `Attrib`. In this case the second element stored in that container is used | |
298 | as the attribute while calling a generator derived from the value stored in the | |
299 | symbol table for the found entry. | |
300 | ||
301 | If the supplied attribute is not a __fusion__ sequence and not a container | |
302 | type, the supplied attribute is directly used as the key for item lookup. The | |
303 | attribute is used as the attribute while calling a generator derived from the | |
304 | value stored in the symbol table for the found entry. | |
305 | ||
306 | In any case, because the supplied key (i.e. either the first element of the | |
307 | __fusion__ sequence, the first container element, or the attribute otherwise) | |
308 | is passed as the attribute to a generator derived from the value | |
309 | stored in the symbol table for the found entry, the symbol table may store | |
310 | generators, which will produce output based on that value. For instance: | |
311 | ||
312 | // The symbol table maps a single character key to a rule<> | |
313 | // The rule<> exposes an attribute of char as well | |
314 | rule<output_iterator_type, char()> r1 = char_; | |
315 | ||
316 | symbols<char, rule<output_iterator_type, char()> > sym; | |
317 | sym.add | |
318 | ('j', r1.alias()) | |
319 | ('h', r1.alias()) | |
320 | ('t', r1.alias()) | |
321 | ('k', r1.alias()) | |
322 | ; | |
323 | ||
324 | // Supplying a fusion vector as the attribute will use the first element | |
325 | // (the 'j') as the key to be looked up, while the second element (the 'J') | |
326 | // is passed on as the attribute to the rule<> stored in the symbol table. | |
327 | // Consequently, the example generates a single 'J'. | |
328 | BOOST_ASSERT(test("J", sym, make_vector('j', 'J'))); | |
329 | ||
330 | [heading Complexity] | |
331 | ||
332 | The default implementation uses a `std::map<>` or a `std::set<>` with a | |
333 | complexity of: | |
334 | ||
335 | [:O(log n)] | |
336 | ||
337 | Where n is the number of stored symbols. | |
338 | ||
339 | [heading Example] | |
340 | ||
341 | [note The test harness for the example(s) below is presented in the | |
342 | __karma_basics_examples__ section.] | |
343 | ||
344 | Some includes: | |
345 | ||
346 | [reference_karma_includes] | |
347 | ||
348 | Some using declarations: | |
349 | ||
350 | [reference_karma_using_declarations_symbols] | |
351 | ||
352 | Basic usage of `symbol` generators: | |
353 | ||
354 | [reference_karma_symbols] | |
355 | ||
356 | [endsect] [/ symbols] | |
357 | ||
358 | [endsect] |