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