AirSched Logo  0.1.4
C++ Simulated Airline Schedule Manager Library
ScheduleParserHelper.cpp
Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // STL
00005 #include <cassert>
00006 // StdAir
00007 #include <stdair/basic/BasFileMgr.hpp>
00008 #include <stdair/bom/BomRoot.hpp>
00009 #include <stdair/service/Logger.hpp>
00010 // AIRSCHED
00011 //#define BOOST_SPIRIT_DEBUG
00012 #include <airsched/command/ScheduleParserHelper.hpp>
00013 #include <airsched/command/InventoryGenerator.hpp>
00014 
00015 namespace bsc = boost::spirit::classic;
00016 
00017 namespace AIRSCHED {
00018 
00019   namespace ScheduleParserHelper {
00020       
00021     // //////////////////////////////////////////////////////////////////
00022     //  Semantic actions
00023     // //////////////////////////////////////////////////////////////////
00024 
00025     ParserSemanticAction::
00026     ParserSemanticAction (FlightPeriodStruct& ioFlightPeriod)
00027       : _flightPeriod (ioFlightPeriod) {
00028     }      
00029 
00030     // //////////////////////////////////////////////////////////////////
00031     storeAirlineCode::
00032     storeAirlineCode (FlightPeriodStruct& ioFlightPeriod)
00033       : ParserSemanticAction (ioFlightPeriod) {
00034     }
00035     
00036     // //////////////////////////////////////////////////////////////////
00037     void storeAirlineCode::operator() (iterator_t iStr,
00038                                        iterator_t iStrEnd) const { 
00039       const stdair::AirlineCode_T lAirlineCode (iStr, iStrEnd);
00040       _flightPeriod._airlineCode = lAirlineCode;
00041                 
00042       // As that's the beginning of a new flight, the list of legs
00043       // must be reset
00044       _flightPeriod._legList.clear();
00045     }
00046 
00047     // //////////////////////////////////////////////////////////////////
00048     storeFlightNumber::
00049     storeFlightNumber (FlightPeriodStruct& ioFlightPeriod)
00050       : ParserSemanticAction (ioFlightPeriod) {
00051     }
00052 
00053     // //////////////////////////////////////////////////////////////////
00054     void storeFlightNumber::operator() (unsigned int iNumber) const { 
00055       _flightPeriod._flightNumber = iNumber;
00056     }
00057 
00058     // //////////////////////////////////////////////////////////////////
00059     storeDateRangeStart::
00060     storeDateRangeStart (FlightPeriodStruct& ioFlightPeriod)
00061       : ParserSemanticAction (ioFlightPeriod) {
00062     }
00063     
00064     // //////////////////////////////////////////////////////////////////
00065     void storeDateRangeStart::operator() (iterator_t iStr,
00066                                           iterator_t iStrEnd) const {
00067       _flightPeriod._dateRangeStart = _flightPeriod.getDate();
00068         
00069       // Reset the number of seconds
00070       _flightPeriod._itSeconds = 0;
00071     }
00072       
00073     // //////////////////////////////////////////////////////////////////
00074     storeDateRangeEnd::
00075     storeDateRangeEnd (FlightPeriodStruct& ioFlightPeriod)
00076       : ParserSemanticAction (ioFlightPeriod) {
00077     }
00078     
00079     // //////////////////////////////////////////////////////////////////
00080     void storeDateRangeEnd::operator() (iterator_t iStr,
00081                                         iterator_t iStrEnd) const {
00082       // As a Boost date period (DatePeriod_T) defines the last day of
00083       // the period to be end-date - one day, we have to add one day to that
00084       // end date before.
00085       const stdair::DateOffset_T oneDay (1);
00086       _flightPeriod._dateRangeEnd = _flightPeriod.getDate() + oneDay;
00087 
00088       // Transform the date pair (i.e., the date range) into a date period
00089       _flightPeriod._dateRange =
00090         stdair::DatePeriod_T (_flightPeriod._dateRangeStart,
00091                               _flightPeriod._dateRangeEnd);
00092         
00093       // Reset the number of seconds
00094       _flightPeriod._itSeconds = 0;
00095     }
00096 
00097     // //////////////////////////////////////////////////////////////////
00098     storeDow::storeDow (FlightPeriodStruct& ioFlightPeriod)
00099       : ParserSemanticAction (ioFlightPeriod) {
00100     }
00101 
00102     // //////////////////////////////////////////////////////////////////
00103     void storeDow::operator() (iterator_t iStr, iterator_t iStrEnd) const {
00104       stdair::DOW_String_T lDow (iStr, iStrEnd);
00105       _flightPeriod._dow = lDow;
00106     }
00107       
00108     // //////////////////////////////////////////////////////////////////
00109     storeLegBoardingPoint::
00110     storeLegBoardingPoint (FlightPeriodStruct& ioFlightPeriod)
00111       : ParserSemanticAction (ioFlightPeriod) {
00112     }
00113 
00114     // //////////////////////////////////////////////////////////////////
00115     void storeLegBoardingPoint::operator() (iterator_t iStr,
00116                                             iterator_t iStrEnd) const {
00117       stdair::AirportCode_T lBoardingPoint (iStr, iStrEnd);
00118 
00119       // If a leg has already been parsed, add it to the FlightPeriod
00120       if (_flightPeriod._legAlreadyDefined == true) {
00121         _flightPeriod._legList.push_back (_flightPeriod._itLeg);
00122       } else {
00123         _flightPeriod._legAlreadyDefined = true;
00124       }
00125         
00126       // Set the (new) boarding point
00127       _flightPeriod._itLeg._boardingPoint = lBoardingPoint;
00128       
00129       // As that's the beginning of a new leg, the list of cabins
00130       // must be reset
00131       _flightPeriod._itLeg._cabinList.clear();
00132 
00133       // Add the airport code if it is not already stored in the airport lists
00134       _flightPeriod.addAirport (lBoardingPoint);
00135     }
00136 
00137     // //////////////////////////////////////////////////////////////////
00138     storeLegOffPoint::
00139     storeLegOffPoint (FlightPeriodStruct& ioFlightPeriod)
00140       : ParserSemanticAction (ioFlightPeriod) {
00141     }
00142 
00143     // //////////////////////////////////////////////////////////////////
00144     void storeLegOffPoint::operator() (iterator_t iStr,
00145                                        iterator_t iStrEnd) const {
00146       stdair::AirportCode_T lOffPoint (iStr, iStrEnd);
00147       _flightPeriod._itLeg._offPoint = lOffPoint;
00148 
00149       // Add the airport code if it is not already stored in the airport lists
00150       _flightPeriod.addAirport (lOffPoint);
00151     }
00152 
00153     // //////////////////////////////////////////////////////////////////
00154     storeBoardingTime::
00155     storeBoardingTime (FlightPeriodStruct& ioFlightPeriod)
00156       : ParserSemanticAction (ioFlightPeriod) {
00157     }
00158     
00159     // //////////////////////////////////////////////////////////////////
00160     void storeBoardingTime::operator() (iterator_t iStr,
00161                                         iterator_t iStrEnd) const {
00162       _flightPeriod._itLeg._boardingTime = _flightPeriod.getTime();
00163         
00164       // Reset the number of seconds
00165       _flightPeriod._itSeconds = 0;
00166 
00167       // Reset the date off-set
00168       _flightPeriod._dateOffset = 0;
00169     }
00170 
00171     // //////////////////////////////////////////////////////////////////
00172     storeOffTime::
00173     storeOffTime (FlightPeriodStruct& ioFlightPeriod)
00174       : ParserSemanticAction (ioFlightPeriod) {
00175     }
00176     
00177     // //////////////////////////////////////////////////////////////////
00178     void storeOffTime::operator() (iterator_t iStr,
00179                                    iterator_t iStrEnd) const {
00180       _flightPeriod._itLeg._offTime = _flightPeriod.getTime();
00181         
00182       // Reset the number of seconds
00183       _flightPeriod._itSeconds = 0;
00184 
00185       // As the boarding date off set is optional, it can be set only
00186       // afterwards, based on the staging date off-set value
00187       // (_flightPeriod._dateOffset).
00188       const stdair::DateOffset_T lDateOffset (_flightPeriod._dateOffset);
00189       _flightPeriod._itLeg._boardingDateOffset = lDateOffset;
00190     }
00191 
00192     // //////////////////////////////////////////////////////////////////
00193     storeElapsedTime::
00194     storeElapsedTime (FlightPeriodStruct& ioFlightPeriod)
00195       : ParserSemanticAction (ioFlightPeriod) {
00196     }
00197     
00198     // //////////////////////////////////////////////////////////////////
00199     void storeElapsedTime::operator() (iterator_t iStr,
00200                                        iterator_t iStrEnd) const {
00201       _flightPeriod._itLeg._elapsed = _flightPeriod.getTime();
00202         
00203       // Reset the number of seconds
00204       _flightPeriod._itSeconds = 0;
00205 
00206       // As the boarding date off set is optional, it can be set only
00207       // afterwards, based on the staging date off-set value
00208       // (_flightPeriod._dateOffset).
00209       const stdair::DateOffset_T lDateOffset (_flightPeriod._dateOffset);
00210       _flightPeriod._itLeg._offDateOffset = lDateOffset;
00211     }
00212 
00213     // //////////////////////////////////////////////////////////////////
00214     storeLegCabinCode::
00215     storeLegCabinCode (FlightPeriodStruct& ioFlightPeriod)
00216       : ParserSemanticAction (ioFlightPeriod) {
00217     }
00218     
00219     // //////////////////////////////////////////////////////////////////
00220     void storeLegCabinCode::operator() (char iChar) const { 
00221       _flightPeriod._itLegCabin._cabinCode = iChar; 
00222       //std::cout << "Cabin code: " << iChar << std::endl;
00223     }
00224 
00225     // //////////////////////////////////////////////////////////////////
00226     storeCapacity::
00227     storeCapacity (FlightPeriodStruct& ioFlightPeriod)
00228       : ParserSemanticAction (ioFlightPeriod) {
00229     }
00230     
00231     // //////////////////////////////////////////////////////////////////
00232     void storeCapacity::operator() (double iReal) const { 
00233       _flightPeriod._itLegCabin._capacity = iReal; 
00234       //std::cout << "Capacity: " << iReal << std::endl;
00235 
00236       // The capacity is the last (according to the arrival order
00237       // within the schedule input file) detail of the leg cabin. Hence,
00238       // when a capacity is parsed, it means that the full cabin
00239       // details have already been parsed as well: the cabin can
00240       // thus be added to the leg.
00241       _flightPeriod._itLeg._cabinList.push_back (_flightPeriod._itLegCabin);
00242     }
00243 
00244     // //////////////////////////////////////////////////////////////////
00245     storeSegmentSpecificity::
00246     storeSegmentSpecificity (FlightPeriodStruct& ioFlightPeriod)
00247       : ParserSemanticAction (ioFlightPeriod) {
00248     }
00249 
00250     // //////////////////////////////////////////////////////////////////
00251     void storeSegmentSpecificity::operator() (char iChar) const {
00252       if (iChar == '0') {
00253         _flightPeriod._areSegmentDefinitionsSpecific = false;
00254       } else {
00255         _flightPeriod._areSegmentDefinitionsSpecific = true;
00256       }
00257 
00258       // Do a few sanity checks: the two lists should get exactly the same
00259       // content (in terms of airport codes). The only difference is that one
00260       // is a STL set, and the other a STL vector.
00261       assert (_flightPeriod._airportList.size()
00262               == _flightPeriod._airportOrderedList.size());
00263       assert (_flightPeriod._airportList.size() >= 2);
00264         
00265       // Since all the legs have now been parsed, we get all the airports
00266       // and the segments may be built.
00267       _flightPeriod.buildSegments();
00268     }
00269       
00270     // //////////////////////////////////////////////////////////////////
00271     storeSegmentBoardingPoint::
00272     storeSegmentBoardingPoint (FlightPeriodStruct& ioFlightPeriod)
00273       : ParserSemanticAction (ioFlightPeriod) {
00274     }
00275 
00276     // //////////////////////////////////////////////////////////////////
00277     void storeSegmentBoardingPoint::operator() (iterator_t iStr,
00278                                              iterator_t iStrEnd) const {
00279       stdair::AirportCode_T lBoardingPoint (iStr, iStrEnd);
00280       _flightPeriod._itSegment._boardingPoint = lBoardingPoint;
00281     }
00282 
00283     // //////////////////////////////////////////////////////////////////
00284     storeSegmentOffPoint::
00285     storeSegmentOffPoint (FlightPeriodStruct& ioFlightPeriod)
00286       : ParserSemanticAction (ioFlightPeriod) {
00287     }
00288 
00289     // //////////////////////////////////////////////////////////////////
00290     void storeSegmentOffPoint::operator() (iterator_t iStr,
00291                                            iterator_t iStrEnd) const {
00292       stdair::AirportCode_T lOffPoint (iStr, iStrEnd);
00293       _flightPeriod._itSegment._offPoint = lOffPoint;
00294     }
00295 
00296     // //////////////////////////////////////////////////////////////////
00297     storeSegmentCabinCode::
00298     storeSegmentCabinCode (FlightPeriodStruct& ioFlightPeriod)
00299       : ParserSemanticAction (ioFlightPeriod) {
00300     }
00301     
00302     // //////////////////////////////////////////////////////////////////
00303     void storeSegmentCabinCode::operator() (char iChar) const { 
00304       _flightPeriod._itSegmentCabin._cabinCode = iChar; 
00305     }
00306 
00307     // //////////////////////////////////////////////////////////////////
00308     storeClasses::
00309     storeClasses (FlightPeriodStruct& ioFlightPeriod)
00310       : ParserSemanticAction (ioFlightPeriod) {
00311     }
00312 
00313     // //////////////////////////////////////////////////////////////////
00314     void storeClasses::operator() (iterator_t iStr,
00315                                    iterator_t iStrEnd) const {
00316       std::string lClasses (iStr, iStrEnd);
00317       _flightPeriod._itSegmentCabin._classes = lClasses;
00318 
00319       // The list of classes is the last (according to the arrival order
00320       // within the schedule input file) detail of the segment cabin. Hence,
00321       // when a list of classes is parsed, it means that the full segment
00322       // cabin details have already been parsed as well: the segment cabin
00323       // can thus be added to the segment.
00324       if (_flightPeriod._areSegmentDefinitionsSpecific == true) {
00325         _flightPeriod.addSegmentCabin (_flightPeriod._itSegment,
00326                                        _flightPeriod._itSegmentCabin);
00327       } else {
00328         _flightPeriod.addSegmentCabin (_flightPeriod._itSegmentCabin);
00329       }
00330     }
00331 
00332     // //////////////////////////////////////////////////////////////////
00333     storeFamilyCode::
00334     storeFamilyCode (FlightPeriodStruct& ioFlightPeriod)
00335       : ParserSemanticAction (ioFlightPeriod) {
00336     }
00337     
00338     // //////////////////////////////////////////////////////////////////
00339     void storeFamilyCode::operator() (int iCode) const {
00340       std::ostringstream ostr;
00341       ostr << iCode;
00342       _flightPeriod._itSegmentCabin._itFamilyCode = ostr.str(); 
00343     }
00344 
00345     // //////////////////////////////////////////////////////////////////
00346     storeFClasses::
00347     storeFClasses (FlightPeriodStruct& ioFlightPeriod)
00348       : ParserSemanticAction (ioFlightPeriod) {
00349     }
00350 
00351     // //////////////////////////////////////////////////////////////////
00352     void storeFClasses::operator() (iterator_t iStr,
00353                                     iterator_t iStrEnd) const {
00354       std::string lClasses (iStr, iStrEnd);
00355       FareFamilyStruct lFareFamily(_flightPeriod._itSegmentCabin._itFamilyCode,
00356                                      lClasses);
00357 
00358       // The list of classes is the last (according to the arrival order
00359       // within the schedule input file) detail of the segment cabin. Hence,
00360       // when a list of classes is parsed, it means that the full segment
00361       // cabin details have already been parsed as well: the segment cabin
00362       // can thus be added to the segment.
00363       if (_flightPeriod._areSegmentDefinitionsSpecific == true) {
00364         _flightPeriod.addFareFamily (_flightPeriod._itSegment,
00365                                      _flightPeriod._itSegmentCabin,
00366                                      lFareFamily);
00367       } else {
00368         _flightPeriod.addFareFamily (_flightPeriod._itSegmentCabin,
00369                                      lFareFamily);
00370       }
00371     }
00372 
00373     // //////////////////////////////////////////////////////////////////
00374     doEndFlight::
00375     doEndFlight (stdair::BomRoot& ioBomRoot,
00376                  FlightPeriodStruct& ioFlightPeriod)
00377       : ParserSemanticAction (ioFlightPeriod),
00378         _bomRoot (ioBomRoot) {
00379     }
00380     
00381     // //////////////////////////////////////////////////////////////////
00382     // void doEndFlight::operator() (char iChar) const {
00383     void doEndFlight::operator() (iterator_t iStr,
00384                                   iterator_t iStrEnd) const {
00385 
00386       assert (_flightPeriod._legAlreadyDefined == true);
00387       _flightPeriod._legList.push_back (_flightPeriod._itLeg);
00388         
00389       // The lists of legs and cabins must be reset
00390       _flightPeriod._legAlreadyDefined = false;
00391       _flightPeriod._itLeg._cabinList.clear();
00392         
00393       // DEBUG: Display the result
00394       STDAIR_LOG_DEBUG ("FlightPeriod: " << _flightPeriod.describe());
00395 
00396       // Create the FlightPeriod BOM objects, and potentially the intermediary
00397       // objects (e.g., Inventory).
00398       InventoryGenerator::createFlightPeriod (_bomRoot, _flightPeriod);
00399     }
00400 
00401       
00402     // ///////////////////////////////////////////////////////////////////
00403     //
00404     //  Utility Parsers
00405     //
00406     // ///////////////////////////////////////////////////////////////////
00408     int1_p_t int1_p;
00409     
00411     uint2_p_t uint2_p;
00412     
00414     uint4_p_t uint4_p;
00415     
00417     uint1_4_p_t uint1_4_p;
00418 
00420     repeat_p_t airline_code_p (chset_t("0-9A-Z").derived(), 2, 3);
00421       
00423     bounded1_4_p_t flight_number_p (uint1_4_p.derived(), 0u, 9999u);
00424 
00426     bounded4_p_t year_p (uint4_p.derived(), 2000u, 2099u);
00427       
00429     bounded2_p_t month_p (uint2_p.derived(), 1u, 12u);
00430 
00432     bounded2_p_t day_p (uint2_p.derived(), 1u, 31u);
00433      
00435     repeat_p_t dow_p (chset_t("0-1").derived().derived(), 7, 7);
00436 
00438     repeat_p_t airport_p (chset_t("0-9A-Z").derived(), 3, 3);
00439       
00441     bounded2_p_t hours_p (uint2_p.derived(), 0u, 23u);
00442 
00444     bounded2_p_t minutes_p (uint2_p.derived(), 0u, 59u);
00445 
00447     bounded2_p_t seconds_p (uint2_p.derived(), 0u, 59u);
00448 
00450     chset_t cabin_code_p ("A-Z");
00451 
00453     int1_p_t family_code_p;
00454       
00456     repeat_p_t class_code_list_p (chset_t("A-Z").derived(), 1, 26);
00457 
00458 
00459     // //////////////////////////////////////////////////////////////////
00460     //  (Boost Spirit) Grammar Definition
00461     // //////////////////////////////////////////////////////////////////
00462 
00463     // //////////////////////////////////////////////////////////////////
00464     FlightPeriodParser::
00465     FlightPeriodParser (stdair::BomRoot& ioBomRoot,
00466                         FlightPeriodStruct& ioFlightPeriod) 
00467       : _bomRoot (ioBomRoot),
00468         _flightPeriod (ioFlightPeriod) {
00469     }
00470 
00471     // //////////////////////////////////////////////////////////////////
00472     template<typename ScannerT>
00473     FlightPeriodParser::definition<ScannerT>::
00474     definition (FlightPeriodParser const& self) {
00475 
00476       flight_period_list = *(not_to_be_parsed
00477                              | flight_period )
00478         ;
00479 
00480       not_to_be_parsed =bsc::
00481         lexeme_d[bsc::comment_p("//") |bsc::comment_p("/*", "*/")
00482                  |bsc::eol_p];
00483       
00484       flight_period = flight_key
00485         >> +( ';' >> leg )
00486         >> ';' >> segment_section
00487         >> flight_period_end[doEndFlight (self._bomRoot, self._flightPeriod)]
00488         ;
00489 
00490       flight_period_end =
00491        bsc::ch_p(';')
00492         ;
00493       
00494       flight_key = airline_code
00495         >> ';' >> flight_number
00496         >> ';' >> date[storeDateRangeStart(self._flightPeriod)]
00497         >> ';' >> date[storeDateRangeEnd(self._flightPeriod)]
00498         >> ';' >> dow[storeDow(self._flightPeriod)]
00499         ;
00500 
00501       airline_code =bsc::
00502         lexeme_d[(airline_code_p)[storeAirlineCode(self._flightPeriod)] ]
00503         ;
00504         
00505       flight_number =bsc::
00506         lexeme_d[(flight_number_p)[storeFlightNumber(self._flightPeriod)] ]
00507         ;
00508 
00509       date =bsc::
00510         lexeme_d[(year_p)[bsc::assign_a(self._flightPeriod._itYear)]
00511                  >> '-'
00512                  >> (month_p)[bsc::assign_a(self._flightPeriod._itMonth)]
00513                  >> '-'
00514                  >> (day_p)[bsc::assign_a(self._flightPeriod._itDay)]
00515                  ]
00516         ;
00517 
00518       dow =bsc::lexeme_d[ dow_p ]
00519         ;
00520       
00521       leg = leg_key >> ';' >> leg_details >> +( ';' >> leg_cabin_details )
00522         ;
00523          
00524       leg_key =
00525         (airport_p)[storeLegBoardingPoint(self._flightPeriod)]
00526         >> ';'
00527         >> (airport_p)[storeLegOffPoint(self._flightPeriod)]
00528         ;
00529          
00530       leg_details =
00531         time[storeBoardingTime(self._flightPeriod)]
00532         >> !(date_offset)
00533         >> ';'
00534         >> time[storeOffTime(self._flightPeriod)]
00535         >> !(date_offset)
00536         >> ';'
00537         >> time[storeElapsedTime(self._flightPeriod)]
00538         ;
00539         
00540       time =bsc::
00541         lexeme_d[(hours_p)[bsc::assign_a(self._flightPeriod._itHours)]
00542                  >> ':'
00543                  >> (minutes_p)[bsc::assign_a(self._flightPeriod._itMinutes)]
00544                  >> !(':'
00545                       >> (seconds_p)[bsc::assign_a(self._flightPeriod._itSeconds)])
00546                  ]
00547         ;
00548 
00549       date_offset =bsc::ch_p('/')
00550         >> (int1_p)[bsc::assign_a(self._flightPeriod._dateOffset)]
00551         ;          
00552         
00553       leg_cabin_details = (cabin_code_p)[storeLegCabinCode(self._flightPeriod)]
00554         >> ';' >> (bsc::ureal_p)[storeCapacity(self._flightPeriod)]
00555         ;
00556         
00557       segment_key =
00558         (airport_p)[storeSegmentBoardingPoint(self._flightPeriod)]
00559         >> ';'
00560         >> (airport_p)[storeSegmentOffPoint(self._flightPeriod)]
00561         ;
00562          
00563       segment_section =
00564         generic_segment | specific_segment_list
00565         ;
00566 
00567       generic_segment =bsc::
00568         ch_p('0')[storeSegmentSpecificity(self._flightPeriod)]
00569         >> +(';' >> segment_cabin_details)
00570         ;
00571 
00572       specific_segment_list =bsc::
00573         ch_p('1')[storeSegmentSpecificity(self._flightPeriod)]
00574         >> +(';' >> segment_key >> full_segment_cabin_details)
00575         ;
00576 
00577       full_segment_cabin_details =
00578         +(';' >> segment_cabin_details)
00579         ;
00580 
00581       segment_cabin_details =
00582         (cabin_code_p)[storeSegmentCabinCode(self._flightPeriod)]
00583         >> ';' >> (class_code_list_p)[storeClasses(self._flightPeriod)]
00584         >> *(';' >> family_cabin_details)
00585         ;
00586 
00587       family_cabin_details =
00588         (family_code_p)[storeFamilyCode(self._flightPeriod)]
00589         >> ';'
00590         >> (class_code_list_p)[storeFClasses(self._flightPeriod)]
00591         ;
00592         
00593       // BOOST_SPIRIT_DEBUG_NODE (FlightPeriodParser);
00594       BOOST_SPIRIT_DEBUG_NODE (flight_period_list);
00595       BOOST_SPIRIT_DEBUG_NODE (flight_period);
00596       BOOST_SPIRIT_DEBUG_NODE (not_to_be_parsed);
00597       BOOST_SPIRIT_DEBUG_NODE (flight_period_end);
00598       BOOST_SPIRIT_DEBUG_NODE (flight_key);
00599       BOOST_SPIRIT_DEBUG_NODE (airline_code);
00600       BOOST_SPIRIT_DEBUG_NODE (flight_number);
00601       BOOST_SPIRIT_DEBUG_NODE (date);
00602       BOOST_SPIRIT_DEBUG_NODE (dow);
00603       BOOST_SPIRIT_DEBUG_NODE (leg);
00604       BOOST_SPIRIT_DEBUG_NODE (leg_key);
00605       BOOST_SPIRIT_DEBUG_NODE (leg_details);
00606       BOOST_SPIRIT_DEBUG_NODE (time);
00607       BOOST_SPIRIT_DEBUG_NODE (date_offset);
00608       BOOST_SPIRIT_DEBUG_NODE (leg_cabin_details);
00609       BOOST_SPIRIT_DEBUG_NODE (segment_section);
00610       BOOST_SPIRIT_DEBUG_NODE (segment_key);
00611       BOOST_SPIRIT_DEBUG_NODE (generic_segment);
00612       BOOST_SPIRIT_DEBUG_NODE (specific_segment_list);
00613       BOOST_SPIRIT_DEBUG_NODE (full_segment_cabin_details);
00614       BOOST_SPIRIT_DEBUG_NODE (segment_cabin_details);
00615       BOOST_SPIRIT_DEBUG_NODE (family_cabin_details);
00616     }
00617 
00618     // //////////////////////////////////////////////////////////////////
00619     template<typename ScannerT>
00620    bsc::rule<ScannerT> const&
00621     FlightPeriodParser::definition<ScannerT>::start() const {
00622       return flight_period_list;
00623     }
00624     
00625   }
00626 
00627 
00629   //
00630   //  Entry class for the file parser
00631   //
00633 
00634   // //////////////////////////////////////////////////////////////////////
00635   FlightPeriodFileParser::
00636   FlightPeriodFileParser (stdair::BomRoot& ioBomRoot,
00637                           const stdair::Filename_T& iFilename)
00638     : _filename (iFilename), _bomRoot (ioBomRoot) {
00639     init();
00640   }
00641 
00642   // //////////////////////////////////////////////////////////////////////
00643   void FlightPeriodFileParser::init() {
00644     // Check that the file exists and is readable
00645     const bool doesExistAndIsReadable =
00646       stdair::BasFileMgr::doesExistAndIsReadable (_filename);
00647 
00648     if (doesExistAndIsReadable == false) {
00649       STDAIR_LOG_ERROR ("The schedule file " << _filename
00650                         << " does not exist or can not be read.");
00651       
00652       throw ScheduleInputFileNotFoundException ("The schedule file " + _filename
00653                                                 + " does not exist or can not be read");
00654     }
00655     
00656     // Open the file
00657     _startIterator = iterator_t (_filename);
00658 
00659     // Check the filename exists and can be open
00660     if (!_startIterator) {
00661       STDAIR_LOG_ERROR ("The schedule file " << _filename << " can not be open."
00662                           << std::endl);
00663 
00664       throw ScheduleInputFileNotFoundException ("The file " + _filename
00665                                                 + " does not exist or can not be read");
00666     }
00667 
00668     // Create an EOF iterator
00669     _endIterator = _startIterator.make_end();
00670   }
00671     
00672   // //////////////////////////////////////////////////////////////////////
00673   bool FlightPeriodFileParser::generateInventories () {
00674     bool oResult = false;
00675       
00676     STDAIR_LOG_DEBUG ("Parsing schedule input file: " << _filename);
00677 
00678     // Initialise the parser (grammar) with the helper/staging structure.
00679     ScheduleParserHelper::FlightPeriodParser lFPParser (_bomRoot, 
00680                                                         _flightPeriod);
00681       
00682     // Launch the parsing of the file and, thanks to the doEndFlight
00683     // call-back structure, the building of the whole BomRoot BOM
00684     // (i.e., including Inventory, FlightDate, LegDate, SegmentDate, etc.)
00685     bsc::parse_info<iterator_t> info =
00686       bsc::parse (_startIterator, _endIterator, lFPParser,
00687                   bsc::space_p - bsc::eol_p);
00688   
00689     // Retrieves whether or not the parsing was successful
00690     oResult = info.hit;
00691       
00692     const std::string hasBeenFullyReadStr = (info.full == true)?"":"not ";
00693     if (oResult == true) {
00694       STDAIR_LOG_DEBUG ("Parsing of schedule input file: " << _filename
00695                        << " succeeded: read " << info.length
00696                        << " characters. The input file has "
00697                        << hasBeenFullyReadStr
00698                        << "been fully read. Stop point: " << info.stop);
00699         
00700     } else {
00701       // TODO: decide whether to throw an exception
00702       STDAIR_LOG_ERROR ("Parsing of schedule input file: " << _filename
00703                        << " failed: read " << info.length
00704                        << " characters. The input file has "
00705                        << hasBeenFullyReadStr
00706                        << "been fully read. Stop point: " << info.stop);
00707     }
00708 
00709     return oResult;
00710   }
00711     
00712 }