]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/============================================================================== |
2 | Copyright (C) 2001-2011 Joel de Guzman | |
3 | Copyright (C) 2001-2011 Hartmut Kaiser | |
4 | Copyright (C) 2011 Bryce Lelbach | |
5 | ||
6 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
7 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 | ===============================================================================/] | |
9 | ||
10 | [section:directive Parser Directives] | |
11 | ||
12 | This module includes different directives usable to augment and parameterize | |
13 | other parsers. It includes the `no_case`, `lexeme`, `omit`, `raw`, `repeat`, | |
14 | `matches`, `no_skip`, `skip`, `hold`, `as<T>`, `as_string` and | |
15 | `as_wstring` directives. | |
16 | ||
17 | ||
18 | [heading Module Header] | |
19 | ||
20 | // forwards to <boost/spirit/home/qi/directive.hpp> | |
21 | #include <boost/spirit/include/qi_directive.hpp> | |
22 | ||
23 | Also, see __include_structure__. | |
24 | ||
25 | [/------------------------------------------------------------------------------] | |
26 | [section:lexeme Parser Directive Inhibiting Skipping (`lexeme[]`)] | |
27 | ||
28 | [heading Description] | |
29 | ||
30 | The `lexeme` directive makes its subject a primitive. In a logical point | |
31 | of view, lexemes (and primitives) are minimal atomic units (e.g. words, | |
32 | numbers, identifiers, etc). These are the things that you'd normally put | |
33 | in the lexer (hinting at the term "lexeme"), but in a lexer-less world, | |
34 | you put these in a lexeme. Seeing its subject as a primitive, the | |
35 | `lexeme` directive does an initial pre-skip (as all primitives do) and | |
36 | turns off white space skipping. | |
37 | ||
38 | At the phrase level, the parser ignores white spaces, possibly including | |
39 | comments. Use `lexeme` in situations where you want to work at the | |
40 | character level instead of the phrase level. Parsers can be made to work | |
41 | at the character level by enclosing the pertinent parts inside the | |
42 | `lexeme` directive. For example, here's a rule that parses integers: | |
43 | ||
44 | integer = lexeme[ -(lit('+') | '-') >> +digit ]; | |
45 | ||
46 | The `lexeme` directive instructs its subject parser to work on the | |
47 | character level. Without it, the `integer` rule would have allowed | |
48 | erroneous embedded white spaces in inputs such as `"1 2 345"` which will | |
49 | be parsed as `"12345"`. | |
50 | ||
51 | [note Keep in mind that `lexeme[]` pre-skips spaces. If this is not | |
52 | desired, use the [qi_no_skip `no_skip`] directive instead.] | |
53 | ||
54 | [heading Header] | |
55 | ||
56 | // forwards to <boost/spirit/home/qi/directive/lexeme.hpp> | |
57 | #include <boost/spirit/include/qi_lexeme.hpp> | |
58 | ||
59 | Also, see __include_structure__. | |
60 | ||
61 | [heading Namespace] | |
62 | ||
63 | [table | |
64 | [[Name]] | |
65 | [[`boost::spirit::lexeme // alias: boost::spirit::qi::lexeme` ]] | |
66 | ] | |
67 | ||
68 | [heading Model of] | |
69 | ||
70 | [:__unary_parser_concept__] | |
71 | ||
72 | [variablelist Notation | |
73 | [[`a`] [A __parser_concept__.]] | |
74 | ] | |
75 | ||
76 | [heading Expression Semantics] | |
77 | ||
78 | Semantics of an expression is defined only where it differs from, or is | |
79 | not defined in __unary_parser_concept__. | |
80 | ||
81 | [table | |
82 | [[Expression] [Semantics]] | |
83 | [[`lexeme[a]`] [Pre-skip and turn off white space skipping for the | |
84 | subject parser, `a` (and all its children).]] | |
85 | ] | |
86 | ||
87 | [heading Attributes] | |
88 | ||
89 | See __qi_comp_attr_notation__. | |
90 | ||
91 | [table | |
92 | [[Expression] [Attribute]] | |
93 | [[`lexeme[a]`] | |
94 | [``a: A --> lexeme[a]: A | |
95 | a: Unused --> lexeme[a]: Unused``]] | |
96 | ] | |
97 | ||
98 | [heading Complexity] | |
99 | ||
100 | [:The complexity is defined by the complexity of the subject parser, `a`] | |
101 | ||
102 | [heading Example] | |
103 | ||
104 | [note The test harness for the example(s) below is presented in the | |
105 | __qi_basics_examples__ section.] | |
106 | ||
107 | Some using declarations: | |
108 | ||
109 | [reference_using_declarations_lexeme] | |
110 | ||
111 | Simple usage of `lexeme[]`: | |
112 | ||
113 | [reference_lexeme] | |
114 | ||
115 | [endsect] | |
116 | ||
117 | [/------------------------------------------------------------------------------] | |
118 | [section:no_skip Parser Directive Inhibiting Skipping Without Pre-skip (`no_skip[]`)] | |
119 | ||
120 | [heading Description] | |
121 | ||
122 | The `no_skip[]` directive turns off white space skipping. The difference to | |
123 | __qi_lexeme__ is that it does not do pre-skipping in any case. Otherwise it is | |
124 | completely equivalent to the __qi_lexeme__ directive. | |
125 | ||
126 | [heading Header] | |
127 | ||
128 | // forwards to <boost/spirit/home/qi/directive/no_skip.hpp> | |
129 | #include <boost/spirit/include/qi_no_skip.hpp> | |
130 | ||
131 | Also, see __include_structure__. | |
132 | ||
133 | [heading Namespace] | |
134 | ||
135 | [table | |
136 | [[Name]] | |
137 | [[`boost::spirit::no_skip // alias: boost::spirit::qi::no_skip` ]] | |
138 | ] | |
139 | ||
140 | [heading Model of] | |
141 | ||
142 | [:__unary_parser_concept__] | |
143 | ||
144 | [variablelist Notation | |
145 | [[`a`] [A __parser_concept__.]] | |
146 | ] | |
147 | ||
148 | [heading Expression Semantics] | |
149 | ||
150 | Semantics of an expression is defined only where it differs from, or is | |
151 | not defined in __unary_parser_concept__. | |
152 | ||
153 | [table | |
154 | [[Expression] [Semantics]] | |
155 | [[`no_skip[a]`] [Turns off white space skipping for the | |
156 | subject parser, `a` (and all its children). This | |
157 | directive does not pre-skips.]] | |
158 | ] | |
159 | ||
160 | [heading Attributes] | |
161 | ||
162 | See __qi_comp_attr_notation__. | |
163 | ||
164 | [table | |
165 | [[Expression] [Attribute]] | |
166 | [[`no_skip[a]`] | |
167 | [``a: A --> no_skip[a]: A | |
168 | a: Unused --> no_skip[a]: Unused``]] | |
169 | ] | |
170 | ||
171 | [heading Complexity] | |
172 | ||
173 | [:The complexity is defined by the complexity of the subject parser, `a`] | |
174 | ||
175 | [heading Example] | |
176 | ||
177 | [note The test harness for the example(s) below is presented in the | |
178 | __qi_basics_examples__ section.] | |
179 | ||
180 | Some using declarations: | |
181 | ||
182 | [reference_using_declarations_no_skip] | |
183 | ||
184 | Simple usage of `no_skip[]`: | |
185 | ||
186 | [reference_no_skip] | |
187 | ||
188 | [endsect] | |
189 | ||
190 | [/------------------------------------------------------------------------------] | |
191 | [section:no_case Parser Directive Inhibiting Case Sensitivity (`no_case[]`)] | |
192 | ||
193 | [heading Description] | |
194 | ||
195 | The `no_case[]` directive does not consume any input. The actual | |
196 | matching is done by its subject parser. It's purpose is to force | |
197 | matching of the subject parser (and all its children) to be case | |
198 | insensitive. | |
199 | ||
200 | [heading Header] | |
201 | ||
202 | // forwards to <boost/spirit/home/qi/directive/no_case.hpp> | |
203 | #include <boost/spirit/include/qi_no_case.hpp> | |
204 | ||
205 | Also, see __include_structure__. | |
206 | ||
207 | [heading Namespace] | |
208 | ||
209 | [table | |
210 | [[Name]] | |
211 | [[`ns::no_case`]] | |
212 | ] | |
213 | ||
214 | In the table above, `ns` represents a __char_encoding_namespace__. | |
215 | ||
216 | [heading Model of] | |
217 | ||
218 | The model of `no_case` is the model of its subject parser. | |
219 | ||
220 | [variablelist Notation | |
221 | [[`a`] [A __parser_concept__.]] | |
222 | [[`ns`] [A __char_encoding_namespace__.]] | |
223 | ] | |
224 | ||
225 | [heading Expression Semantics] | |
226 | ||
227 | Semantics of an expression is defined only where it differs from, or is | |
228 | not defined in the subject's concept. | |
229 | ||
230 | [table | |
231 | [[Expression] [Semantics]] | |
232 | [[`ns::no_case[a]`] [Force matching of the subject parser, `a` | |
233 | (and all its children) to be case insensitive]] | |
234 | ] | |
235 | ||
236 | [heading Attributes] | |
237 | ||
238 | See __qi_comp_attr_notation__. | |
239 | ||
240 | [table | |
241 | [[Expression] [Attribute]] | |
242 | [[`ns::no_case[a]`] | |
243 | [``a: A --> ns::no_case[a]: A | |
244 | a: Unused --> ns::no_case[a]: Unused``]] | |
245 | ] | |
246 | ||
247 | [heading Complexity] | |
248 | ||
249 | [:The complexity is defined by the complexity of the subject parser, `a`] | |
250 | ||
251 | [heading Example] | |
252 | ||
253 | [note The test harness for the example(s) below is presented in the | |
254 | __qi_basics_examples__ section.] | |
255 | ||
256 | Some using declarations: | |
257 | ||
258 | [reference_using_declarations_no_case] | |
259 | ||
260 | Simple usage of `no_case[]`: | |
261 | ||
262 | [reference_no_case] | |
263 | ||
264 | A more sophisticated use case of `no_case[]` in conjunction with a symbol | |
265 | table (see __qi_symbols__ for more details): | |
266 | ||
267 | [reference_symbols_with_no_case] | |
268 | ||
269 | [endsect] | |
270 | ||
271 | [/------------------------------------------------------------------------------] | |
272 | [section:omit Parser Directive Ignoring Attribute (`omit[]`)] | |
273 | ||
274 | [heading Description] | |
275 | ||
276 | The `omit[]` ignores the attribute of its subject parser replacing it | |
277 | with __unused__. | |
278 | ||
279 | [heading Header] | |
280 | ||
281 | // forwards to <boost/spirit/home/qi/directive/omit.hpp> | |
282 | #include <boost/spirit/include/qi_omit.hpp> | |
283 | ||
284 | Also, see __include_structure__. | |
285 | ||
286 | [heading Namespace] | |
287 | ||
288 | [table | |
289 | [[Name]] | |
290 | [[`boost::spirit::omit // alias: boost::spirit::qi::omit` ]] | |
291 | ] | |
292 | ||
293 | [heading Model of] | |
294 | ||
295 | [:__unary_parser_concept__] | |
296 | ||
297 | [variablelist Notation | |
298 | [[`a`] [A __parser_concept__.]] | |
299 | ] | |
300 | ||
301 | [heading Expression Semantics] | |
302 | ||
303 | Semantics of an expression is defined only where it differs from, or is | |
304 | not defined in __unary_parser_concept__. | |
305 | ||
306 | [table | |
307 | [[Expression] [Semantics]] | |
308 | [[`omit[a]`] [Ignore the attribute of the subject parser, `a`]] | |
309 | ] | |
310 | ||
311 | [heading Attributes] | |
312 | ||
313 | [table | |
314 | [[Expression] [Attribute]] | |
315 | [[`omit[a]`] [__unused_type__]] | |
316 | ] | |
317 | ||
318 | [heading Complexity] | |
319 | ||
320 | [:The complexity is defined by the complexity of the subject parser, `a`] | |
321 | ||
322 | [heading Example] | |
323 | ||
324 | [note The test harness for the example(s) below is presented in the | |
325 | __qi_basics_examples__ section.] | |
326 | ||
327 | Some using declarations: | |
328 | ||
329 | [reference_using_declarations_omit] | |
330 | ||
331 | [reference_omit] | |
332 | ||
333 | [endsect] | |
334 | ||
335 | [/------------------------------------------------------------------------------] | |
336 | [section:raw Directive for Transduction Parsing (`raw[]`)] | |
337 | ||
338 | [heading Description] | |
339 | ||
340 | The `raw[]` disregards the attribute of its subject parser, instead | |
341 | exposing the half-open range `[first, last)` pointing to the matched | |
342 | characters from the input stream. The `raw[]` directive brings back the | |
343 | classic Spirit transduction (un-attributed) behavior for a subject | |
344 | parser. | |
345 | ||
346 | [heading Header] | |
347 | ||
348 | // forwards to <boost/spirit/home/qi/directive/raw.hpp> | |
349 | #include <boost/spirit/include/qi_raw.hpp> | |
350 | ||
351 | Also, see __include_structure__. | |
352 | ||
353 | [heading Namespace] | |
354 | ||
355 | [table | |
356 | [[Name]] | |
357 | [[`boost::spirit::raw // alias: boost::spirit::qi::raw` ]] | |
358 | ] | |
359 | ||
360 | [heading Model of] | |
361 | ||
362 | [:__unary_parser_concept__] | |
363 | ||
364 | [variablelist Notation | |
365 | [[`a`] [A __parser_concept__.]] | |
366 | [[`Iter`] [A __fwditer__ type.]] | |
367 | ] | |
368 | ||
369 | [heading Expression Semantics] | |
370 | ||
371 | Semantics of an expression is defined only where it differs from, or is | |
372 | not defined in __unary_parser_concept__. | |
373 | ||
374 | [table | |
375 | [[Expression] [Semantics]] | |
376 | [[`raw[a]`] [Disregard the attribute of the subject parser, `a`. | |
377 | Expose instead the half-open range `[first, last)` | |
378 | pointing to the matched characters from the input stream.]] | |
379 | ] | |
380 | ||
381 | [heading Attributes] | |
382 | ||
383 | See __qi_comp_attr_notation__. | |
384 | ||
385 | [table | |
386 | [[Expression] [Attribute]] | |
387 | [[`raw[a]`] | |
388 | [``a: A --> raw[a]: boost::iterator_range<Iter> | |
389 | a: Unused --> raw[a]: Unused``]] | |
390 | ] | |
391 | ||
392 | [note See __boost_iterator_range__.] | |
393 | ||
394 | [heading Complexity] | |
395 | ||
396 | [:The complexity is defined by the complexity of the subject parser, `a`] | |
397 | ||
398 | [heading Example] | |
399 | ||
400 | [note The test harness for the example(s) below is presented in the | |
401 | __qi_basics_examples__ section.] | |
402 | ||
403 | Some using declarations: | |
404 | ||
405 | [reference_using_declarations_raw] | |
406 | ||
407 | [reference_raw] | |
408 | ||
409 | [endsect] | |
410 | ||
411 | [/------------------------------------------------------------------------------] | |
412 | [section:repeat Repetition Parser Directive (`repeat[]`)] | |
413 | ||
414 | [heading Description] | |
415 | ||
416 | The `repeat[]` provides a more powerful and flexible mechanism for | |
417 | repeating a parser. There are grammars that are impractical and | |
418 | cumbersome, if not impossible, for the basic EBNF iteration syntax | |
419 | (__qi_kleene__ and the __qi_plus__) to specify. Examples: | |
420 | ||
421 | * A file name may have a maximum of 255 characters only. | |
422 | * A specific bitmap file format has exactly 4096 RGB color information. | |
423 | * A 256 bit binary string (1..256 1s or 0s). | |
424 | ||
425 | [heading Header] | |
426 | ||
427 | // forwards to <boost/spirit/home/qi/directive/repeat.hpp> | |
428 | #include <boost/spirit/include/qi_repeat.hpp> | |
429 | ||
430 | Also, see __include_structure__. | |
431 | ||
432 | [heading Namespace] | |
433 | ||
434 | [table | |
435 | [[Name]] | |
436 | [[`boost::spirit::repeat // alias: boost::spirit::qi::repeat` ]] | |
437 | [[`boost::spirit::inf // alias: boost::spirit::qi::inf` ]] | |
438 | ] | |
439 | ||
440 | [heading Model of] | |
441 | ||
442 | [:__unary_parser_concept__] | |
443 | ||
444 | [variablelist Notation | |
445 | [[`a`] [A __parser_concept__.]] | |
446 | [[`n`, `min`, `max`] [An `int` anything that can be converted to an | |
447 | `int`, or a __qi_lazy_argument__ that evaluates to | |
448 | anything that can be converted to an `int`.]] | |
449 | ] | |
450 | ||
451 | [heading Expression Semantics] | |
452 | ||
453 | Semantics of an expression is defined only where it differs from, or is | |
454 | not defined in __unary_parser_concept__. | |
455 | ||
456 | [table | |
457 | [[Expression] [Semantics]] | |
458 | [[`repeat[a]`] [Repeat `a` zero or more times. Same as __qi_kleene__.]] | |
459 | [[`repeat(n)[a]`] [Repeat `a` exactly `n` times.]] | |
460 | [[`repeat(min, max)[a]`] [Repeat `a` at least `min` times and at most `max` times.]] | |
461 | [[`repeat(min, inf)[a]`] [Repeat `a` at least `min` or more (continuing until `a` | |
462 | fails or the input is consumed).]] | |
463 | ] | |
464 | ||
465 | [heading Attributes] | |
466 | ||
467 | See __qi_comp_attr_notation__. | |
468 | ||
469 | [table | |
470 | [[Expression] [Attribute]] | |
471 | [[`repeat[a]`] | |
472 | [``a: A --> repeat[a]: vector<A> | |
473 | a: Unused --> repeat[a]: Unused``]] | |
474 | [[`repeat(n)[a]`] | |
475 | [``a: A --> repeat(n)[a]: vector<A> | |
476 | a: Unused --> repeat(n)[a]: Unused``]] | |
477 | [[`repeat(min, max)[a]`] | |
478 | [``a: A --> repeat(min, max)[a]: vector<A> | |
479 | a: Unused --> repeat(min, max)[a]: Unused``]] | |
480 | [[`repeat(min, inf)[a]`] | |
481 | [``a: A --> repeat(min, inf)[a]: vector<A> | |
482 | a: Unused --> repeat(min, inf)[a]: Unused``]] | |
483 | ] | |
484 | ||
485 | [heading Complexity] | |
486 | ||
487 | [:The overall complexity is defined by the complexity of its subject | |
488 | parser. The complexity of `repeat` itself is O(N), where N is the number | |
489 | of repetitions to execute.] | |
490 | ||
491 | [heading Example] | |
492 | ||
493 | [note The test harness for the example(s) below is presented in the | |
494 | __qi_basics_examples__ section.] | |
495 | ||
496 | Using the repeat directive, we can now write our examples above. | |
497 | ||
498 | Some using declarations: | |
499 | ||
500 | [reference_using_declarations_repeat] | |
501 | ||
502 | [reference_repeat] | |
503 | ||
504 | The Loop parsers can be dynamic. Consider the parsing of a binary file | |
505 | of Pascal-style length prefixed string, where the first byte determines | |
506 | the length of the incoming string. Here's a sample input: | |
507 | ||
508 | [:__pascal_string__] | |
509 | ||
510 | [reference_repeat_pascal] | |
511 | ||
512 | [endsect] | |
513 | ||
514 | [/------------------------------------------------------------------------------] | |
515 | [section:matches Directive Testing if Parser Succeeded (`matches[]`)] | |
516 | ||
517 | [heading Description] | |
518 | ||
519 | The `matches[]` directive executes the embedded parser and returns whether it | |
520 | succeeded matching. | |
521 | ||
522 | [heading Header] | |
523 | ||
524 | // forwards to <boost/spirit/home/qi/directive/matches.hpp> | |
525 | #include <boost/spirit/include/qi_matches.hpp> | |
526 | ||
527 | Also, see __include_structure__. | |
528 | ||
529 | [heading Namespace] | |
530 | ||
531 | [table | |
532 | [[Name]] | |
533 | [[`boost::spirit::matches // alias: boost::spirit::qi::matches` ]] | |
534 | ] | |
535 | ||
536 | [heading Model of] | |
537 | ||
538 | [:__unary_parser_concept__] | |
539 | ||
540 | [variablelist Notation | |
541 | [[`a`] [A __parser_concept__.]] | |
542 | ] | |
543 | ||
544 | [heading Expression Semantics] | |
545 | ||
546 | Semantics of an expression is defined only where it differs from, or is | |
547 | not defined in __unary_parser_concept__. | |
548 | ||
549 | [table | |
550 | [[Expression] [Semantics]] | |
551 | [[`matches[a]`] [Execute the subject parser `a`, and return as its | |
552 | attribute whether it succeeded. The directive itself | |
553 | does always succeed.]] | |
554 | ] | |
555 | ||
556 | [heading Attributes] | |
557 | ||
558 | [table | |
559 | [[Expression] [Attribute]] | |
560 | [[`matches[a]`] [`bool`]] | |
561 | ] | |
562 | ||
563 | [heading Complexity] | |
564 | ||
565 | [:The complexity is defined by the complexity of the subject parser, `a`] | |
566 | ||
567 | [heading Example] | |
568 | ||
569 | [note The test harness for the example(s) below is presented in the | |
570 | __qi_basics_examples__ section.] | |
571 | ||
572 | Some using declarations: | |
573 | ||
574 | [reference_using_declarations_matches] | |
575 | ||
576 | [reference_matches] | |
577 | ||
578 | [endsect] | |
579 | ||
580 | [/------------------------------------------------------------------------------] | |
581 | [section:skip Parser Directive Re-Establishing Skipping (`skip[]`)] | |
582 | ||
583 | [heading Description] | |
584 | ||
585 | The `skip` directive is the inverse of __qi_lexeme__ or [qi_no_skip `no_skip[]`]. | |
586 | While the __qi_lexeme__ directive turns off white space | |
587 | skipping, the `skip` directive turns it on again. This is simply done by | |
588 | wrapping the parts inside the `skip` directive: | |
589 | ||
590 | skip[a] | |
591 | ||
592 | It is also possible to supply a skip parser to the `skip` directive: | |
593 | ||
594 | skip(p)[a] // Use `p` as a skipper for parsing `a` | |
595 | ||
596 | This makes it possible to: | |
597 | ||
598 | * Perform localized phrase level parsing while doing character level parsing. | |
599 | * Replace the current skipper anywhere with an entirely different | |
600 | skipper while doing phrase level parsing. | |
601 | ||
602 | [heading Header] | |
603 | ||
604 | // forwards to <boost/spirit/home/qi/directive/skip.hpp> | |
605 | #include <boost/spirit/include/qi_skip.hpp> | |
606 | ||
607 | Also, see __include_structure__. | |
608 | ||
609 | [heading Namespace] | |
610 | ||
611 | [table | |
612 | [[Name]] | |
613 | [[`boost::spirit::skip // alias: boost::spirit::qi::skip` ]] | |
614 | ] | |
615 | ||
616 | [heading Model of] | |
617 | ||
618 | [:__unary_parser_concept__] | |
619 | ||
620 | [variablelist Notation | |
621 | [[`a`] [A __parser_concept__.]] | |
622 | ] | |
623 | ||
624 | [heading Expression Semantics] | |
625 | ||
626 | Semantics of an expression is defined only where it differs from, or is | |
627 | not defined in __unary_parser_concept__. | |
628 | ||
629 | [table | |
630 | [[Expression] [Semantics]] | |
631 | ||
632 | [[`skip[a]`] [Re-establish the skipper that got inhibited by lexeme or no_skip]] | |
633 | [[`skip(p)[a]`] [Use `p` as a skipper for parsing `a`]] | |
634 | ] | |
635 | ||
636 | [heading Attributes] | |
637 | ||
638 | See __qi_comp_attr_notation__. | |
639 | ||
640 | [table | |
641 | [[Expression] [Attribute]] | |
642 | [[`skip[a]`] | |
643 | [``a: A --> skip[a]: A | |
644 | a: Unused --> skip[a]: Unused``]] | |
645 | [[`skip(p)[a]`] | |
646 | [``a: A --> skip(p)[a]: A | |
647 | a: Unused --> skip(p)[a]: Unused``]] | |
648 | ] | |
649 | ||
650 | [heading Complexity] | |
651 | ||
652 | [:The complexity is defined by the complexity of the subject parser, `a`] | |
653 | ||
654 | [heading Example] | |
655 | ||
656 | [note The test harness for the example(s) below is presented in the | |
657 | __qi_basics_examples__ section.] | |
658 | ||
659 | Some using declarations: | |
660 | ||
661 | [reference_using_declarations_skip] | |
662 | ||
663 | Simple usage of `skip[]`: | |
664 | ||
665 | [reference_skip] | |
666 | ||
667 | [endsect] | |
668 | ||
669 | [/------------------------------------------------------------------------------] | |
670 | [section:hold Parser Directive for Attribute Commit/Rollback (`hold[]`)] | |
671 | ||
672 | [heading Description] | |
673 | ||
674 | The `hold[]` directive helps managing attributes, mainly for alternative | |
675 | parsers. It instantiates a new attribute instance for the embedded parser. The | |
676 | value of that attribute instance is copied to the outer attribute if the | |
677 | embedded parser succeeds and it is discarded otherwise. Alternative parsers | |
678 | normally do not rollback changes made to the outer attribute by an failed | |
679 | alternative. Wrapping those alternatives into a `hold[]` directive ensures that | |
680 | only the succeeding alternative gets to modify the attribute. | |
681 | ||
682 | [heading Header] | |
683 | ||
684 | // forwards to <boost/spirit/home/qi/directive/hold.hpp> | |
685 | #include <boost/spirit/include/qi_hold.hpp> | |
686 | ||
687 | Also, see __include_structure__. | |
688 | ||
689 | [heading Namespace] | |
690 | ||
691 | [table | |
692 | [[Name]] | |
693 | [[`boost::spirit::hold // alias: boost::spirit::qi::hold` ]] | |
694 | ] | |
695 | ||
696 | [heading Model of] | |
697 | ||
698 | [:__unary_parser_concept__] | |
699 | ||
700 | [variablelist Notation | |
701 | [[`a`] [A __parser_concept__.]] | |
702 | ] | |
703 | ||
704 | [heading Expression Semantics] | |
705 | ||
706 | Semantics of an expression is defined only where it differs from, or is | |
707 | not defined in __unary_parser_concept__. | |
708 | ||
709 | [table | |
710 | [[Expression] [Semantics]] | |
711 | ||
712 | [[`hold[a]`] [Create a new attribute instance while parsing `a`, | |
713 | copying the result to the outer attribute only after | |
714 | `a` succeeds.]] | |
715 | ] | |
716 | ||
717 | [heading Attributes] | |
718 | ||
719 | See __qi_comp_attr_notation__. | |
720 | ||
721 | [table | |
722 | [[Expression] [Attribute]] | |
723 | [[`hold[a]`] | |
724 | [``a: A --> hold[a]: A | |
725 | a: Unused --> hold[a]: Unused``]] | |
726 | ] | |
727 | ||
728 | [note The `hold[]` directive uses `swap()` to implement the rollback/commit | |
729 | semantics for the attribute. For this reason the attribute type needs to | |
730 | to be usable with `boost::swap` (needs to either define a proper overload | |
731 | for `swap(attribute_type&, attribute_type&)` or expose a member function | |
732 | `attribute_type::swap(attribute_type&)`.] | |
733 | ||
734 | [heading Complexity] | |
735 | ||
736 | [:The complexity is defined by the complexity of the subject parser, `a`] | |
737 | ||
738 | [heading Example] | |
739 | ||
740 | [note The test harness for the example(s) below is presented in the | |
741 | __qi_basics_examples__ section.] | |
742 | ||
743 | Some using declarations: | |
744 | ||
745 | [reference_using_declarations_hold] | |
746 | ||
747 | [reference_hold] | |
748 | ||
749 | [endsect] | |
750 | ||
751 | [/------------------------------------------------------------------------------] | |
752 | [section:as Parser Directives Forcing Atomic Assignment (`as<T>, as_string[], as_wstring[]`)] | |
753 | ||
754 | [heading Description] | |
755 | ||
756 | The `as<T>` class forces the atomic assignment of it's subject's synthesized | |
757 | attribute. Usually, repetitive parsers (such as __qi_kleene__, etc) or | |
758 | sequences exposing a `vector<A>` will assign elements to the container supplied | |
759 | as their synthesized attribute by calling __customize_push_back_container__ | |
760 | repeatedly. In some cases, this may be undesirable. The `as<T>` class creates a | |
761 | directive that will pass a temporary object of type `T` to it's subject. If the | |
762 | subject parser passes, the temporary object will be assigned to the directive's | |
763 | supplied attribute with a single call to __customize_assign_to__. If the | |
764 | subject parser fails, the directive's attribute is not mutated. | |
765 | ||
766 | [note `T` is required to be a container type. If __customize_is_container__ | |
767 | does not return true for `T`, a compile-time error will occur.] | |
768 | ||
769 | [note The `as<T>` implicitly causes commit/rollback semantics | |
770 | similar in nature to the __qi_hold__ directive.] | |
771 | ||
772 | [caution The __customize_assign_to__ customization point may end up | |
773 | using __customize_push_back_container__ to assign the temporary object to the | |
774 | supplied attribute by default, depending on the types involved. Use the | |
775 | interface described in __sec_customization_points__ to manipulate the semantics | |
776 | of this assignment operation.] | |
777 | ||
778 | [heading Header] | |
779 | ||
780 | // forwards to <boost/spirit/home/qi/directive/as.hpp> | |
781 | #include <boost/spirit/include/qi_as.hpp> | |
782 | ||
783 | Also, see __include_structure__. | |
784 | ||
785 | [heading Namespace] | |
786 | ||
787 | [table | |
788 | [[Name]] | |
789 | [[`boost::spirit::as // alias: boost::spirit::qi::as` ]] | |
790 | [[`boost::spirit::as_string // alias: boost::spirit::qi::as_string` ]] | |
791 | [[`boost::spirit::as_wstring // alias: boost::spirit::qi::as_wstring` ]] | |
792 | ] | |
793 | ||
794 | [heading Synopsis] | |
795 | ||
796 | template <typename T> | |
797 | struct as; | |
798 | ||
799 | [heading Template parameters] | |
800 | ||
801 | [table | |
802 | [[Parameter] [Description] [Default]] | |
803 | [[`T`] [A container type. [none]] | |
804 | ] | |
805 | ||
806 | [heading Model of] | |
807 | ||
808 | [:__unary_parser_concept__] | |
809 | ||
810 | [variablelist Notation | |
811 | [[`a`] [A __parser_concept__.]] | |
812 | [[`t`] [A container of type `T`.]] | |
813 | [[`attr`] [The attribute supplied to the directive.]] | |
814 | ] | |
815 | ||
816 | [heading Expression Semantics] | |
817 | ||
818 | Semantics of an expression is defined only where it differs from, or is | |
819 | not defined in __unary_parser_concept__. | |
820 | ||
821 | [table | |
822 | [[Expression] [Semantics]] | |
823 | [[`as<T>()[a]`] [Create a temporary object of `t` of type `T`, | |
824 | and invoke the subject parser `a`, supplying | |
825 | `t` as an attribute. If the subject parser | |
826 | passes, assign `t` to `attr`.]] | |
827 | [[`as_string[a]`] [Equivalent to `as<std::string>()[a]`]] | |
828 | [[`as_wstring[a]`] [Equivalent to `as<std::wstring>()[a]`]] | |
829 | ] | |
830 | ||
831 | [heading Attributes] | |
832 | ||
833 | See __qi_comp_attr_notation__. | |
834 | ||
835 | [table | |
836 | [[Expression] [Attribute]] | |
837 | [[`as<T>()[a]`] [`a: A --> as<T>()[a]: T`]] | |
838 | ] | |
839 | ||
840 | [heading Complexity] | |
841 | ||
842 | [:The complexity is defined by the complexity of the subject parser, `a`, and | |
843 | the complexity of the assignment of the container `t` to the supplied | |
844 | attribute `attr`.] | |
845 | ||
846 | [heading Example] | |
847 | ||
848 | [note The test harness for the example(s) below is presented in the | |
849 | __qi_basics_examples__ section.] | |
850 | ||
851 | Some using declarations: | |
852 | ||
853 | [reference_using_declarations_as] | |
854 | ||
855 | Simple usage of `as<T>`, `as_string` and `as_wstring`: | |
856 | ||
857 | [reference_as] | |
858 | ||
859 | [endsect] | |
860 | ||
861 | [endsect] |