]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/repository/doc/qi/confix.qbk
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / repository / doc / qi / confix.qbk
1 [/==============================================================================
2 Copyright (C) 2001-2011 Hartmut Kaiser
3 Copyright (C) 2001-2011 Joel de Guzman
4 Copyright (C) 2009 Chris Hoeppler
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:confix Qi Confix Parser Directive]
11
12 [heading Description]
13
14 The __qi__ `confix` directive is a unary parser component allowing to embed a
15 parser (the subject) inside an opening (the prefix) and a closing (the suffix):
16
17 confix(prefix, suffix)[subject]
18
19 This results in a parser that is equivalent to the sequence
20
21 omit[prefix] >> subject >> omit[suffix]
22
23 A simple example is a parser for non-nested comments which can now be written
24 as:
25
26 confix("/*", "*/")[*(char_ - "*/")] // C style comment
27 confix("//", eol)[*(char_ - eol)] // C++ style comment
28
29 Using the `confix` directive instead of the explicit sequence has the advantage
30 of being able to encapsulate the prefix and the suffix into a separate construct.
31 The following code snippet illustrates the idea:
32
33 namespace spirit = boost::spirit;
34 namespace repo = boost::spirit::repository;
35
36 // Define a metafunction allowing to compute the type
37 // of the confix() construct
38 template <typename Prefix, typename Suffix = Prefix>
39 struct confix_spec
40 {
41 typedef typename spirit::result_of::terminal<
42 repo::tag::confix(Prefix, Suffix)
43 >::type type;
44 };
45
46 confix_spec<std::string>::type const c_comment = repo::confix("/*", "*/");
47 confix_spec<std::string>::type const cpp_comment = repo::confix("//", "\n");
48
49 Now, the comment parsers can be written as
50
51 c_comment[*(char_ - "*/")] // C style comment
52 cpp_comment[*(char_ - eol)] // C++ style comment
53
54 [note While the `confix_p(prefix, subject, suffix)` parser in __classic__
55 was equivalent to the sequence `prefix >> *(subject - suffix) >> suffix,
56 the __qi__ `confix` directive will not perform this refactoring any more.
57 This simplifies the code and makes things more explicit.]
58
59 [heading Header]
60
61 // forwards to <boost/spirit/repository/home/qi/directive/confix.hpp>
62 #include <boost/spirit/repository/include/qi_confix.hpp>
63
64 [heading Synopsis]
65
66 confix(prefix, suffix)[subject]
67
68 [heading Parameters]
69
70 [table
71 [[Parameter] [Description]]
72 [[`prefix`] [The parser for the opening (the prefix).]]
73 [[`suffix`] [The parser for the ending (the suffix).]]
74 [[`subject`] [The parser for the input sequence between the
75 `prefix` and `suffix` parts.]]
76 ]
77
78 All three parameters can be arbitrarily complex parsers themselves.
79
80 [heading Attribute]
81
82 The `confix` directive exposes the attribute type of its subject as its own
83 attribute type. If the `subject` does not expose any attribute (the type is
84 `unused_type`), then the `confix` does not expose any attribute either.
85
86 a: A, p: P, s: S: --> confix(p, s)[a]: A
87
88 [note This notation is used all over the Spirit documentation and reads as:
89 Given, `a`, `p`, and `s` are parsers, and `A`, `P`, and `S` are the types
90 of their attributes, then the type of the attribute exposed by
91 `confix(p, s)[a]` will be `A`.]
92
93 [heading Example]
94
95 The following example shows simple use cases of the `confix` directive. We will
96 illustrate its usage by generating parsers for different comment styles and
97 for some simple tagged data (for the full example code see
98 [@../../example/qi/confix.cpp confix.cpp])
99
100 [import ../example/qi/confix.cpp]
101
102 [heading Prerequisites]
103
104 In addition to the main header file needed to include the core components
105 implemented in __qi__ we add the header file needed for the new `confix`
106 directive.
107
108 [qi_confix_includes]
109
110 In order to make the examples below more readable we import a number of
111 elements into the current namespace:
112
113 [qi_confix_using]
114
115 [heading Parsing Different Comment Styles]
116
117 We will show how to parse different comment styles. First we will parse
118 a C++ comment:
119
120 [qi_confix_cpp_comment]
121
122 This function will obviously parse input such as "`// This is a comment \n `".
123 Similarily parsing a 'C'-style comment proves to be straightforward:
124
125 [qi_confix_c_comment]
126
127 which again will be able to parse e.g. "`/* This is a comment */ `".
128
129 [heading Parsing Tagged Data]
130
131 Generating a parser that extracts the body from the HTML snippet "`<b>The Body</b>`"
132 is not very hard, either:
133
134 [qi_confix_tagged_data]
135
136
137 [endsect]