AirTSP Logo  1.01.0
C++ Simulated Airline Travel Solution Provider Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BookingRequestParser.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 #include <sstream>
7 #include <fstream>
8 // Boost (Extended STL)
9 #include <boost/date_time/posix_time/posix_time.hpp>
10 #include <boost/date_time/gregorian/gregorian.hpp>
11 // Boost Spirit (Parsing)
12 #define BOOST_SPIRIT_DEBUG
13 #include <boost/spirit/home/classic/core.hpp>
14 #include <boost/spirit/home/classic/attribute.hpp>
15 #include <boost/spirit/home/classic/utility/functor_parser.hpp>
16 #include <boost/spirit/home/classic/utility/loops.hpp>
17 #include <boost/spirit/home/classic/utility/chset.hpp>
18 #include <boost/spirit/home/classic/utility/confix.hpp>
19 #include <boost/spirit/home/classic/iterator/file_iterator.hpp>
20 #include <boost/spirit/home/classic/actor/push_back_actor.hpp>
21 #include <boost/spirit/home/classic/actor/assign_actor.hpp>
22 // StdAir
23 #include <stdair/service/Logger.hpp>
24 // AirTSP
26 
27 // Type definitions
28 typedef char char_t;
29 typedef char const* iterator_t;
30 //typedef boost::spirit::classic::file_iterator<char_t> iterator_t;
31 typedef boost::spirit::classic::scanner<iterator_t> scanner_t;
32 typedef boost::spirit::classic::rule<scanner_t> rule_t;
33 
34 namespace airtsp {
35 
40  : _searchString (ioSearchString) {}
41 
43  void operator() (iterator_t iStr, iterator_t iStrEnd) const {
44  std::string lPlace (iStr, iStrEnd);
45  // std::cout << "Place: " << lPlace << std::endl;
46 
47  // Set the place
48  _searchString._tmpPlace._name += " " + lPlace;
49 
50  // Add the parsed place to the list
51  // _searchString._placeList.push_back (_searchString._tmpPlace);
52  }
53 
55  };
56 
58  struct store_date {
60  store_date (SearchString_T& ioSearchString)
61  : _searchString (ioSearchString) {}
62 
64  void operator() (iterator_t iStr, iterator_t iStrEnd) const {
66  // std::cout << "Board date: "
67  // << _searchString._date << std::endl;
68 
69  // Add the parsed date to the list
71  }
72 
74  };
75 
80  : _searchString (ioSearchString) {}
81 
83  void operator() (bool iAirlineSign) const {
84  _searchString._tmpAirline._isPreferred = !iAirlineSign;
85  // std::cout << "Airline is preferred: " << iAirlineSign << std::endl;
86  }
87 
89  };
90 
95  : _searchString (ioSearchString) {}
96 
98  void operator() (iterator_t iStr, iterator_t iStrEnd) const {
99  std::string lAirlineCode (iStr, iStrEnd);
100  _searchString._tmpAirline._code = lAirlineCode;
101  // std::cout << "Airline code: " << lAirlineCode << std::endl;
102 
103  // Add the parsed airline to the list
105  }
106 
108  };
109 
114  : _searchString (ioSearchString) {}
115 
117  void operator() (iterator_t iStr, iterator_t iStrEnd) const {
118  std::string lAirlineName (iStr, iStrEnd);
119  _searchString._tmpAirline._name = lAirlineName;
120  // std::cout << "Airline: " << lAirlineName << std::endl;
121 
122  // Add the parsed airline to the list
124  }
125 
127  };
128 
133  : _searchString (ioSearchString) {}
134 
136  void operator() (unsigned int iNumber) const {
138  // std::cout << "Number of passengers: " << iNumber << std::endl;
139  }
140 
142  };
143 
148  : _searchString (ioSearchString) {}
149 
151  void operator() (iterator_t iStr, iterator_t iStrEnd) const {
152  std::string lPassengerType (iStr, iStrEnd);
154  // std::cout << "Passenger type: " << lPassengerType << std::endl;
155 
156  // Add the parsed passenger to the list
158  }
159 
161  };
162 
167  : _searchString (ioSearchString) {}
168 
170  void operator() (iterator_t iStr, iterator_t iStrEnd) const {
171  std::string lPassengerType (iStr, iStrEnd);
173  // std::cout << "Passenger type: " << lPassengerType << std::endl;
174 
175  // Add the parsed passenger to the list
177  }
178 
180  };
181 
186  : _searchString (ioSearchString) {}
187 
189  void operator() (iterator_t iStr, iterator_t iStrEnd) const {
190  std::string lPassengerType (iStr, iStrEnd);
192  // std::cout << "Passenger type: " << lPassengerType << std::endl;
193 
194  // Add the parsed passenger to the list
196  }
197 
199  };
200 
201  // /////////// Utilities /////////////
203  boost::spirit::classic::int_parser<unsigned int, 10, 1, 1> int1_p;
205  boost::spirit::classic::uint_parser<unsigned int, 10, 1, 1> uint1_p;
207  boost::spirit::classic::uint_parser<unsigned int, 10, 1, 2> uint1_2_p;
209  boost::spirit::classic::uint_parser<int, 10, 2, 2> uint2_p;
211  boost::spirit::classic::uint_parser<int, 10, 2, 4> uint2_4_p;
213  boost::spirit::classic::uint_parser<int, 10, 4, 4> uint4_p;
215  boost::spirit::classic::uint_parser<int, 10, 1, 4> uint1_4_p;
216 
218  //
219  // Our calculator grammar (using subrules)
220  //
222 
248  using namespace boost::spirit::classic;
249 
252  public boost::spirit::classic::grammar<SearchStringParser> {
253 
255  : _searchString (ioSearchString) {
256  }
257 
258  template <typename ScannerT>
259  struct definition {
261 
262  search_string = places
263  >> !( dates )
264  >> *( preferred_airlines )
265  >> *( passengers )
266  ;
267 
268  places =
269  +( place_element )
270  ;
271 
272  place_element =
273  lexeme_d[ (repeat_p(1,20)[chset_p("a-z")])[store_place_element(self._searchString)] ]
274  ;
275 
276  dates =
277  date[store_date(self._searchString)]
278  >> !date[store_date(self._searchString)]
279  ;
280 
281  date =
282  ( month | day )
283  >> boost::spirit::classic::chset_p("/-")
284  >> ( day | month )
285  >> ! ( boost::spirit::classic::chset_p("/-")
286  >> year )
287  ;
288 
289  day =
290  lexeme_d[ limit_d(1u,31u)[uint1_2_p][assign_a(self._searchString._tmpDate._day)] ]
291  ;
292 
293  month =
294  lexeme_d[ limit_d(1u,12u)[uint1_2_p][assign_a(self._searchString._tmpDate._month)] ]
295  ;
296 
297  year =
298  lexeme_d[ limit_d(2000u,2099u)[uint4_p][assign_a(self._searchString._tmpDate._year)] ]
299  | lexeme_d[ limit_d(0u,99u)[uint2_p][assign_a(self._searchString._tmpDate._year)] ]
300  ;
301 
302  preferred_airlines =
303  !(boost::spirit::classic::sign_p)[store_airline_sign(self._searchString)]
304  >> airline_code | airline_name
305  ;
306 
307  airline_code =
308  lexeme_d[ (repeat_p(2,3)[chset_p("0-9a-z")])[store_airline_code(self._searchString)] ]
309  ;
310 
311  airline_name =
312  lexeme_d[ (repeat_p(4,20)[chset_p("0-9a-z")])[store_airline_name(self._searchString)] ]
313  ;
314 
315  passengers =
316  passenger_number >> passenger_type
317  ;
318 
319  passenger_number =
320  lexeme_d[ limit_d(1u, 9u)[uint1_p][store_passenger_number(self._searchString)] ]
321  ;
322 
323  passenger_type =
324  passenger_adult_type[store_adult_passenger_type(self._searchString)]
325  | passenger_child_type[store_child_passenger_type(self._searchString)]
326  | passenger_pet_type[store_pet_passenger_type(self._searchString)]
327  ;
328 
329  passenger_adult_type =
330  lexeme_d[ as_lower_d [ str_p("adult") >> !ch_p('s') ] ]
331  ;
332 
333  passenger_child_type =
334  lexeme_d[ as_lower_d [ str_p("child") >> !str_p("ren") ] ]
335  ;
336 
337  passenger_pet_type =
338  lexeme_d[ as_lower_d [ str_p("dog") | str_p("cat") >> !ch_p('s') ] ]
339  ;
340 
341  BOOST_SPIRIT_DEBUG_NODE (search_string);
342  BOOST_SPIRIT_DEBUG_NODE (places);
343  BOOST_SPIRIT_DEBUG_NODE (place_element);
344  BOOST_SPIRIT_DEBUG_NODE (dates);
345  BOOST_SPIRIT_DEBUG_NODE (date);
346  BOOST_SPIRIT_DEBUG_NODE (day);
347  BOOST_SPIRIT_DEBUG_NODE (month);
348  BOOST_SPIRIT_DEBUG_NODE (year);
349  BOOST_SPIRIT_DEBUG_NODE (preferred_airlines);
350  BOOST_SPIRIT_DEBUG_NODE (airline_code);
351  BOOST_SPIRIT_DEBUG_NODE (airline_name);
352  BOOST_SPIRIT_DEBUG_NODE (passengers);
353  BOOST_SPIRIT_DEBUG_NODE (passenger_number);
354  BOOST_SPIRIT_DEBUG_NODE (passenger_type);
355  BOOST_SPIRIT_DEBUG_NODE (passenger_adult_type);
356  BOOST_SPIRIT_DEBUG_NODE (passenger_child_type);
357  BOOST_SPIRIT_DEBUG_NODE (passenger_pet_type);
358  }
359 
360  boost::spirit::classic::rule<ScannerT> search_string, places, place_element,
361  dates, date, month, day, year,
362  preferred_airlines, airline_code, airline_name,
363  passengers, passenger_number, passenger_type, passenger_adult_type,
364  passenger_child_type, passenger_pet_type;
365 
366  boost::spirit::classic::rule<ScannerT> const& start() const { return search_string; }
367  };
368 
370  };
371 
372  // //////////////////////////////////////////////////////////
373  SearchString_T parseBookingRequest (const std::string& iSearchString) {
374  SearchString_T oSearchStringStruct;
375 
376  // Read the search string
377  iterator_t lStringIterator = iSearchString.c_str();
378 
379  // Instantiate the structure that will hold the result of the parsing.
380  SearchStringParser lSearchStringParser (oSearchStringStruct);
381  boost::spirit::classic::parse_info<iterator_t> info =
382  boost::spirit::classic::parse (lStringIterator, lSearchStringParser,
383  boost::spirit::classic::space_p);
384 
385  STDAIR_LOG_DEBUG ("-------------------------");
386 
387  bool hasBeenParsingSuccessful = info.full;
388  if (hasBeenParsingSuccessful == true) {
389  STDAIR_LOG_DEBUG ("Parsing succeeded");
390 
391  } else {
392  STDAIR_LOG_DEBUG ("Parsing failed");
393  }
394  STDAIR_LOG_DEBUG ("-------------------------");
395 
396  return oSearchStringStruct;
397  }
398 
399 }