fipa_acl  1.4
grammar_bitefficient.h
Go to the documentation of this file.
1 #ifndef _FIPAACL_GRAMMAR_BITEFFICIENT_H_
2 #define _FIPAACL_GRAMMAR_BITEFFICIENT_H_
3 
4 #include <fipa_acl/message_parser/grammar/grammar_common.h>
5 
6 using namespace fipa::acl::grammar;
7 
8 // ########################################################
9 // BOOST_FUSION_ADAPTION
10 // #######################################################
11 //
12 // We need to tell boost::fusion about the message structure to make
13 // This includes all composite types like Header etc.
16  (char, id)
17  (char, version)
18 )
19 
21  fipa::acl::message::Parameter,
22  (std::string, name)
23  (fipa::acl::message::ParameterValue, data)
24 )
25 
27  fipa::acl::UserDefinedParameter,
28  (std::string, name)
29  (fipa::acl::UserDefinedParameterValue, data)
30 )
31 
33  fipa::acl::AgentIdentifier,
34  (std::string, name)
35  (std::vector<std::string>, addresses)
36  (std::vector<fipa::acl::Resolver>, resolvers)
37  (std::vector<fipa::acl::UserDefinedParameter>, parameters)
38 )
39 
40 // The final message structure
42  fipa::acl::Message,
43  (fipa::acl::Header, header)
44  (std::string, type)
45  (std::vector<fipa::acl::message::Parameter>, parameters)
46 )
47 
48 namespace fipa
49 {
50 
51 //#####################################################
52 // Utility functions
53 //#####################################################
54  // In order to use functions as semantic actions
55  // lazy evaluation is required
56 
57 namespace acl {
58 namespace bitefficient {
59 
60 // To avoid namespace clashes with boost::bind
61 namespace label = qi::labels;
62 
63 template<typename Iterator>
64 struct EndOfCollection : qi::grammar<Iterator, qi::unused_type>
65 {
66  EndOfCollection() : EndOfCollection::base_type(eof_collection_rule, "EndOfCollection-bitefficient_grammar")
67  {
68  eof_collection_rule = qi::byte_(0x01);
69 
70  FIPA_DEBUG_RULE(eof_collection_rule);
71  }
72 
73  qi::rule<Iterator, qi::unused_type> eof_collection_rule;
74 };
75 
76 template<typename Iterator>
77 struct BinStringNoCodetable : qi::grammar<Iterator, fipa::acl::ByteSequence(), qi::locals<boost::uint_least32_t> >
78 {
79  BinStringNoCodetable() : BinStringNoCodetable::base_type(bin_string_no_codetable_rule, "BinStringNoCodetable-bitefficient_grammar")
80  {
81  using namespace qi;
82 
83  bin_string_no_codetable_rule = ( byte_(0x14) >> nullTerminatedString [ label::_val = label::_1 ])
84  // The byte length will be stored in the rule local variable (label::_a) and then forwarded to the qi::repeat instruction
85  | ( byte_(0x16) >> len8 [ label::_a = label::_1 ]
86  >> byteSeq(label::_a) [ phoenix::at_c<2>(label::_val) = label::_1] ) // new byteLengthEncoded string
87  | ( byte_(0x17) >> len16 [ label::_a = label::_1 ]
88  >> byteSeq(label::_a) [ phoenix::at_c<2>(label::_val) = label::_1 ] )
89  | ( byte_(0x19) >> len32 [ label::_a = label::_1 ]
90  >> byteSeq(label::_a) [ phoenix::at_c<2>(label::_val) = label::_1 ] )
91  ;
92 
93  byteSeq = qi::repeat(label::_r1)[byte_] [ label::_val = convertToCharVector(label::_1) ]
94  ;
95  FIPA_DEBUG_RULE(bin_string_no_codetable_rule);
96  }
97 
98  qi::rule<Iterator, fipa::acl::ByteSequence(), qi::locals<boost::uint_least32_t> > bin_string_no_codetable_rule;
99  Len8<Iterator> len8;
100  Len16<Iterator> len16;
101  Len32<Iterator> len32;
102  qi::rule<Iterator, std::vector<unsigned char>(boost::uint_least32_t) > byteSeq;
103  NullTerminatedString<Iterator> nullTerminatedString;
104 };
105 
106 template<typename Iterator>
107 struct BinStringCodetable : qi::grammar<Iterator, fipa::acl::ByteSequence(), qi::locals<boost::uint_least32_t> >
108 {
109  BinStringCodetable() : BinStringCodetable::base_type(bin_string_codetable_rule, "BinStringCodetable-bitefficient_grammar")
110  {
111  using namespace qi;
112 
113  bin_string_codetable_rule =
114  // string literal from code table
115  ( byte_(0x15) >> index [ phoenix::at_c<2>(label::_val) = extractFromCodetable(label::_1) ])
116  | ( byte_(0x18) >> index [ phoenix::at_c<2>(label::_val) = extractFromCodetable(label::_1) ]) // byteLengthEncoded from code table
117  ;
118 
119  FIPA_DEBUG_RULE(bin_string_codetable_rule);
120  }
121 
122  qi::rule<Iterator, fipa::acl::ByteSequence(), qi::locals<boost::uint_least32_t> > bin_string_codetable_rule;
123  Index<Iterator> index;
124 };
125 
126 
127 template<typename Iterator>
128 struct BinString : qi::grammar<Iterator, fipa::acl::ByteSequence() >
129 {
130  BinString() : BinString::base_type(bin_string_rule, "BinString-bitefficient_grammar")
131  {
132  bin_string_rule = ( binStringNoCodetable | binStringCodetable) [ label::_val = label::_1];
133 
134  FIPA_DEBUG_RULE(bin_string_rule);
135  }
136 
137  qi::rule<Iterator, fipa::acl::ByteSequence()> bin_string_rule;
138  BinStringNoCodetable<Iterator> binStringNoCodetable;
139  BinStringCodetable<Iterator> binStringCodetable;
140 };
141 
142 
143 template<typename Iterator>
144 struct BinNumber : qi::grammar<Iterator, std::string()>
145 {
146  BinNumber() : BinNumber::base_type(bin_number_rule, "BinNumber-bitefficient_grammar")
147  {
148  using qi::byte_;
149  // Decimal number 0x12
150  // Hex number 0x13
151  // Hexadecimal number are converted to int and then back
152  bin_number_rule = ( byte_(0x12) >> digits [ label::_val = label::_1 ] )
153  | ( byte_(0x13) >> digits [ label::_val = convertDigitsToHex(label::_1) ]
154  );
155 
156  FIPA_DEBUG_RULE(bin_number_rule);
157  }
158 
159  qi::rule<Iterator, std::string()> bin_number_rule;
160  Digits<Iterator> digits;
161 };
162 
163 template <typename Iterator>
164 struct BinDateTime : qi::grammar<Iterator, fipa::acl::DateTime()>
165 {
166  BinDateTime() : BinDateTime::base_type(bin_date_time_rule, "BinDateTime-bitefficient_grammar")
167  {
168  using qi::byte_;
169  using encoding::alpha;
170 
171  // Absolute time, relative +/-
172  // identifier indicate if typeDesignator follows or not
173  // NOTE: When parser fails, make sure the data forwarded to the parser really(!) contains
174  // all characters. Since 0x20 is a special character in normal ASCII some ways of reading the data
175  // or using std::copy might lead to an unexpected failure, since these special characters will be discarded
176  bin_date_time_rule = ( byte_(0x20) [ phoenix::at_c<0>(label::_val) = ' ' ]
177  >> binDate [ phoenix::at_c<1>(label::_val) = label::_1 ]
178  )
179  // Relative time (+)
180  | ( byte_(0x21) [ phoenix::at_c<0>(label::_val) = '+' ]
181  >> binDate [ phoenix::at_c<1>(label::_val) = label::_1 ]
182  )
183  // Relative time (-)
184  | ( byte_(0x22) [ phoenix::at_c<0>(label::_val) = '-' ]
185  >> binDate [ phoenix::at_c<1>(label::_val) = label::_1 ]
186  )
187  // Absolute time
188  | ( byte_(0x24) [ phoenix::at_c<0>(label::_val) = ' ' ]
189  >> binDate [ phoenix::at_c<1>(label::_val) = label::_1 ]
190  >> typeDesignator [ phoenix::at_c<2>(label::_val) = label::_1 ]
191  )
192  // Relative time (+)
193  | ( byte_(0x25) [ phoenix::at_c<0>(label::_val) = '+' ]
194  >> binDate [ phoenix::at_c<1>(label::_val) = label::_1 ]
195  >> typeDesignator [ phoenix::at_c<2>(label::_val) = label::_1 ]
196  )
197  // Relative time (-)
198  | ( byte_(0x26) [ phoenix::at_c<0>(label::_val) = '-' ]
199  >> binDate [ phoenix::at_c<1>(label::_val) = label::_1 ]
200  >> typeDesignator [ phoenix::at_c<2>(label::_val) = label::_1 ]
201  )
202  ;
203 
204  // Timezone for UTC is Z
205  typeDesignator = alpha [ label::_val = label::_1 ];
206 
207 
208  #ifdef BOOST_SPIRIT_DEBUG
209  BOOST_SPIRIT_DEBUG_NODE(typeDesignator);
210  FIPA_DEBUG_RULE(bin_date_time_rule);
211  #endif
212  }
213 
214  qi::rule<Iterator, fipa::acl::DateTime() > bin_date_time_rule;
215  grammar::DateTime<Iterator> binDate;
216  qi::rule<Iterator, char() > typeDesignator;
217 };
218 
219 
220 
221 template <typename Iterator>
222 struct BinWord : qi::grammar<Iterator, std::string()>
223 {
224  BinWord() : BinWord::base_type(bin_word_rule, "BinWord-bitefficient_grammar")
225  {
226  using qi::byte_;
227 
228  bin_word_rule = ( ( byte_(0x10)
229  >> word [ label::_val = label::_1 ]
230  >> byte_(0x00) )
231  | byte_(0x11) >> index [ label::_val = extractFromCodetable(label::_1) ]
232  );
233 
234  FIPA_DEBUG_RULE(bin_word_rule);
235  }
236 
237  qi::rule<Iterator, std::string()> bin_word_rule;
238  Word<Iterator> word;
239  Index<Iterator> index;
240 };
241 
242 template <typename Iterator>
243 struct BinExpression : qi::grammar<Iterator, std::string()>
244 {
245  BinExpression() : BinExpression::base_type(bin_expression_rule, "BinExpression-bitefficient_grammar")
246  {
247  using qi::on_error;
248  using qi::fail;
249  using phoenix::construct;
250  using phoenix::val;
251 
252  // Inbuild parser:
253  // Encoding is ASCII here
254  using encoding::char_;
255  using encoding::string;
256  using encoding::digit;
257  using encoding::alpha;
258  using qi::byte_;
259 
260  bin_expression_rule = binExpr [ label::_val = label::_1 ]
261  | byte_(0xFF) >> binString [ label::_val = convertToString(label::_1) ]
262  ;
263  binExpr = binWord [ label::_val = label::_1 ]
264  | binString [ label::_val = convertToString(label::_1) ]
265  | binNumber [ label::_val = label::_1 ]
266  // Every expression can look like the following of "(+ (-1 2) 3)"
267  | (exprStart [ label::_val = "(" , label::_val += label::_1 ]
268  >> *binExpr [ label::_val += label::_1 ]
269  >> exprEnd [ label::_val += ")", label::_val += label::_1 ]
270  )
271  ;
272 
273  exprStart = ( byte_(0x60) ) [ label::_val = "" ]
274  | ( byte_(0x70) >> word [ label::_val = label::_1 ]
275  >> byte_(0x00) )
276  | ( byte_(0x71) >> index [ label::_val = extractFromCodetable(label::_1)] )
277  | ( byte_(0x72) >> digits [ label::_val = label::_1 ] )
278  | ( byte_(0x73) >> digits [ label::_val = label::_1 ] )
279  | ( byte_(0x74) >> ( stringLiteralTerminated
280  | byteLengthEncodedStringTerminated ) [ label::_val = convertToString(label::_1) ] )
281  | ( byte_(0x75) >> index [ label::_val = extractFromCodetable(label::_1)])
282  | ( byte_(0x76) >> len8 [ label::_a = label::_1 ]
283  >> fipaString(label::_a) [ label::_val = convertToString(label::_1) ])
284  | ( byte_(0x77) >> len16 [ label::_a = label::_1 ]
285  >> fipaString(label::_a) [ label::_val = convertToString(label::_1) ])
286  | ( byte_(0x78) >> len32 [ label::_a = label::_1 ]
287  >> fipaString(label::_a) [ label::_val = convertToString(label::_1) ])
288  | ( byte_(0x79) >> index [ label::_val = extractFromCodetable(label::_1)])
289  ;
290 
291  exprEnd = ( byte_(0x40) ) [ label::_val = "" ]
292  | ( byte_(0x50) >> word [ label::_val = label::_1 ]
293  >> byte_(0x00) )
294  | ( byte_(0x51) >> index [ label::_val = extractFromCodetable(label::_1)])
295  | ( byte_(0x52) >> digits [ label::_val = label::_1 ] )
296  | ( byte_(0x53) >> digits [ label::_val = label::_1 ] )
297  | ( byte_(0x54) >> ( stringLiteralTerminated
298  | byteLengthEncodedStringTerminated ) [ label::_val = convertToString(label::_1) ])
299  | ( byte_(0x55) >> index [ label::_val = extractFromCodetable(label::_1)])
300  | ( byte_(0x56) >> len8 [ label::_a = label::_1 ]
301  >> fipaString(label::_a) [ label::_val = convertToString(label::_1)] )
302  | ( byte_(0x57) >> len16 [ label::_a = label::_1 ]
303  >> fipaString(label::_a) [ label::_val = convertToString(label::_1)])
304  | ( byte_(0x58) >> len32 [ label::_a = label::_1 ]
305  >> fipaString(label::_a) [ label::_val = convertToString(label::_1)])
306  | ( byte_(0x59) >> index [ label::_val = extractFromCodetable(label::_1)])
307  ;
308 
309 
310  // pass the local length variable down to the rule using parent rules variable _r1
311  fipaString = (stringLiteral | byteLengthEncodedString(label::_r1) );
312 
313  byteLengthEncodedStringHeader = char_('#')
314  >> + digit [ label::_val += label::_1 ]
315  >> char_('"')
316  ;
317 
318  // Digits tell the byte encoding
319  // label::_r1 is an inherited local variable from the parent rule
320  byteLengthEncodedString = byteLengthEncodedStringHeader [ phoenix::at_c<0>(label::_val) += label::_1 ]
321  >> qi::repeat(label::_r1)[byte_] [ phoenix::at_c<2>(label::_val) = convertToString(label::_1) ]
322  ;
323 
324  #ifdef BOOST_SPIRIT_DEBUG
325  BOOST_SPIRIT_DEBUG_NODE(bin_expression_rule);
326  FIPA_DEBUG_RULE(byteLengthEncodedString);
327  #endif
328  }
329 
330  // Main rule
331  qi::rule<Iterator, std::string()> bin_expression_rule;
332 
333  BinNumber<Iterator> binNumber;
334  BinWord<Iterator> binWord;
335  Word<Iterator> word;
336  Index<Iterator> index;
337 
338  Digits<Iterator> digits;
339  BinString<Iterator> binString;
340 
341  BinDateTime<Iterator> binDateTime;
342  qi::rule<Iterator, std::string() > binExpr;
343  qi::rule<Iterator, std::string(), qi::locals<boost::uint_least32_t> > exprStart;
344  qi::rule<Iterator, std::string(), qi::locals<boost::uint_least32_t> > exprEnd;
345 
346  //qi::symbols<char, qi::rule<Iterator> > exprKeyword;
347 
348  qi::rule<Iterator, std::vector<unsigned char>(boost::uint32_t) > byteSeq;
349  Len8<Iterator> len8;
350  Len16<Iterator> len16;
351  Len32<Iterator> len32;
352 
353  qi::rule<Iterator, fipa::acl::ByteSequence(boost::uint32_t) > fipaString;
354  StringLiteral<Iterator> stringLiteral;
355  qi::rule<Iterator, fipa::acl::ByteSequence() > stringLiteralTerminated;
356  qi::rule<Iterator, std::string() > byteLengthEncodedStringHeader;
357  qi::rule<Iterator, fipa::acl::ByteSequence(boost::uint32_t) > byteLengthEncodedString;
358  ByteLengthEncodedStringTerminated<Iterator> byteLengthEncodedStringTerminated;
359  CodedNumber<Iterator> codedNumber;
360 };
361 
362 template<typename Iterator>
363 struct UserdefinedParameter : qi::grammar<Iterator, fipa::acl::UserDefinedParameter()>
364 {
365  UserdefinedParameter() : UserdefinedParameter::base_type(userdefined_parameter_rule, "UserdefinedParameter-bitefficient_grammar")
366  {
367  userdefined_parameter_rule = qi::byte_(0x04)
368  >> binWord [ phoenix::at_c<0>(label::_val) = label::_1 ]
369  >> binExpression [ phoenix::at_c<1>(label::_val) = label::_1 ];
370 
371  FIPA_DEBUG_RULE(userdefined_parameter_rule);
372  }
373 
374  qi::rule<Iterator, fipa::acl::UserDefinedParameter() > userdefined_parameter_rule;
375 
376  BinWord<Iterator> binWord;
377  BinExpression<Iterator> binExpression;
378 };
379 
380 template<typename Iterator>
381 struct AgentIdentifier : qi::grammar<Iterator, fipa::acl::AgentIdentifier()>
382 {
383  AgentIdentifier() : AgentIdentifier::base_type(agent_identifier_rule, "AgentIdentifier-bitefficient_grammar")
384  {
385  using qi::byte_;
386 
387  agent_identifier_rule = byte_(0x02) >> agentName [ phoenix::at_c<0>(label::_val) = label::_1 ]
388  >> -addresses [ phoenix::at_c<1>(label::_val) = label::_1 ]
389  >> -resolvers [ phoenix::at_c<2>(label::_val) = label::_1 ]
390  >> *userDefinedParameter [ phoenix::push_back(phoenix::at_c<3>(label::_val), label::_1) ]
391  >> endOfCollection;
392 
393  addresses = byte_(0x02) >> urlCollection [ label::_val = label::_1 ];
394  resolvers = byte_(0x03) >> *agent_identifier_rule [ phoenix::push_back(label::_val, label::_1) ]
395  >> endOfCollection;
396 
397  urlCollection = *url [ phoenix::push_back(label::_val, label::_1) ]
398  >> endOfCollection;
399 
400  ;
401  endOfCollection %= byte_(0x01);
402 
403  FIPA_DEBUG_RULE(addresses);
404  FIPA_DEBUG_RULE(resolvers);
405  FIPA_DEBUG_RULE(agent_identifier_rule);
406  }
407 
408  qi::rule<Iterator, fipa::acl::AgentIdentifier()> agent_identifier_rule;
409  BinWord<Iterator> agentName;
410  qi::rule<Iterator, std::vector<std::string>() > addresses;
411  qi::rule<Iterator, std::vector<fipa::acl::Resolver>() > resolvers;
412  UserdefinedParameter<Iterator> userDefinedParameter;
413  qi::rule<Iterator, std::vector<std::string>() > urlCollection;
414  BinWord<Iterator> url;
415  qi::rule<Iterator> endOfCollection;
416 };
417 
418 template <typename Iterator>
419 // IMPORTANT: ACLMessage with following () otherwise, compiler error
420 struct Message : qi::grammar<Iterator, fipa::acl::Message()>
421 {
422 
423  Message() : Message::base_type(aclCommunicativeAct, "message-bitefficient_grammar")
424  {
425  using phoenix::construct;
426  using phoenix::val;
427 
428  using qi::lit;
429  using qi::lexeme; // prevents character skipping
430  using qi::byte_;
431 
432 
433  // To avoid namespace clashes with boost::bind
434  namespace label = qi::labels;
435 
436  // Explanation:
437  // at_c<0>(label::_val) = label::_1
438  // set the first element (position 0) of the element synthesized attribute,i.e._val, to the parsed value, i.e. _1
439  // the synthesized attribute might be a fipa::acl::message, and the element ordering depends on the structure as
440  // defined with the BOOST_FUSION_ADAPT_STRUCT definition
441  aclCommunicativeAct = header [ phoenix::at_c<0>(label::_val) = label::_1 ]
442  >> messageType [ phoenix::at_c<1>(label::_val) = label::_1 ]
443  >> *messageParameter [ phoenix::push_back(phoenix::at_c<2>(label::_val), label::_1) ]
444  >> endOfMessage // No action here
445  ;
446 
447  header = messageId [ phoenix::at_c<0>(label::_val) = label::_1 ]
448  >> version [ phoenix::at_c<1>(label::_val) = label::_1 ]
449  ;
450 
451  // byte_() does only return an unused_type, so if we want to save the value, we have to assign it directly
452  messageId = byte_(0xFA) [ label::_val = 0xfa ]
453  | byte_(0xFB) [ label::_val = 0xfb ]
454  | byte_(0xFC) [ label::_val = 0xfc ]
455  ;
456 
457 
458  version = byte_;
459  endOfMessage %= endOfCollection;
460  endOfCollection %= byte_(0x01);
461 
462  // we do not support dynamic code tables or user defined values
463  // message type is a string
464  // the types in the rule definition have to match to apply alias()
465  messageType = predefinedMessageType | userDefinedMessageType;
466 
467  userDefinedMessageType = byte_(0x00)
468  >> messageTypeName [ label::_val = label::_1 ]
469  ;
470 
471 
472  // Note: never do a direct assignment like
473  // messageParameter = predefinedMessageParameter or you will be getting runtime errors
474  // use messageParameter = predefinedMessageParameter.alias() instead
475  messageParameter = predefinedMessageParameter | userDefinedMessageParameter;
476 
477  userDefinedMessageParameter = byte_(0x00)
478  >> parameterName [ phoenix::at_c<0>(label::_val) = label::_1 ]
479  >> parameterValue [ phoenix::at_c<1>(label::_val) = label::_1 ]
480  ;
481 
482  // Converting message type into predefined strings
483  predefinedMessageType = byte_(0x01) [ label::_val = "accept-proposal" ]
484  | byte_(0x02) [ label::_val = "agree" ]
485  | byte_(0x03) [ label::_val = "cancel" ]
486  | byte_(0x04) [ label::_val = "cfp" ]
487  | byte_(0x05) [ label::_val = "confirm" ]
488  | byte_(0x06) [ label::_val = "disconfirm" ]
489  | byte_(0x07) [ label::_val = "failure" ]
490  | byte_(0x08) [ label::_val = "inform" ]
491  | byte_(0x09) [ label::_val = "inform-if" ]
492  | byte_(0x0a) [ label::_val = "inform-ref" ]
493  | byte_(0x0b) [ label::_val = "not-understood" ]
494  | byte_(0x0c) [ label::_val = "propagate" ]
495  | byte_(0x0d) [ label::_val = "propose" ]
496  | byte_(0x0e) [ label::_val = "proxy" ]
497  | byte_(0x0f) [ label::_val = "query-if" ]
498  | byte_(0x10) [ label::_val = "query-ref" ]
499  | byte_(0x11) [ label::_val = "refuse" ]
500  | byte_(0x12) [ label::_val = "reject-proposal" ]
501  | byte_(0x13) [ label::_val = "request" ]
502  | byte_(0x14) [ label::_val = "request-when" ]
503  | byte_(0x15) [ label::_val = "request-whenever" ]
504  | byte_(0x16) [ label::_val = "subscribe" ]
505  ;
506 
507  // predefinedMessageParameter uses a boost::variant
508  predefinedMessageParameter = byte_(0x02) [ phoenix::at_c<0>(label::_val) = "sender" ] >> agentIdentifier [ phoenix::at_c<1>(label::_val) = label::_1 ] // sender
509  | byte_(0x03) [ phoenix::at_c<0>(label::_val) = "receiver" ] >> recipientExpr [ phoenix::at_c<1>(label::_val) = label::_1 ] // receiver
510  | byte_(0x04) [ phoenix::at_c<0>(label::_val) = "content" ] >> msgContent [ phoenix::at_c<1>(label::_val) = label::_1 ] // content
511  | byte_(0x05) [ phoenix::at_c<0>(label::_val) = "reply-with" ] >> replyWithParam [ phoenix::at_c<1>(label::_val) = label::_1 ] // reply-with
512  | byte_(0x06) [ phoenix::at_c<0>(label::_val) = "reply-by" ] >> replyByParam [ phoenix::at_c<1>(label::_val) = label::_1 ] // reply-by
513  | byte_(0x07) [ phoenix::at_c<0>(label::_val) = "in-reply-to" ] >> inReplyToParam [ phoenix::at_c<1>(label::_val) = label::_1 ] // in-reply-to
514  | byte_(0x08) [ phoenix::at_c<0>(label::_val) = "reply-to" ] >> replyToParam [ phoenix::at_c<1>(label::_val) = label::_1 ] // reply-to
515  | byte_(0x09) [ phoenix::at_c<0>(label::_val) = "language" ] >> language [ phoenix::at_c<1>(label::_val) = label::_1 ] // language
516  | byte_(0x0a) [ phoenix::at_c<0>(label::_val) = "encoding" ] >> encoding [ phoenix::at_c<1>(label::_val) = label::_1 ] // encoding
517  | byte_(0x0b) [ phoenix::at_c<0>(label::_val) = "ontology" ] >> ontology [ phoenix::at_c<1>(label::_val) = label::_1 ] // ontology
518  | byte_(0x0c) [ phoenix::at_c<0>(label::_val) = "protocol" ] >> protocol [ phoenix::at_c<1>(label::_val) = label::_1 ] // protocol
519  | byte_(0x0d) [ phoenix::at_c<0>(label::_val) = "conversation-id" ] >> conversationId [ phoenix::at_c<1>(label::_val) = label::_1 ] // conversation-id
520  ;
521 
522  recipientExpr = *agentIdentifier [ phoenix::push_back(label::_val, label::_1) ]
523  >> endOfCollection;
524 
525  replyToParam = recipientExpr.alias();
526 
527  // Enables the debug tree when debug mode is active
528  // requires the include of stream operators as well
529  // since every type will be printed to the outputstream (standard is cout)
530  // see also: debug.h
531  #ifdef BOOST_SPIRIT_DEBUG
532  // http://boost-spirit.com/home/articles/doc-addendum/debugging/
533  BOOST_SPIRIT_DEBUG_NODE(header);
534  BOOST_SPIRIT_DEBUG_NODE(messageId);
535  BOOST_SPIRIT_DEBUG_NODE(version);
536  BOOST_SPIRIT_DEBUG_NODE(messageType);
537  BOOST_SPIRIT_DEBUG_NODE(userDefinedMessageType);
538  BOOST_SPIRIT_DEBUG_NODE(messageParameter);
539  BOOST_SPIRIT_DEBUG_NODE(userDefinedMessageParameter);
540  BOOST_SPIRIT_DEBUG_NODE(predefinedMessageParameter);
541  BOOST_SPIRIT_DEBUG_NODE(predefinedMessageType);
542  #endif
543 
544  }
545 
546  // Define rules as follows
547  // qi::rule<Iterator, synthesized_attribute(inherited_attribute>)> r;
548  // synthesized = type of output value
549  // inherited = actual type the parser gives you
550  //
551  // if you have local variable within your rule you have to specify them here as well by using
552  // qi::locals, i.e.
553  // qi::rule<Iterator, fipa::acl::ByteSequence(), qi::locals<std::string> > stringLiteral;
554  // here, the local variable is std::string an can be accessed within the rule as _a, _b, _c, ..
555  // (check the correct namespace)
556  //
557  // inherited attributes: are defined withi the brackets () of the second arg of a rule
558  // and can be accessed within the rule as _r1, _r2, ...
559  // qi::rule<Iterator, std::vector<unsigned char>(boost::uint32_t) > byteSeq;
560  // here, the rule can be called like: byteSeq(20) and will try to match as its synthesised attribute
561  // a vector of 20 characters
562  //
563  qi::rule<Iterator, fipa::acl::Message()> aclCommunicativeAct;
564  qi::rule<Iterator> message;
565  qi::rule<Iterator, fipa::acl::Header()> header;
566  qi::rule<Iterator, char()> messageId;
567  qi::rule<Iterator, char()> version;
568  qi::rule<Iterator> endOfMessage;
569  qi::rule<Iterator> endOfCollection;
570 
571  qi::rule<Iterator, std::string() > messageType;
572  qi::rule<Iterator, std::string() > userDefinedMessageType;
573  BinWord<Iterator> messageTypeName;
574 
575  qi::rule<Iterator, fipa::acl::message::Parameter() > messageParameter;
576  qi::rule<Iterator, fipa::acl::message::Parameter() > userDefinedMessageParameter;
577  qi::rule<Iterator, fipa::acl::message::Parameter() > predefinedMessageParameter;
578 
579  BinWord<Iterator> parameterName;
580  BinExpression<Iterator> parameterValue;
581 
582  qi::rule<Iterator, std::string() > predefinedMessageType;
583  UserdefinedParameter<Iterator> userDefinedParameter;
584 
585  qi::rule<Iterator, std::vector<fipa::acl::AgentIdentifier>() > recipientExpr;
586 
587  AgentIdentifier<Iterator> agentIdentifier;
588 
589  BinExpression<Iterator> binExpression;
590  BinWord<Iterator> binWord;
591  BinString<Iterator> binString;
592  BinString<Iterator> msgContent;
593 
594  BinExpression<Iterator> replyWithParam;
595  BinDateTime<Iterator> replyByParam;
596  BinExpression<Iterator> inReplyToParam;
597  qi::rule<Iterator, std::vector<fipa::acl::AgentIdentifier>() > replyToParam;
598  BinExpression<Iterator> language;
599  BinExpression<Iterator> encoding;
600  BinExpression<Iterator> ontology;
601  BinWord<Iterator> protocol;
602  BinExpression<Iterator> conversationId;
603 };
604 
605 } // end namepsace bitefficient
606 } // end namespace acl
607 } // end namespace fipa
608 
609 #endif // _FIPAACL_GRAMMAR_BITEFFICIENT_H_
phoenix::function< convertToCharVectorImpl > convertToCharVector
boost::recursive_wrapper< AgentIdentifier > Resolver
Definition: agent_id.h:15
Definition: debug.h:28
boost::variant< std::string, fipa::acl::AgentIdentifier, std::vector< fipa::acl::AgentIdentifier >, fipa::acl::ByteSequence, fipa::acl::DateTime, fipa::acl::ByteString > ParameterValue
Definition: parameter.h:12
phoenix::function< convertToStringImpl > convertToString
boost::variant< std::string, fipa::acl::Resolver, std::vector< fipa::acl::Resolver >, fipa::acl::ByteSequence, fipa::acl::ByteString > UserDefinedParameterValue
Definition: agent_id.h:19
BOOST_FUSION_ADAPT_STRUCT(fipa::acl::envelope::Parameter,(std::string, name)(fipa::acl::envelope::ParameterValue, data))
phoenix::function< convertDigitsToHexImpl > convertDigitsToHex
#define FIPA_DEBUG_RULE(X)
Foundation of Physical Intelligent Agents.
Definition: conversation.cpp:6
phoenix::function< extractFromCodetableImpl > extractFromCodetable