00001
00002
00003
00004
00005 #include <cassert>
00006 #include <sstream>
00007 #include <fstream>
00008
00009 #include <boost/date_time/posix_time/posix_time.hpp>
00010 #include <boost/date_time/gregorian/gregorian.hpp>
00011
00012 #define BOOST_SPIRIT_DEBUG
00013 #include <boost/spirit/home/classic/core.hpp>
00014 #include <boost/spirit/home/classic/attribute.hpp>
00015 #include <boost/spirit/home/classic/utility/functor_parser.hpp>
00016 #include <boost/spirit/home/classic/utility/loops.hpp>
00017 #include <boost/spirit/home/classic/utility/chset.hpp>
00018 #include <boost/spirit/home/classic/utility/confix.hpp>
00019 #include <boost/spirit/home/classic/iterator/file_iterator.hpp>
00020 #include <boost/spirit/home/classic/actor/push_back_actor.hpp>
00021 #include <boost/spirit/home/classic/actor/assign_actor.hpp>
00022
00023 #include <stdair/service/Logger.hpp>
00024
00025 #include <airsched/batches/BookingRequestParser.hpp>
00026
00027
00028 typedef char char_t;
00029 typedef char const* iterator_t;
00030
00031 typedef boost::spirit::classic::scanner<iterator_t> scanner_t;
00032 typedef boost::spirit::classic::rule<scanner_t> rule_t;
00033
00034 namespace airsched {
00035
00037 struct store_place_element {
00039 store_place_element (SearchString_T& ioSearchString)
00040 : _searchString (ioSearchString) {}
00041
00043 void operator() (iterator_t iStr, iterator_t iStrEnd) const {
00044 std::string lPlace (iStr, iStrEnd);
00045
00046
00047
00048 _searchString._tmpPlace._name += " " + lPlace;
00049
00050
00051
00052 }
00053
00054 SearchString_T& _searchString;
00055 };
00056
00058 struct store_date {
00060 store_date (SearchString_T& ioSearchString)
00061 : _searchString (ioSearchString) {}
00062
00064 void operator() (iterator_t iStr, iterator_t iStrEnd) const {
00065 _searchString._tmpDate._date = _searchString._tmpDate.getDate();
00066
00067
00068
00069
00070 _searchString._dateList.push_back (_searchString._tmpDate);
00071 }
00072
00073 SearchString_T& _searchString;
00074 };
00075
00077 struct store_airline_sign {
00079 store_airline_sign (SearchString_T& ioSearchString)
00080 : _searchString (ioSearchString) {}
00081
00083 void operator() (bool iAirlineSign) const {
00084 _searchString._tmpAirline._isPreferred = !iAirlineSign;
00085
00086 }
00087
00088 SearchString_T& _searchString;
00089 };
00090
00092 struct store_airline_code {
00094 store_airline_code (SearchString_T& ioSearchString)
00095 : _searchString (ioSearchString) {}
00096
00098 void operator() (iterator_t iStr, iterator_t iStrEnd) const {
00099 std::string lAirlineCode (iStr, iStrEnd);
00100 _searchString._tmpAirline._code = lAirlineCode;
00101
00102
00103
00104 _searchString._airlineList.push_back (_searchString._tmpAirline);
00105 }
00106
00107 SearchString_T& _searchString;
00108 };
00109
00111 struct store_airline_name {
00113 store_airline_name (SearchString_T& ioSearchString)
00114 : _searchString (ioSearchString) {}
00115
00117 void operator() (iterator_t iStr, iterator_t iStrEnd) const {
00118 std::string lAirlineName (iStr, iStrEnd);
00119 _searchString._tmpAirline._name = lAirlineName;
00120
00121
00122
00123 _searchString._airlineList.push_back (_searchString._tmpAirline);
00124 }
00125
00126 SearchString_T& _searchString;
00127 };
00128
00130 struct store_passenger_number {
00132 store_passenger_number (SearchString_T& ioSearchString)
00133 : _searchString (ioSearchString) {}
00134
00136 void operator() (unsigned int iNumber) const {
00137 _searchString._tmpPassenger._number = iNumber;
00138
00139 }
00140
00141 SearchString_T& _searchString;
00142 };
00143
00145 struct store_adult_passenger_type {
00147 store_adult_passenger_type (SearchString_T& ioSearchString)
00148 : _searchString (ioSearchString) {}
00149
00151 void operator() (iterator_t iStr, iterator_t iStrEnd) const {
00152 std::string lPassengerType (iStr, iStrEnd);
00153 _searchString._tmpPassenger._type = Passenger_T::ADULT;
00154
00155
00156
00157 _searchString._passengerList.push_back (_searchString._tmpPassenger);
00158 }
00159
00160 SearchString_T& _searchString;
00161 };
00162
00164 struct store_child_passenger_type {
00166 store_child_passenger_type (SearchString_T& ioSearchString)
00167 : _searchString (ioSearchString) {}
00168
00170 void operator() (iterator_t iStr, iterator_t iStrEnd) const {
00171 std::string lPassengerType (iStr, iStrEnd);
00172 _searchString._tmpPassenger._type = Passenger_T::CHILD;
00173
00174
00175
00176 _searchString._passengerList.push_back (_searchString._tmpPassenger);
00177 }
00178
00179 SearchString_T& _searchString;
00180 };
00181
00183 struct store_pet_passenger_type {
00185 store_pet_passenger_type (SearchString_T& ioSearchString)
00186 : _searchString (ioSearchString) {}
00187
00189 void operator() (iterator_t iStr, iterator_t iStrEnd) const {
00190 std::string lPassengerType (iStr, iStrEnd);
00191 _searchString._tmpPassenger._type = Passenger_T::PET;
00192
00193
00194
00195 _searchString._passengerList.push_back (_searchString._tmpPassenger);
00196 }
00197
00198 SearchString_T& _searchString;
00199 };
00200
00201
00203 boost::spirit::classic::int_parser<unsigned int, 10, 1, 1> int1_p;
00205 boost::spirit::classic::uint_parser<unsigned int, 10, 1, 1> uint1_p;
00207 boost::spirit::classic::uint_parser<unsigned int, 10, 1, 2> uint1_2_p;
00209 boost::spirit::classic::uint_parser<int, 10, 2, 2> uint2_p;
00211 boost::spirit::classic::uint_parser<int, 10, 2, 4> uint2_4_p;
00213 boost::spirit::classic::uint_parser<int, 10, 4, 4> uint4_p;
00215 boost::spirit::classic::uint_parser<int, 10, 1, 4> uint1_4_p;
00216
00218
00219
00220
00222
00248 using namespace boost::spirit::classic;
00249
00251 struct SearchStringParser :
00252 public boost::spirit::classic::grammar<SearchStringParser> {
00253
00254 SearchStringParser (SearchString_T& ioSearchString)
00255 : _searchString (ioSearchString) {
00256 }
00257
00258 template <typename ScannerT>
00259 struct definition {
00260 definition (SearchStringParser const& self) {
00261
00262 search_string = places
00263 >> !( dates )
00264 >> *( preferred_airlines )
00265 >> *( passengers )
00266 ;
00267
00268 places =
00269 +( place_element )
00270 ;
00271
00272 place_element =
00273 lexeme_d[ (repeat_p(1,20)[chset_p("a-z")])[store_place_element(self._searchString)] ]
00274 ;
00275
00276 dates =
00277 date[store_date(self._searchString)]
00278 >> !date[store_date(self._searchString)]
00279 ;
00280
00281 date =
00282 ( month | day )
00283 >> boost::spirit::classic::chset_p("/-")
00284 >> ( day | month )
00285 >> ! ( boost::spirit::classic::chset_p("/-")
00286 >> year )
00287 ;
00288
00289 day =
00290 lexeme_d[ limit_d(1u,31u)[uint1_2_p][assign_a(self._searchString._tmpDate._day)] ]
00291 ;
00292
00293 month =
00294 lexeme_d[ limit_d(1u,12u)[uint1_2_p][assign_a(self._searchString._tmpDate._month)] ]
00295 ;
00296
00297 year =
00298 lexeme_d[ limit_d(2000u,2099u)[uint4_p][assign_a(self._searchString._tmpDate._year)] ]
00299 | lexeme_d[ limit_d(0u,99u)[uint2_p][assign_a(self._searchString._tmpDate._year)] ]
00300 ;
00301
00302 preferred_airlines =
00303 !(boost::spirit::classic::sign_p)[store_airline_sign(self._searchString)]
00304 >> airline_code | airline_name
00305 ;
00306
00307 airline_code =
00308 lexeme_d[ (repeat_p(2,3)[chset_p("0-9a-z")])[store_airline_code(self._searchString)] ]
00309 ;
00310
00311 airline_name =
00312 lexeme_d[ (repeat_p(4,20)[chset_p("0-9a-z")])[store_airline_name(self._searchString)] ]
00313 ;
00314
00315 passengers =
00316 passenger_number >> passenger_type
00317 ;
00318
00319 passenger_number =
00320 lexeme_d[ limit_d(1u, 9u)[uint1_p][store_passenger_number(self._searchString)] ]
00321 ;
00322
00323 passenger_type =
00324 passenger_adult_type[store_adult_passenger_type(self._searchString)]
00325 | passenger_child_type[store_child_passenger_type(self._searchString)]
00326 | passenger_pet_type[store_pet_passenger_type(self._searchString)]
00327 ;
00328
00329 passenger_adult_type =
00330 lexeme_d[ as_lower_d [ str_p("adult") >> !ch_p('s') ] ]
00331 ;
00332
00333 passenger_child_type =
00334 lexeme_d[ as_lower_d [ str_p("child") >> !str_p("ren") ] ]
00335 ;
00336
00337 passenger_pet_type =
00338 lexeme_d[ as_lower_d [ str_p("dog") | str_p("cat") >> !ch_p('s') ] ]
00339 ;
00340
00341 BOOST_SPIRIT_DEBUG_NODE (search_string);
00342 BOOST_SPIRIT_DEBUG_NODE (places);
00343 BOOST_SPIRIT_DEBUG_NODE (place_element);
00344 BOOST_SPIRIT_DEBUG_NODE (dates);
00345 BOOST_SPIRIT_DEBUG_NODE (date);
00346 BOOST_SPIRIT_DEBUG_NODE (day);
00347 BOOST_SPIRIT_DEBUG_NODE (month);
00348 BOOST_SPIRIT_DEBUG_NODE (year);
00349 BOOST_SPIRIT_DEBUG_NODE (preferred_airlines);
00350 BOOST_SPIRIT_DEBUG_NODE (airline_code);
00351 BOOST_SPIRIT_DEBUG_NODE (airline_name);
00352 BOOST_SPIRIT_DEBUG_NODE (passengers);
00353 BOOST_SPIRIT_DEBUG_NODE (passenger_number);
00354 BOOST_SPIRIT_DEBUG_NODE (passenger_type);
00355 BOOST_SPIRIT_DEBUG_NODE (passenger_adult_type);
00356 BOOST_SPIRIT_DEBUG_NODE (passenger_child_type);
00357 BOOST_SPIRIT_DEBUG_NODE (passenger_pet_type);
00358 }
00359
00360 boost::spirit::classic::rule<ScannerT> search_string, places, place_element,
00361 dates, date, month, day, year,
00362 preferred_airlines, airline_code, airline_name,
00363 passengers, passenger_number, passenger_type, passenger_adult_type,
00364 passenger_child_type, passenger_pet_type;
00365
00366 boost::spirit::classic::rule<ScannerT> const& start() const { return search_string; }
00367 };
00368
00369 SearchString_T& _searchString;
00370 };
00371
00372
00373 SearchString_T parseBookingRequest (const std::string& iSearchString) {
00374 SearchString_T oSearchStringStruct;
00375
00376
00377 iterator_t lStringIterator = iSearchString.c_str();
00378
00379
00380 SearchStringParser lSearchStringParser (oSearchStringStruct);
00381 boost::spirit::classic::parse_info<iterator_t> info =
00382 boost::spirit::classic::parse (lStringIterator, lSearchStringParser,
00383 boost::spirit::classic::space_p);
00384
00385 STDAIR_LOG_DEBUG ("-------------------------");
00386
00387 bool hasBeenParsingSuccessful = info.full;
00388 if (hasBeenParsingSuccessful == true) {
00389 STDAIR_LOG_DEBUG ("Parsing succeeded");
00390
00391 } else {
00392 STDAIR_LOG_DEBUG ("Parsing failed");
00393 }
00394 STDAIR_LOG_DEBUG ("-------------------------");
00395
00396 return oSearchStringStruct;
00397 }
00398
00399 }