$treeview $search $mathjax
AirTSP Logo  1.01.2
$projectbrief
$projectbrief
$searchbox

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