Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/spirit/home/classic/utility/rule_parser.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
14 // About: | 14 // About: |
15 // ===== | 15 // ===== |
16 // | 16 // |
17 // Using a typeof operator or Boost.Typeof to automatically set the type of | 17 // Using a typeof operator or Boost.Typeof to automatically set the type of |
18 // variables (as done in the Spirit example demonstrating typeof) is by far not | 18 // variables (as done in the Spirit example demonstrating typeof) is by far not |
19 // all we can do to tighten up our grammars as there are some significant | 19 // all we can do to tighten up our grammars as there are some significant |
20 // drawbacks of this approach: | 20 // drawbacks of this approach: |
21 // - the types complexity scales with the complexity of the grammar (sooner or | 21 // - the types complexity scales with the complexity of the grammar (sooner or |
22 // later hitting the limits of the compiler), | 22 // later hitting the limits of the compiler), |
23 // - recursive grammars are not possible, and | 23 // - recursive grammars are not possible, and |
24 // - all parser objects are embedded by value. | 24 // - all parser objects are embedded by value. |
30 // http://www.boost.org/libs/spirit/doc/techniques.html#typeof | 30 // http://www.boost.org/libs/spirit/doc/techniques.html#typeof |
31 // | 31 // |
32 // In practice manually applying this technique leads to rather lengthy code and | 32 // In practice manually applying this technique leads to rather lengthy code and |
33 // overthis requires the user to have a solid understanding of Spirit details. | 33 // overthis requires the user to have a solid understanding of Spirit details. |
34 // | 34 // |
35 // Here is a generalized, macro-based approach to easily create typeof-based | 35 // Here is a generalized, macro-based approach to easily create typeof-based |
36 // grammars that can be recursive and arbitrarily complex. | 36 // grammars that can be recursive and arbitrarily complex. |
37 // | 37 // |
38 // | 38 // |
39 // Quick manual: | 39 // Quick manual: |
40 // ============ | 40 // ============ |
41 // | 41 // |
42 // 1. Setup | 42 // 1. Setup |
43 // | 43 // |
44 // Before the rule parser macro (the protagonist of the facility) can be used | 44 // Before the rule parser macro (the protagonist of the facility) can be used |
45 // the the user must define the macro BOOST_SPIRIT__NAMESPACE (note the double | 45 // the user must define the macro BOOST_SPIRIT__NAMESPACE (note the double |
46 // underscore characeter) and setup a registration group for Boost.Typeof. | 46 // underscore characeter) and setup a registration group for Boost.Typeof. |
47 // | 47 // |
48 // Examples: | 48 // Examples: |
49 // | 49 // |
50 // // should come after regular #includeS | 50 // // should come after regular #includeS |
51 // #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() | 51 // #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() |
52 // | 52 // |
53 // // [...] | 53 // // [...] |
54 // | 54 // |
55 // #define BOOST_SPIRIT__NAMESPACE (2,(my_project, my_module)) | 55 // #define BOOST_SPIRIT__NAMESPACE (2,(my_project, my_module)) |
56 // // | | +- outer +- inner | 56 // // | | +- outer +- inner |
57 // // ! space ! -+ | namespace namespace | 57 // // ! space ! -+ | namespace namespace |
58 // // | | 58 // // | |
59 // // +--- number of nested namespaces | 59 // // +--- number of nested namespaces |
60 // | 60 // |
61 // namespace my_project { namespace my_module { | 61 // namespace my_project { namespace my_module { |
62 // | 62 // |
63 // // [...] | 63 // // [...] |
64 // | 64 // |
65 // --- | 65 // --- |
66 // | 66 // |
67 // // should come after regular #includeS | 67 // // should come after regular #includeS |
68 // #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() | 68 // #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() |
69 // | 69 // |
70 // // [...] | 70 // // [...] |
71 // | 71 // |
72 // #define BOOST_SPIRIT__NAMESPACE (2,(my_project, (anonymous) )) | 72 // #define BOOST_SPIRIT__NAMESPACE (2,(my_project, (anonymous) )) |
73 // | 73 // |
74 // namespace my_project { namespace { | 74 // namespace my_project { namespace { |
75 // | 75 // |
76 // // [...] | 76 // // [...] |
77 // | 77 // |
78 // --- | 78 // --- |
79 // | 79 // |
80 // // should come after regular #includeS | 80 // // should come after regular #includeS |
81 // #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() | 81 // #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() |
82 // | 82 // |
83 // // [...] | 83 // // [...] |
84 // | 84 // |
85 // | 85 // |
86 // #define BOOST_SPIRIT__NAMESPACE - | 86 // #define BOOST_SPIRIT__NAMESPACE - |
87 // // we're working at root namespace | 87 // // we're working at root namespace |
88 // | 88 // |
89 // | 89 // |
90 // Why do I have to do this? | 90 // Why do I have to do this? |
91 // | 91 // |
92 // Boost.Typeof needs to assign a unique ID for each registration. This ID is | 92 // Boost.Typeof needs to assign a unique ID for each registration. This ID is |
93 // created composed of the line number and the registration group. The | 93 // created composed of the line number and the registration group. The |
94 // facility performs Typeof registration and thus requires the source file to | 94 // facility performs Typeof registration and thus requires the source file to |
95 // have its own registration group. Further Boost.Typeof requires registration | 95 // have its own registration group. Further Boost.Typeof requires registration |
96 // to happen at root namespace so we have to close and reopen the namespace | 96 // to happen at root namespace so we have to close and reopen the namespace |
97 // we're in. | 97 // we're in. |
98 // | 98 // |
99 // | 99 // |
100 // 2. The rule parser macro | 100 // 2. The rule parser macro |
101 // | 101 // |
102 // A simple rule parser definition looks like that: | 102 // A simple rule parser definition looks like that: |
103 // | 103 // |
104 // // we're at namespace scope here | 104 // // we're at namespace scope here |
105 // | 105 // |
106 // // Skip parser for C/C++ comments and whitespace | 106 // // Skip parser for C/C++ comments and whitespace |
107 // BOOST_SPIRIT_RULE_PARSER(skipper, | 107 // BOOST_SPIRIT_RULE_PARSER(skipper, |
108 // -,-,-, | 108 // -,-,-, |
109 // | 109 // |
110 // +( confix_p("//",*anychar_p,eol_p) | 110 // +( confix_p("//",*anychar_p,eol_p) |
111 // | confix_p("/*",*anychar_p,"*/") | 111 // | confix_p("/*",*anychar_p,"*/") |
112 // | space_p | 112 // | space_p |
113 // ) | 113 // ) |
114 // ) | 114 // ) |
115 // | 115 // |
116 // Now we can use 'skipper' in other Spirit expressions. | 116 // Now we can use 'skipper' in other Spirit expressions. |
117 // | 117 // |
118 // The code above creates a parser (template) class 'skpper_t' and (in this | 118 // The code above creates a parser (template) class 'skpper_t' and (in this |
119 // case, because there are no parameters) a static const instance 'skipper' of | 119 // case, because there are no parameters) a static const instance 'skipper' of |
120 // that class. The class is automatically registered with Boost.Typeof. The type | 120 // that class. The class is automatically registered with Boost.Typeof. The type |
121 // name our parser is skipper_t here. | 121 // name our parser is skipper_t here. |
122 // | 122 // |
123 // | 123 // |
124 // 2.1. Parametrized rule parsers | 124 // 2.1. Parametrized rule parsers |
125 // | 125 // |
126 // Rule parser definitions can have parameters. | 126 // Rule parser definitions can have parameters. |
127 // | 127 // |
128 // Parameters are passed to the BOOST_SPIRIT_RULE_PARSER macro as its second | 128 // Parameters are passed to the BOOST_SPIRIT_RULE_PARSER macro as its second |
129 // argument (just pass '-' if there are no parameters) with the following | 129 // argument (just pass '-' if there are no parameters) with the following |
130 // format: | 130 // format: |
131 // | 131 // |
132 // (N,( param1,param2, / ... / paramN )) | 132 // (N,( param1,param2, / ... / paramN )) |
133 // +-- number of parameters | 133 // +-- number of parameters |
134 // | 134 // |
135 // Example of a whole rule parser: | 135 // Example of a whole rule parser: |
136 // | 136 // |
137 // BOOST_SPIRIT_RULE_PARSER(new_name, | 137 // BOOST_SPIRIT_RULE_PARSER(new_name, |
138 // (1,( symbol_table )),-,-, | 138 // (1,( symbol_table )),-,-, |
139 // | 139 // |
140 // lexeme_d[ (alpha_p >> *alnum_p)[ symbol_table.add ] ] | 140 // lexeme_d[ (alpha_p >> *alnum_p)[ symbol_table.add ] ] |
141 // ) | 141 // ) |
142 // | 142 // |
143 // The expression 'new_name(my_symbols)' parses a string literal and adds it to | 143 // The expression 'new_name(my_symbols)' parses a string literal and adds it to |
144 // the symbol table 'my_symbols'. | 144 // the symbol table 'my_symbols'. |
145 // | 145 // |
146 // The rule parser macro creates a function template as called 'new_name' that | 146 // The rule parser macro creates a function template as called 'new_name' that |
147 // takes one parameter of deduced reference type and returns a specialization of | 147 // takes one parameter of deduced reference type and returns a specialization of |
148 // 'new_name_t' in this case. | 148 // 'new_name_t' in this case. |
149 // | 149 // |
150 // Since parsers that require to be fast and lightweight often also require to | 150 // Since parsers that require to be fast and lightweight often also require to |
151 // be reentrant, it's quite common to pass in some semantic controller (the | 151 // be reentrant, it's quite common to pass in some semantic controller (the |
152 // symbol table in the example above). | 152 // symbol table in the example above). |
153 // However, parameters are templated so they can be anything (including parsers | 153 // However, parameters are templated so they can be anything (including parsers |
154 // of course) so refactoring tasks can be abstracted with rule parsers as well. | 154 // of course) so refactoring tasks can be abstracted with rule parsers as well. |
155 // | 155 // |
156 // BOOST_SPIRIT_RULE_PARSER(enumeration_parser, | 156 // BOOST_SPIRIT_RULE_PARSER(enumeration_parser, |
157 // (2,( element_parser, delimiter_parser )),-,-, | 157 // (2,( element_parser, delimiter_parser )),-,-, |
158 // | 158 // |
159 // element_parser >> *(delimiter_parser >> element_parser) | 159 // element_parser >> *(delimiter_parser >> element_parser) |
160 // ) | 160 // ) |
161 // | 161 // |
162 // The expression 'enumeration_parser(int_p[ some_action ], ',')' creates a | 162 // The expression 'enumeration_parser(int_p[ some_action ], ',')' creates a |
163 // parser for a comma-separated list of integers. | 163 // parser for a comma-separated list of integers. |
164 // | 164 // |
165 // | 165 // |
166 // 2.2. Rule parsrs and semantic actions | 166 // 2.2. Rule parsrs and semantic actions |
167 // | 167 // |
168 // While semantic actions can be globally attached to a rule parser or passed | 168 // While semantic actions can be globally attached to a rule parser or passed |
169 // to a parametrized rule parser as (part of) an argument, even more control is | 169 // to a parametrized rule parser as (part of) an argument, even more control is |
170 // possible by using action placeholders. E.g: | 170 // possible by using action placeholders. E.g: |
171 // | 171 // |
172 // BOOST_SPIRIT_ACTION_PLACEHOLDER(int_action) | 172 // BOOST_SPIRIT_ACTION_PLACEHOLDER(int_action) |
173 // | 173 // |
174 // BOOST_SPIRIT_RULE_PARSER(int_list, | 174 // BOOST_SPIRIT_RULE_PARSER(int_list, |
175 // -,(1,( int_action )),-, | 175 // -,(1,( int_action )),-, |
176 // | 176 // |
177 // int_p[ int_action ] >> *(',' >> int_p[ int_action ]) | 177 // int_p[ int_action ] >> *(',' >> int_p[ int_action ]) |
178 // ) | 178 // ) |
179 // | 179 // |
180 // The expression 'int_list[ my_action ]' parses a comma separated list of | 180 // The expression 'int_list[ my_action ]' parses a comma separated list of |
181 // integers and calls 'my_action' for every integer parsed therein. | 181 // integers and calls 'my_action' for every integer parsed therein. |
182 // | 182 // |
183 // Of course multiple actions can be attached to one placeholder as usual (in | 183 // Of course multiple actions can be attached to one placeholder as usual (in |
184 // this case 'int_list[ my_action1 ][ my_action2 ] would call two actions). | 184 // this case 'int_list[ my_action1 ][ my_action2 ] would call two actions). |
185 // | 185 // |
186 // Further there can be multiple action placeholders for a single rule parser: | 186 // Further there can be multiple action placeholders for a single rule parser: |
187 // | 187 // |
188 // BOOST_SPIRIT_ACTION_PLACEHOLDER(feed_int) | 188 // BOOST_SPIRIT_ACTION_PLACEHOLDER(feed_int) |
189 // BOOST_SPIRIT_ACTION_PLACEHOLDER(next_int) | 189 // BOOST_SPIRIT_ACTION_PLACEHOLDER(next_int) |
190 // | 190 // |
191 // BOOST_SPIRIT_RULE_PARSER(int_list, | 191 // BOOST_SPIRIT_RULE_PARSER(int_list, |
192 // -,(2,( feed_int, next_int )),-, | 192 // -,(2,( feed_int, next_int )),-, |
193 // | 193 // |
194 // int_p[ feed_int ] >> *(',' >> int_p[ next_int ][ feed_int ]) | 194 // int_p[ feed_int ] >> *(',' >> int_p[ next_int ][ feed_int ]) |
195 // ) | 195 // ) |
196 // | 196 // |
197 // The expression 'int_list[ (feed_int = my_action1), (next_int = my_action2) ]' | 197 // The expression 'int_list[ (feed_int = my_action1), (next_int = my_action2) ]' |
198 // creates a parser for a comma separated list of integers with the actions | 198 // creates a parser for a comma separated list of integers with the actions |
199 // attached appropriately. | 199 // attached appropriately. |
200 // | 200 // |
201 // int_list[ feed_int = my_action1,my_action2, next_int = my_action3 ] | 201 // int_list[ feed_int = my_action1,my_action2, next_int = my_action3 ] |
202 // | 202 // |
203 // works too (in this case the action placeholder 'feed_int' has two actions | 203 // works too (in this case the action placeholder 'feed_int' has two actions |
204 // attached to it). | 204 // attached to it). |
205 // | 205 // |
206 // You can both override and append actions associated with an action | 206 // You can both override and append actions associated with an action |
207 // placeholder: | 207 // placeholder: |
208 // | 208 // |
209 // var = int_list[ feed_int = my_action1, next_int = my_action2 ] | 209 // var = int_list[ feed_int = my_action1, next_int = my_action2 ] |
210 // | 210 // |
211 // // [...] | 211 // // [...] |
212 // | 212 // |
213 // ... var[ feed_int = another_action ] | 213 // ... var[ feed_int = another_action ] |
214 // // 'another_action' overrides the actions previously attached to 'feed_int' | 214 // // 'another_action' overrides the actions previously attached to 'feed_int' |
215 // | 215 // |
216 // ... var[ next_int += another_action ] | 216 // ... var[ next_int += another_action ] |
217 // // 'another_action' is appended to the list of actions attached to | 217 // // 'another_action' is appended to the list of actions attached to |
218 // // 'next_int' | 218 // // 'next_int' |
219 // | 219 // |
220 // Action placeholders are not entirely for free -- they add to the size and the | 220 // Action placeholders are not entirely for free -- they add to the size and the |
221 // initialization time of the rule parser. However, the impact on an already | 221 // initialization time of the rule parser. However, the impact on an already |
222 // initialized rule parser instance should be quite small. | 222 // initialized rule parser instance should be quite small. |
223 // | 223 // |
224 // | 224 // |
225 // 2.3. Member variables | 225 // 2.3. Member variables |
226 // | 226 // |
227 // You can add member variables to the rule parser class using the third | 227 // You can add member variables to the rule parser class using the third |
228 // parameter of the rule parser macro: | 228 // parameter of the rule parser macro: |
229 // | 229 // |
230 // BOOST_SPIRIT_RULE_PARSER( calc, | 230 // BOOST_SPIRIT_RULE_PARSER( calc, |
231 // -, | 231 // -, |
232 // -, | 232 // -, |
233 // (3,( ((subrule<0>),expression,()), | 233 // (3,( ((subrule<0>),expression,()), |
234 // ((subrule<1>),term,()), | 234 // ((subrule<1>),term,()), |
235 // ((subrule<2>),factor,() )) ), | 235 // ((subrule<2>),factor,() )) ), |
236 // | 236 // |
237 // // [...] | 237 // // [...] |
238 // | 238 // |
239 // adds three subrules to the rule parser. | 239 // adds three subrules to the rule parser. |
240 // Each parameter must have the following type to allow commas to be handled | 240 // Each parameter must have the following type to allow commas to be handled |
241 // safely from within the preprocessing code: | 241 // safely from within the preprocessing code: |
242 // | 242 // |
243 // ((type)),name,(constructor argument(s))) | 243 // ((type)),name,(constructor argument(s))) |
244 // | 244 // |
245 // | 245 // |
246 // 2.4. The opaque rule parser | 246 // 2.4. The opaque rule parser |
247 // | 247 // |
248 // Rule parsers usually are templates. Building large grammars pushes the | 248 // Rule parsers usually are templates. Building large grammars pushes the |
249 // compiler really hard (and eventually to its limits) because of the | 249 // compiler really hard (and eventually to its limits) because of the |
250 // metafunction complexity involved. | 250 // metafunction complexity involved. |
251 // If a rule parser without parameters and action placeholders is defined, a | 251 // If a rule parser without parameters and action placeholders is defined, a |
252 // non-template class is created. Non-templated rule parsers can also be created | 252 // non-template class is created. Non-templated rule parsers can also be created |
253 // explicitly by using BOOST_SPIRIT_OPAQUE_RULE_PARSER. | 253 // explicitly by using BOOST_SPIRIT_OPAQUE_RULE_PARSER. |
254 // Opaque rule parsers can have parameters and member variables (note: no action | 254 // Opaque rule parsers can have parameters and member variables (note: no action |
255 // placeholders are possible). The parameters of an opaque rule parsers are | 255 // placeholders are possible). The parameters of an opaque rule parsers are |
256 // strictly typed, e.g: | 256 // strictly typed, e.g: |
257 // | 257 // |
258 // BOOST_SPIRIT_OPAQUE_RULE_PARSER(new_identifier, | 258 // BOOST_SPIRIT_OPAQUE_RULE_PARSER(new_identifier, |
259 // (1,( ((my_symbol_table_t &),symbol_table) )) | 259 // (1,( ((my_symbol_table_t &),symbol_table) )) |
260 // ,-, | 260 // ,-, |
261 // (alpha_p >> *alnum_p) [ symbol_table.add ] | 261 // (alpha_p >> *alnum_p) [ symbol_table.add ] |
262 // ) | 262 // ) |
263 // | 263 // |
264 // Note it's also possible to have opaque rule parsers accept parameters of | 264 // Note it's also possible to have opaque rule parsers accept parameters of |
265 // non-const reference types which is not possible with regular rule parsers. | 265 // non-const reference types which is not possible with regular rule parsers. |
266 // | 266 // |
267 // | 267 // |
268 // 3. Utilities for by-reference embedding | 268 // 3. Utilities for by-reference embedding |
269 // | 269 // |
270 // When using parsers mutiple times or recursively it can be helpful to embed | 270 // When using parsers mutiple times or recursively it can be helpful to embed |
271 // them by-reference into the final parser expression. | 271 // them by-reference into the final parser expression. |
272 // For this purpose the library provides a wrapper template 'parser_reference'. | 272 // For this purpose the library provides a wrapper template 'parser_reference'. |
273 // There is also a function template to create a wrapped parser which can deduce | 273 // There is also a function template to create a wrapped parser which can deduce |
274 // the parser's type from its argument. | 274 // the parser's type from its argument. |
275 // | 275 // |
347 //============================================================================== | 347 //============================================================================== |
348 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() | 348 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() |
349 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 349 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
350 // RP_REGISTER_TEMPLATE | 350 // RP_REGISTER_TEMPLATE |
351 // | 351 // |
352 // Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE | 352 // Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE |
353 # define BOOST_SPIRIT_RP_REGISTER_TEMPLATE(name,params) \ | 353 # define BOOST_SPIRIT_RP_REGISTER_TEMPLATE(name,params) \ |
354 BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \ | 354 BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \ |
355 BOOST_TYPEOF_REGISTER_TEMPLATE( \ | 355 BOOST_TYPEOF_REGISTER_TEMPLATE( \ |
356 BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name, \ | 356 BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name, \ |
357 params) \ | 357 params) \ |
358 BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-) | 358 BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-) |
359 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 359 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
360 // RP_REGISTER_TYPE | 360 // RP_REGISTER_TYPE |
361 // | 361 // |
362 // Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE | 362 // Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE |
363 # define BOOST_SPIRIT_RP_REGISTER_TYPE(name) \ | 363 # define BOOST_SPIRIT_RP_REGISTER_TYPE(name) \ |
364 BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \ | 364 BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \ |
365 BOOST_TYPEOF_REGISTER_TYPE( \ | 365 BOOST_TYPEOF_REGISTER_TYPE( \ |
366 BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name ) \ | 366 BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name ) \ |
367 BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-) | 367 BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-) |
368 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 368 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
369 // RP_AP_IMPL | 369 // RP_AP_IMPL |
370 // | 370 // |
371 // The action placeholder definition | 371 // The action placeholder definition |
372 # define BOOST_SPIRIT_RP_AP_IMPL(name,ns) \ | 372 # define BOOST_SPIRIT_RP_AP_IMPL(name,ns) \ |
383 ns :: action_chain< name, ns :: append, Action> \ | 383 ns :: action_chain< name, ns :: append, Action> \ |
384 operator+=(Action const & __a) const \ | 384 operator+=(Action const & __a) const \ |
385 { return ns :: action_chain< name, ns :: append, Action> (__a); } \ | 385 { return ns :: action_chain< name, ns :: append, Action> (__a); } \ |
386 }; \ | 386 }; \ |
387 } \ | 387 } \ |
388 __action_placeholder:: name const name = __action_placeholder:: name (); | 388 __action_placeholder:: name const name = __action_placeholder:: name (); |
389 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 389 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
390 // RP_IMPL_I | 390 // RP_IMPL_I |
391 // | 391 // |
392 // Does some precalculation so RP_IMPL_II can look cleaner | 392 // Does some precalculation so RP_IMPL_II can look cleaner |
393 # define BOOST_SPIRIT_RP_IMPL_I(name,pars,acts,mbrs,expr) \ | 393 # define BOOST_SPIRIT_RP_IMPL_I(name,pars,acts,mbrs,expr) \ |
407 // The rule parser definition | 407 // The rule parser definition |
408 # define BOOST_SPIRIT_RP_IMPL_III(name,name_t,pars,np,acts,na,mbrs,nm,x) \ | 408 # define BOOST_SPIRIT_RP_IMPL_III(name,name_t,pars,np,acts,na,mbrs,nm,x) \ |
409 \ | 409 \ |
410 template< BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,typename __,1) > \ | 410 template< BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,typename __,1) > \ |
411 class name_t \ | 411 class name_t \ |
412 : public ::BOOST_SPIRIT_CLASSIC_NS::parser< name_t \ | 412 : public ::BOOST_SPIRIT_CLASSIC_NS::parser< name_t \ |
413 < BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,__,0) > > \ | 413 < BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,__,0) > > \ |
414 { \ | 414 { \ |
415 class __rule \ | 415 class __rule \ |
416 { \ | 416 { \ |
417 BOOST_SPIRIT_RP_EMIT(PM_STATIC,pars,__T) \ | 417 BOOST_SPIRIT_RP_EMIT(PM_STATIC,pars,__T) \ |
418 BOOST_SPIRIT_RP_EMIT(AP_STATIC,acts,-) \ | 418 BOOST_SPIRIT_RP_EMIT(AP_STATIC,acts,-) \ |
419 BOOST_SPIRIT_RP_EMIT(MV_STATIC,mbrs,BOOST_PP_IDENTITY(typename)) \ | 419 BOOST_SPIRIT_RP_EMIT(MV_STATIC,mbrs,BOOST_PP_IDENTITY(typename)) \ |
420 public: \ | 420 public: \ |
421 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(__expr, \ | 421 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(__expr, \ |
422 ::BOOST_SPIRIT_CLASSIC_NS::type_of::depend_on_type<__Dummy>(x) ) \ | 422 ::BOOST_SPIRIT_CLASSIC_NS::type_of::depend_on_type<__Dummy>(x) ) \ |
423 }; \ | 423 }; \ |
424 \ | 424 \ |
425 public: \ | 425 public: \ |
426 \ | 426 \ |
427 typedef name_t self_t; \ | 427 typedef name_t self_t; \ |
469 }; \ | 469 }; \ |
470 \ | 470 \ |
471 BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_FUNC,BOOST_SPIRIT_RP_GLOB_VAR) \ | 471 BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_FUNC,BOOST_SPIRIT_RP_GLOB_VAR) \ |
472 (name,name_t,np,na) \ | 472 (name,name_t,np,na) \ |
473 BOOST_SPIRIT_RP_REGISTER_TEMPLATE \ | 473 BOOST_SPIRIT_RP_REGISTER_TEMPLATE \ |
474 (name_t,BOOST_PP_INC(BOOST_PP_ADD(np,na))) | 474 (name_t,BOOST_PP_INC(BOOST_PP_ADD(np,na))) |
475 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 475 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
476 // RP_OPAQUE_IMPL_I | 476 // RP_OPAQUE_IMPL_I |
477 // | 477 // |
478 # define BOOST_SPIRIT_RP_OPAQUE_IMPL_I(name,pars,mbrs,expr) \ | 478 # define BOOST_SPIRIT_RP_OPAQUE_IMPL_I(name,pars,mbrs,expr) \ |
479 BOOST_SPIRIT_RP_OPAQUE_IMPL_II(name, name ## _t, \ | 479 BOOST_SPIRIT_RP_OPAQUE_IMPL_II(name, name ## _t, \ |
534 }; \ | 534 }; \ |
535 \ | 535 \ |
536 BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_OPAQUE,BOOST_SPIRIT_RP_GLOB_OPAQUE) \ | 536 BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_OPAQUE,BOOST_SPIRIT_RP_GLOB_OPAQUE) \ |
537 (name,name_t,np,pars) | 537 (name,name_t,np,pars) |
538 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 538 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
539 // RP_AP_HANDLER | 539 // RP_AP_HANDLER |
540 // | 540 // |
541 // Part of the rule parser definition for handling action placeholders | 541 // Part of the rule parser definition for handling action placeholders |
542 # define BOOST_SPIRIT_RP_AP_HANDLER(name_t,np,acts,na,ns) \ | 542 # define BOOST_SPIRIT_RP_AP_HANDLER(name_t,np,acts,na,ns) \ |
543 private: \ | 543 private: \ |
544 template<typename A> struct __rebound_1st \ | 544 template<typename A> struct __rebound_1st \ |
588 // | 588 // |
589 // Extra members we need for rebinding if there are action placeholders | 589 // Extra members we need for rebinding if there are action placeholders |
590 # define BOOST_SPIRIT_RP_AP_EXTRA_MBRS(np,na) \ | 590 # define BOOST_SPIRIT_RP_AP_EXTRA_MBRS(np,na) \ |
591 private: \ | 591 private: \ |
592 BOOST_PP_REPEAT(np,BOOST_SPIRIT_RP_PM_MBRS,-) \ | 592 BOOST_PP_REPEAT(np,BOOST_SPIRIT_RP_PM_MBRS,-) \ |
593 BOOST_PP_REPEAT(na,BOOST_SPIRIT_RP_AP_MBRS,-) | 593 BOOST_PP_REPEAT(na,BOOST_SPIRIT_RP_AP_MBRS,-) |
594 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 594 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
595 // RP_PM_MBRS | 595 // RP_PM_MBRS |
596 // | 596 // |
597 // Member variables to remember parameters if there are action placeholder | 597 // Member variables to remember parameters if there are action placeholder |
598 # define BOOST_SPIRIT_RP_PM_MBRS(z,i,d) __T ## i __p ## i ; | 598 # define BOOST_SPIRIT_RP_PM_MBRS(z,i,d) __T ## i __p ## i ; |
615 # define BOOST_SPIRIT_RP_CTOR_COMMA(what,pars,np,acts) \ | 615 # define BOOST_SPIRIT_RP_CTOR_COMMA(what,pars,np,acts) \ |
616 BOOST_SPIRIT_RP_CTOR(what,pars,np,acts) , | 616 BOOST_SPIRIT_RP_CTOR(what,pars,np,acts) , |
617 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 617 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
618 // RP_TPL_PARAMS | 618 // RP_TPL_PARAMS |
619 // | 619 // |
620 // Expands to the template parameters or arguments of the rule parser template | 620 // Expands to the template parameters or arguments of the rule parser template |
621 # define BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,prefix,defaults) \ | 621 # define BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,prefix,defaults) \ |
622 prefix ## Dummy \ | 622 prefix ## Dummy \ |
623 BOOST_SPIRIT_RP_EMIT(PM_TEMPLATE_PARAMS,pars,prefix ## T) \ | 623 BOOST_SPIRIT_RP_EMIT(PM_TEMPLATE_PARAMS,pars,prefix ## T) \ |
624 BOOST_SPIRIT_RP_EMIT(AP_TEMPLATE_PARAMS,acts,(prefix ## A,defaults)) | 624 BOOST_SPIRIT_RP_EMIT(AP_TEMPLATE_PARAMS,acts,(prefix ## A,defaults)) |
625 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 625 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
677 static typename ::boost::call_traits< data ## i >::reference elem ; | 677 static typename ::boost::call_traits< data ## i >::reference elem ; |
678 | 678 |
679 // PM_CTOR_PARAMS | 679 // PM_CTOR_PARAMS |
680 # define BOOST_SPIRIT_RP__PM_CTOR_PARAMS(r,data,i,elem) \ | 680 # define BOOST_SPIRIT_RP__PM_CTOR_PARAMS(r,data,i,elem) \ |
681 BOOST_PP_COMMA_IF(i) \ | 681 BOOST_PP_COMMA_IF(i) \ |
682 typename ::boost::call_traits< data ## i >::param_type elem | 682 typename ::boost::call_traits< data ## i >::param_type elem |
683 | 683 |
684 // PM_CTOR_ARGS | 684 // PM_CTOR_ARGS |
685 # define BOOST_SPIRIT_RP__PM_CTOR_ARGS(r,data,i,elem) \ | 685 # define BOOST_SPIRIT_RP__PM_CTOR_ARGS(r,data,i,elem) \ |
686 BOOST_PP_COMMA_IF(i) elem | 686 BOOST_PP_COMMA_IF(i) elem |
687 | 687 |
775 ( __a ## i , data ) | 775 ( __a ## i , data ) |
776 | 776 |
777 // AP_REBOUND_TPL_ARGS | 777 // AP_REBOUND_TPL_ARGS |
778 # define BOOST_SPIRIT_RP__AP_REBOUND_TPL_ARGS(r,data,i,elem) \ | 778 # define BOOST_SPIRIT_RP__AP_REBOUND_TPL_ARGS(r,data,i,elem) \ |
779 , typename ::BOOST_SPIRIT_CLASSIC_NS::type_of::placeholdee< \ | 779 , typename ::BOOST_SPIRIT_CLASSIC_NS::type_of::placeholdee< \ |
780 __action_placeholder:: elem , __A ## i, data >::type | 780 __action_placeholder:: elem , __A ## i, data >::type |
781 | 781 |
782 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 782 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
783 // PP_EMIT | 783 // PP_EMIT |
784 // | 784 // |
785 // Performs one of the operations in the above section on an optional array. | 785 // Performs one of the operations in the above section on an optional array. |
786 // | 786 // |
787 # define BOOST_SPIRIT_RP_EMIT(op, array, data) \ | 787 # define BOOST_SPIRIT_RP_EMIT(op, array, data) \ |
788 BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I(BOOST_SPIRIT_RP__ ## op,data,array) | 788 BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I(BOOST_SPIRIT_RP__ ## op,data,array) |
789 // --- --- - - --- - - --- - - - - --- - - - - - - - - - - - - - - - - - - - - - | 789 // --- --- - - --- - - --- - - - - --- - - - - - - - - - - - - - - - - - - - - - |
790 // RP_ARRAY_FOR_EACH_I | 790 // RP_ARRAY_FOR_EACH_I |
791 // | 791 // |
792 // Iterates an optional array. That is you can pass e.g.'-' or 'none' to denote | 792 // Iterates an optional array. That is you can pass e.g.'-' or 'none' to denote |
793 // emptiness. | 793 // emptiness. |
794 # define BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I(macro,data,optional_array) \ | 794 # define BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I(macro,data,optional_array) \ |
795 BOOST_PP_IIF(BOOST_PP_IS_BINARY(optional_array), \ | 795 BOOST_PP_IIF(BOOST_PP_IS_BINARY(optional_array), \ |
796 BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I_IMPL, \ | 796 BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I_IMPL, \ |
797 BOOST_PP_TUPLE_EAT(3))(macro,data,optional_array) | 797 BOOST_PP_TUPLE_EAT(3))(macro,data,optional_array) |
798 | 798 |
799 // RP_ARRAY_FOR_EACH_I_IMPL | 799 // RP_ARRAY_FOR_EACH_I_IMPL |
800 # define BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I_IMPL(macro,data,array) \ | 800 # define BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I_IMPL(macro,data,array) \ |
801 BOOST_SPIRIT_RP_IF(BOOST_PP_ARRAY_SIZE(array),PP_SEQ_FOR_EACH_I,3) \ | 801 BOOST_SPIRIT_RP_IF(BOOST_PP_ARRAY_SIZE(array),PP_SEQ_FOR_EACH_I,3) \ |
802 (macro,data, BOOST_SPIRIT_RP_IF(BOOST_PP_ARRAY_SIZE(array), \ | 802 (macro,data, BOOST_SPIRIT_RP_IF(BOOST_PP_ARRAY_SIZE(array), \ |
803 PP_TUPLE_TO_SEQ,2) array) | 803 PP_TUPLE_TO_SEQ,2) array) |
804 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 804 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
805 // RP_ARRAY_SIZE | 805 // RP_ARRAY_SIZE |
806 // | 806 // |
807 // Expands to the size of an "optional array". | 807 // Expands to the size of an "optional array". |
808 // | 808 // |
809 // Examples: | 809 // Examples: |
810 // | 810 // |
816 # define BOOST_SPIRIT_RP_ARRAY_SIZE(optional_array) \ | 816 # define BOOST_SPIRIT_RP_ARRAY_SIZE(optional_array) \ |
817 BOOST_PP_IIF(BOOST_PP_IS_BINARY(optional_array), \ | 817 BOOST_PP_IIF(BOOST_PP_IS_BINARY(optional_array), \ |
818 BOOST_PP_ARRAY_SIZE, 0 BOOST_PP_TUPLE_EAT(1))(optional_array) | 818 BOOST_PP_ARRAY_SIZE, 0 BOOST_PP_TUPLE_EAT(1))(optional_array) |
819 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 819 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
820 // RP_OPTIONAL | 820 // RP_OPTIONAL |
821 // | 821 // |
822 // Expands to nothing if the argument is parenthesized. | 822 // Expands to nothing if the argument is parenthesized. |
823 // | 823 // |
824 // Examples: | 824 // Examples: |
825 // | 825 // |
826 // BOOST_SPIRIT_RP_OPTIONAL( foobar ) // foobar | 826 // BOOST_SPIRIT_RP_OPTIONAL( foobar ) // foobar |
827 // BOOST_SPIRIT_RP_OPTIONAL( (none) ) // evaluates to nothing | 827 // BOOST_SPIRIT_RP_OPTIONAL( (none) ) // evaluates to nothing |
828 // | 828 // |
829 # define BOOST_SPIRIT_RP_OPTIONAL(elem) \ | 829 # define BOOST_SPIRIT_RP_OPTIONAL(elem) \ |
830 BOOST_PP_EXPR_IIF(BOOST_PP_COMPL(BOOST_PP_IS_UNARY(elem)),elem) | 830 BOOST_PP_EXPR_IIF(BOOST_PP_COMPL(BOOST_PP_IS_UNARY(elem)),elem) |
831 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 831 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
832 // RP_COMMA_IF_OR | 832 // RP_COMMA_IF_OR |
833 // | 833 // |
834 // Expands to nothing if both arguments are zero, otherwise expands to a comma. | 834 // Expands to nothing if both arguments are zero, otherwise expands to a comma. |
835 // | 835 // |
849 | 849 |
850 //------------------------------------------------------------------------------ | 850 //------------------------------------------------------------------------------ |
851 // Wrapper and gernator function to embed a parser by reference | 851 // Wrapper and gernator function to embed a parser by reference |
852 //------------------------------------------------------------------------------ | 852 //------------------------------------------------------------------------------ |
853 | 853 |
854 namespace boost { namespace spirit { | 854 namespace boost { namespace spirit { |
855 | 855 |
856 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | 856 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN |
857 | 857 |
858 // Wrapper to embed a parser by reference | 858 // Wrapper to embed a parser by reference |
859 | 859 |
860 template<class P> class parser_reference | 860 template<class P> class parser_reference |
861 : public parser< parser_reference<P> > | 861 : public parser< parser_reference<P> > |
862 { | 862 { |
863 P const & ref_that; | 863 P const & ref_that; |
864 public: | 864 public: |
865 parser_reference(P & that) | 865 parser_reference(P & that) |
866 // we allow implicit conversion but forbid temporaries. | 866 // we allow implicit conversion but forbid temporaries. |
867 : ref_that(that) | 867 : ref_that(that) |
868 { } | 868 { } |
869 | 869 |
870 typedef parser_reference<P> self_t; | 870 typedef parser_reference<P> self_t; |
871 typedef self_t const & embed_t; | 871 typedef self_t const & embed_t; |
872 typedef typename P::parser_category_t parser_category_t; | 872 typedef typename P::parser_category_t parser_category_t; |
873 | 873 |
874 template<typename ScannerT> struct result | 874 template<typename ScannerT> struct result |
875 { typedef typename P::BOOST_NESTED_TEMPLATE result<ScannerT>::type type; }; | 875 { typedef typename P::BOOST_NESTED_TEMPLATE result<ScannerT>::type type; }; |
876 | 876 |
877 template<typename ScannerT> | 877 template<typename ScannerT> |
878 typename result<ScannerT>::type | 878 typename result<ScannerT>::type |
879 parse(ScannerT const & scan) const | 879 parse(ScannerT const & scan) const |
880 { return this->ref_that.parse(scan); } | 880 { return this->ref_that.parse(scan); } |
881 }; | 881 }; |
882 | 882 |
883 template<class P> parser_reference<P> | 883 template<class P> parser_reference<P> |
884 embed_by_reference(::BOOST_SPIRIT_CLASSIC_NS::parser<P> & p) | 884 embed_by_reference(::BOOST_SPIRIT_CLASSIC_NS::parser<P> & p) |
885 { return p; } | 885 { return p; } |
886 | 886 |
887 BOOST_SPIRIT_CLASSIC_NAMESPACE_END | 887 BOOST_SPIRIT_CLASSIC_NAMESPACE_END |
888 | 888 |
892 | 892 |
893 //------------------------------------------------------------------------------ | 893 //------------------------------------------------------------------------------ |
894 // Expression templates for action placeholders. | 894 // Expression templates for action placeholders. |
895 //------------------------------------------------------------------------------ | 895 //------------------------------------------------------------------------------ |
896 | 896 |
897 namespace boost { namespace spirit { | 897 namespace boost { namespace spirit { |
898 | 898 |
899 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | 899 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN |
900 | 900 |
901 namespace type_of { | 901 namespace type_of { |
902 | 902 |
903 // No-operation functor | 903 // No-operation functor |
904 | 904 |
905 struct nop_functor | 905 struct nop_functor |
906 { | 906 { |
907 template<typename T> | 907 template<typename T> |
908 bool operator()(T const &) const | 908 bool operator()(T const &) const |
909 { return false; } | 909 { return false; } |
910 template<typename T, typename U> | 910 template<typename T, typename U> |
911 bool operator()(T const &, U const &) const | 911 bool operator()(T const &, U const &) const |
912 { return false; } | 912 { return false; } |
913 | 913 |
947 }; | 947 }; |
948 template<typename Action> struct action_concatenator<nop_functor, Action> | 948 template<typename Action> struct action_concatenator<nop_functor, Action> |
949 { | 949 { |
950 typedef Action type; | 950 typedef Action type; |
951 | 951 |
952 static type concatenate(nop_functor const &, Action const & a) | 952 static type concatenate(nop_functor const &, Action const & a) |
953 { return a; } | 953 { return a; } |
954 }; | 954 }; |
955 template<typename Action> struct action_concatenator<Action, nop_functor> | 955 template<typename Action> struct action_concatenator<Action, nop_functor> |
956 { | 956 { |
957 typedef Action type; | 957 typedef Action type; |
958 | 958 |
959 static type concatenate(Action const & a, nop_functor const &) | 959 static type concatenate(Action const & a, nop_functor const &) |
960 { return a; } | 960 { return a; } |
961 }; | 961 }; |
962 template<> struct action_concatenator<nop_functor, nop_functor> | 962 template<> struct action_concatenator<nop_functor, nop_functor> |
963 { | 963 { |
964 typedef nop_functor type; | 964 typedef nop_functor type; |
965 | 965 |
966 static type concatenate(nop_functor const &, nop_functor const &) | 966 static type concatenate(nop_functor const &, nop_functor const &) |
967 { return nop_functor(); } | 967 { return nop_functor(); } |
968 }; | 968 }; |
969 | 969 |
970 template<typename Action1, typename Action2> | 970 template<typename Action1, typename Action2> |
971 typename action_concatenator<Action1,Action2>::type | 971 typename action_concatenator<Action1,Action2>::type |
972 concatenate_actions(Action1 const & a1, Action2 const & a2) | 972 concatenate_actions(Action1 const & a1, Action2 const & a2) |
973 { | 973 { |
974 return action_concatenator<Action1,Action2>::concatenate(a1,a2); | 974 return action_concatenator<Action1,Action2>::concatenate(a1,a2); |
975 } | 975 } |
976 | 976 |
1015 typedef ChainOrChains head_type; | 1015 typedef ChainOrChains head_type; |
1016 typedef LastChain tail_type; | 1016 typedef LastChain tail_type; |
1017 | 1017 |
1018 head_type const & head() const { return obj_head; } | 1018 head_type const & head() const { return obj_head; } |
1019 tail_type const & tail() const { return obj_tail; } | 1019 tail_type const & tail() const { return obj_tail; } |
1020 }; | 1020 }; |
1021 | 1021 |
1022 // Action chain concatenation | 1022 // Action chain concatenation |
1023 template<class Head, class Tail> | 1023 template<class Head, class Tail> |
1024 action_chains<Head,Tail> make_chain(Head const & h, Tail const & t) | 1024 action_chains<Head,Tail> make_chain(Head const & h, Tail const & t) |
1025 { return action_chains<Head,Tail>(h,t); } | 1025 { return action_chains<Head,Tail>(h,t); } |
1026 | 1026 |
1027 template<class PH1, action_chain_mode M1, typename A1, | 1027 template<class PH1, action_chain_mode M1, typename A1, |
1028 class PH2, action_chain_mode M2, typename A2> | 1028 class PH2, action_chain_mode M2, typename A2> |
1029 action_chains< action_chain<PH1,M1,A1>, action_chain<PH2,M2,A2> > | 1029 action_chains< action_chain<PH1,M1,A1>, action_chain<PH2,M2,A2> > |
1030 operator, (action_chain<PH1,M1,A1> const & h, | 1030 operator, (action_chain<PH1,M1,A1> const & h, |
1031 action_chain<PH2,M2,A2> const & t) | 1031 action_chain<PH2,M2,A2> const & t) |
1032 { return make_chain(h,t); } | 1032 { return make_chain(h,t); } |
1033 | 1033 |
1034 template<class Head, class Tail,class PH, action_chain_mode M, typename A> | 1034 template<class Head, class Tail,class PH, action_chain_mode M, typename A> |
1035 action_chains< action_chains<Head,Tail>, action_chain<PH,M,A> > | 1035 action_chains< action_chains<Head,Tail>, action_chain<PH,M,A> > |
1036 operator, (action_chains<Head,Tail> const & h, action_chain<PH,M,A> const & t) | 1036 operator, (action_chains<Head,Tail> const & h, action_chain<PH,M,A> const & t) |
1037 { return make_chain(h,t); } | 1037 { return make_chain(h,t); } |
1038 | 1038 |
1039 | 1039 |
1040 // Extract the (maybe composite) action associated with an action | 1040 // Extract the (maybe composite) action associated with an action |
1041 // placeholders from the chains with a fold algorithm. | 1041 // placeholders from the chains with a fold algorithm. |
1042 template<class Placeholder, typename StartAction, class NewChainOrChains> | 1042 template<class Placeholder, typename StartAction, class NewChainOrChains> |
1043 struct placeholdee | 1043 struct placeholdee |
1044 { | 1044 { |
1045 typedef StartAction type; | 1045 typedef StartAction type; |
1046 | 1046 |
1047 static type get(StartAction const & a, NewChainOrChains const &) | 1047 static type get(StartAction const & a, NewChainOrChains const &) |
1048 { return a; } | 1048 { return a; } |
1049 }; | 1049 }; |
1050 | 1050 |
1052 typename StartAction, class NewChainOrChains> | 1052 typename StartAction, class NewChainOrChains> |
1053 typename placeholdee<Placeholder,StartAction,NewChainOrChains>::type | 1053 typename placeholdee<Placeholder,StartAction,NewChainOrChains>::type |
1054 get_placeholdee(StartAction const & a, NewChainOrChains const & c) | 1054 get_placeholdee(StartAction const & a, NewChainOrChains const & c) |
1055 { return placeholdee<Placeholder,StartAction,NewChainOrChains>::get(a,c); } | 1055 { return placeholdee<Placeholder,StartAction,NewChainOrChains>::get(a,c); } |
1056 | 1056 |
1057 template<class Placeholder, typename StartAction, class Head, class Tail> | 1057 template<class Placeholder, typename StartAction, class Head, class Tail> |
1058 struct placeholdee | 1058 struct placeholdee |
1059 < Placeholder, StartAction, action_chains<Head,Tail> > | 1059 < Placeholder, StartAction, action_chains<Head,Tail> > |
1060 { | 1060 { |
1061 typedef typename placeholdee<Placeholder, | 1061 typedef typename placeholdee<Placeholder, |
1062 typename placeholdee<Placeholder,StartAction,Head>::type, Tail >::type | 1062 typename placeholdee<Placeholder,StartAction,Head>::type, Tail >::type |
1073 struct placeholdee | 1073 struct placeholdee |
1074 < Placeholder, StartAction, action_chain<Placeholder,replace,A> > | 1074 < Placeholder, StartAction, action_chain<Placeholder,replace,A> > |
1075 { | 1075 { |
1076 typedef A type; | 1076 typedef A type; |
1077 | 1077 |
1078 static type get(StartAction const &, | 1078 static type get(StartAction const &, |
1079 action_chain<Placeholder,replace,A> const & c) | 1079 action_chain<Placeholder,replace,A> const & c) |
1080 { return c.action(); } | 1080 { return c.action(); } |
1081 }; | 1081 }; |
1082 | 1082 |
1083 template<class Placeholder, typename StartAction, typename A> | 1083 template<class Placeholder, typename StartAction, typename A> |
1084 struct placeholdee | 1084 struct placeholdee |
1085 < Placeholder, StartAction, action_chain<Placeholder,append,A> > | 1085 < Placeholder, StartAction, action_chain<Placeholder,append,A> > |
1086 { | 1086 { |
1087 typedef typename action_concatenator<StartAction,A>::type type; | 1087 typedef typename action_concatenator<StartAction,A>::type type; |
1088 | 1088 |
1089 static type get(StartAction const & a, | 1089 static type get(StartAction const & a, |
1090 action_chain<Placeholder,append,A> const & c) | 1090 action_chain<Placeholder,append,A> const & c) |
1091 { return concatenate_actions(a,c.action()); } | 1091 { return concatenate_actions(a,c.action()); } |
1092 }; | 1092 }; |
1093 | 1093 |
1094 } | 1094 } |
1095 | 1095 |
1096 BOOST_SPIRIT_CLASSIC_NAMESPACE_END | 1096 BOOST_SPIRIT_CLASSIC_NAMESPACE_END |
1097 | 1097 |
1098 } } // namespace ::BOOST_SPIRIT_CLASSIC_NS::type_of | 1098 } } // namespace ::BOOST_SPIRIT_CLASSIC_NS::type_of |
1099 | 1099 |
1102 | 1102 |
1103 //------------------------------------------------------------------------------ | 1103 //------------------------------------------------------------------------------ |
1104 // Misc.utilities | 1104 // Misc.utilities |
1105 //------------------------------------------------------------------------------ | 1105 //------------------------------------------------------------------------------ |
1106 | 1106 |
1107 namespace boost { namespace spirit { | 1107 namespace boost { namespace spirit { |
1108 | 1108 |
1109 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | 1109 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN |
1110 | 1110 |
1111 namespace type_of { | 1111 namespace type_of { |
1112 | 1112 |
1113 // Utility function to create a dependency to a template argument. | 1113 // Utility function to create a dependency to a template argument. |
1114 | 1114 |
1115 template<typename T, typename X> | 1115 template<typename T, typename X> |
1116 X const & depend_on_type(X const & x) | 1116 X const & depend_on_type(X const & x) |
1117 { return x; } | 1117 { return x; } |
1118 | 1118 |
1119 // Utility to allow use parenthesized type expressions with commas inside | 1119 // Utility to allow use parenthesized type expressions with commas inside |
1120 // as a type within macros. Thanks to Dave Abrahams for telling me this nice | 1120 // as a type within macros. Thanks to Dave Abrahams for telling me this nice |
1121 // trick. | 1121 // trick. |
1128 | 1128 |
1129 template<typename T> struct remove_special_fptr { }; | 1129 template<typename T> struct remove_special_fptr { }; |
1130 template<typename T> struct remove_special_fptr< special_result & (*)(T) > | 1130 template<typename T> struct remove_special_fptr< special_result & (*)(T) > |
1131 { typedef T type; }; | 1131 { typedef T type; }; |
1132 | 1132 |
1133 } | 1133 } |
1134 | 1134 |
1135 BOOST_SPIRIT_CLASSIC_NAMESPACE_END | 1135 BOOST_SPIRIT_CLASSIC_NAMESPACE_END |
1136 | 1136 |
1137 } } // namespace ::BOOST_SPIRIT_CLASSIC_NS::type_of | 1137 } } // namespace ::BOOST_SPIRIT_CLASSIC_NS::type_of |
1138 | 1138 |
1139 //------------------------------------------------------------------------------ | 1139 //------------------------------------------------------------------------------ |
1140 #endif | 1140 #endif |
1141 //------------------------------------------------------------------------------ | 1141 //------------------------------------------------------------------------------ |
1142 | 1142 |