• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
11This module includes different string oriented generators allowing to output
12character 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
20Also, see __include_structure__.
21
22[section:string String Generators (`string`, `lit`)]
23
24[heading Description]
25
26The string generators described in this section are:
27
28The `string` generator emits a string of characters. The `string` generator
29is implicitly verbatim: the `delimit` parser is not applied in between
30characters of the string. The `string` generator has an associated
31__karma_char_encoding_namespace__. This is needed when doing basic operations
32such 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
39difference is that `lit` does not consumes an attribute. A plain
40string like `"hello"` or a `std::basic_string` is equivalent to a `lit`.
41Examples:
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
53Also, 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
63In the table above, `ns` represents a __karma_char_encoding_namespace__ used by the
64corresponding 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
79Semantics of an expression is defined only where it differs from, or is
80not 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 succeeds 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
141Some includes:
142
143[reference_karma_includes]
144
145Some using declarations:
146
147[reference_karma_using_declarations_string]
148
149Basic 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
160The class `symbols` implements an 'inverse' symbol table: an associative
161container (or map) of key-value pairs where the values are (most of the time)
162strings. It maps the value to be generated (the key) to any other value which
163will be emitted instead of the original key.
164
165The Karma symbol table class `symbols` is-a generator, an instance of which may
166be used anywhere in the grammar specification. It is an example of a
167dynamic generator. A dynamic generator is characterized by its ability to
168modify its behavior at run time. Initially, an empty symbols object
169will emit nothing. At any time, symbols may be added, thus, dynamically
170altering 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
177Also, 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
228Semantics of an expression is defined only where it differs from, or is not
229defined 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
275The symbols generator uses the supplied attribute as the key to be looked up
276in the internal associative container. If the key exists the generator emits
277the associated value and succeeds (unless the underlying output stream reports
278an error). If the value type stored in the symbol generator is __unused_type__
279it will emit the key instead. If the key does not exist the generator fails
280while not emitting anything.
281
282[heading Attributes]
283
284The attribute of `symbol<Attrib, T>` is `Attrib`.
285
286If the supplied attribute is a __fusion__ sequence, then the symbol table
287generator will use the first element of that __fusion__ sequence as the key
288to be used for lookup. The type of that first element needs to be convertible
289to `Attrib`. In this case the second element of the __fusion__ sequence is used
290as the attribute while calling a generator derived from the value stored in the
291symbol table for the found entry.
292
293If the supplied attribute is a container type (__customize_is_container__
294resolves to `mpl::true_`), then the symbol table generator will use the first
295element 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
297to `Attrib`. In this case the second element stored in that container is used
298as the attribute while calling a generator derived from the value stored in the
299symbol table for the found entry.
300
301If the supplied attribute is not a __fusion__ sequence and not a container
302type, the supplied attribute is directly used as the key for item lookup. The
303attribute is used as the attribute while calling a generator derived from the
304value stored in the symbol table for the found entry.
305
306In 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)
308is passed as the attribute to a generator derived from the value
309stored in the symbol table for the found entry, the symbol table may store
310generators, 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
332The default implementation uses a `std::map<>` or a `std::set<>` with a
333complexity of:
334
335[:O(log n)]
336
337Where 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
344Some includes:
345
346[reference_karma_includes]
347
348Some using declarations:
349
350[reference_karma_using_declarations_symbols]
351
352Basic usage of `symbol` generators:
353
354[reference_karma_symbols]
355
356[endsect] [/ symbols]
357
358[endsect]
359