$treeview $search $mathjax
00001 // ////////////////////////////////////////////////////////////////////// 00002 // Import section 00003 // ////////////////////////////////////////////////////////////////////// 00004 // STL 00005 #include <cassert> 00006 #include <sstream> 00007 #include <fstream> 00008 // Boost (Extended STL) 00009 #include <boost/date_time/posix_time/posix_time.hpp> 00010 #include <boost/date_time/gregorian/gregorian.hpp> 00011 // Boost Spirit (Parsing) 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 // StdAir 00023 #include <stdair/service/Logger.hpp> 00024 // AirTSP 00025 #include <airtsp/batches/BookingRequestParser.hpp> 00026 00027 // Type definitions 00028 typedef char char_t; 00029 typedef char const* iterator_t; 00030 //typedef boost::spirit::classic::file_iterator<char_t> iterator_t; 00031 typedef boost::spirit::classic::scanner<iterator_t> scanner_t; 00032 typedef boost::spirit::classic::rule<scanner_t> rule_t; 00033 00034 namespace airtsp { 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 // std::cout << "Place: " << lPlace << std::endl; 00046 00047 // Set the place 00048 _searchString._tmpPlace._name += " " + lPlace; 00049 00050 // Add the parsed place to the list 00051 // _searchString._placeList.push_back (_searchString._tmpPlace); 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 // std::cout << "Board date: " 00067 // << _searchString._date << std::endl; 00068 00069 // Add the parsed date to the list 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 // std::cout << "Airline is preferred: " << iAirlineSign << std::endl; 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 // std::cout << "Airline code: " << lAirlineCode << std::endl; 00102 00103 // Add the parsed airline to the list 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 // std::cout << "Airline: " << lAirlineName << std::endl; 00121 00122 // Add the parsed airline to the list 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 // std::cout << "Number of passengers: " << iNumber << std::endl; 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 // std::cout << "Passenger type: " << lPassengerType << std::endl; 00155 00156 // Add the parsed passenger to the list 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 // std::cout << "Passenger type: " << lPassengerType << std::endl; 00174 00175 // Add the parsed passenger to the list 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 // std::cout << "Passenger type: " << lPassengerType << std::endl; 00193 00194 // Add the parsed passenger to the list 00195 _searchString._passengerList.push_back (_searchString._tmpPassenger); 00196 } 00197 00198 SearchString_T& _searchString; 00199 }; 00200 00201 // /////////// Utilities ///////////// 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 // Our calculator grammar (using subrules) 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 // Read the search string 00377 iterator_t lStringIterator = iSearchString.c_str(); 00378 00379 // Instantiate the structure that will hold the result of the parsing. 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 }