$treeview $search $mathjax
AirInv Logo  1.00.0
$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/stdair_exceptions.hpp>
00008 #include <stdair/stdair_types.hpp>
00009 #include <stdair/bom/BomRoot.hpp>
00010 #include <stdair/service/Logger.hpp>
00011 // AirInv
00012 #include <airinv/command/InventoryGenerator.hpp>
00013 // #define BOOST_SPIRIT_DEBUG
00014 #include <airinv/command/ScheduleParserHelper.hpp>
00015 
00016 //
00017 namespace bsc = boost::spirit::classic;
00018 
00019 namespace AIRINV {
00020 
00021   namespace ScheduleParserHelper {
00022       
00023     // //////////////////////////////////////////////////////////////////
00024     //  Semantic actions
00025     // //////////////////////////////////////////////////////////////////
00026 
00027     ParserSemanticAction::
00028     ParserSemanticAction (FlightPeriodStruct& ioFlightPeriod)
00029       : _flightPeriod (ioFlightPeriod) {
00030     }      
00031 
00032     // //////////////////////////////////////////////////////////////////
00033     storeAirlineCode::
00034     storeAirlineCode (FlightPeriodStruct& ioFlightPeriod)
00035       : ParserSemanticAction (ioFlightPeriod) {
00036     }
00037     
00038     // //////////////////////////////////////////////////////////////////
00039     void storeAirlineCode::operator() (iterator_t iStr,
00040                                        iterator_t iStrEnd) const { 
00041       const stdair::AirlineCode_T lAirlineCode (iStr, iStrEnd);
00042       _flightPeriod._airlineCode = lAirlineCode;
00043                 
00044       // As that's the beginning of a new flight, the list of legs
00045       // must be reset
00046       _flightPeriod._legList.clear();
00047     }
00048 
00049     // //////////////////////////////////////////////////////////////////
00050     storeFlightNumber::
00051     storeFlightNumber (FlightPeriodStruct& ioFlightPeriod)
00052       : ParserSemanticAction (ioFlightPeriod) {
00053     }
00054 
00055     // //////////////////////////////////////////////////////////////////
00056     void storeFlightNumber::operator() (unsigned int iNumber) const { 
00057       _flightPeriod._flightNumber = 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     // //////////////////////////////////////////////////////////////////
00105     storeDow::storeDow (FlightPeriodStruct& ioFlightPeriod)
00106       : ParserSemanticAction (ioFlightPeriod) {
00107     }
00108 
00109     // //////////////////////////////////////////////////////////////////
00110     void storeDow::operator() (iterator_t iStr, iterator_t iStrEnd) const {
00111       stdair::DOW_String_T lDow (iStr, iStrEnd);
00112       _flightPeriod._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       //STDAIR_LOG_DEBUG ("Airline code: " << lAirlineCode);
00174     }
00175 
00176     // //////////////////////////////////////////////////////////////////
00177     storeOperatingFlightNumber::
00178     storeOperatingFlightNumber (FlightPeriodStruct& ioFlightPeriod)
00179       : ParserSemanticAction (ioFlightPeriod) {
00180     }
00181 
00182     // //////////////////////////////////////////////////////////////////
00183     void storeOperatingFlightNumber::operator() (unsigned int iNumber) const { 
00184       _flightPeriod._itLeg._flightNumber = iNumber;
00185       //STDAIR_LOG_DEBUG ("Flight number: " << iNumber);
00186     }
00187 
00188     // //////////////////////////////////////////////////////////////////
00189     storeBoardingTime::
00190     storeBoardingTime (FlightPeriodStruct& ioFlightPeriod)
00191       : ParserSemanticAction (ioFlightPeriod) {
00192     }
00193     
00194     // //////////////////////////////////////////////////////////////////
00195     void storeBoardingTime::operator() (iterator_t iStr,
00196                                         iterator_t iStrEnd) const {
00197       _flightPeriod._itLeg._boardingTime = _flightPeriod.getTime();
00198         
00199       // Reset the number of seconds
00200       _flightPeriod._itSeconds = 0;
00201 
00202       // Reset the date off-set
00203       _flightPeriod._dateOffset = 0;
00204     }
00205 
00206     // //////////////////////////////////////////////////////////////////
00207     storeOffTime::
00208     storeOffTime (FlightPeriodStruct& ioFlightPeriod)
00209       : ParserSemanticAction (ioFlightPeriod) {
00210     }
00211     
00212     // //////////////////////////////////////////////////////////////////
00213     void storeOffTime::operator() (iterator_t iStr,
00214                                    iterator_t iStrEnd) const {
00215       _flightPeriod._itLeg._offTime = _flightPeriod.getTime();
00216         
00217       // Reset the number of seconds
00218       _flightPeriod._itSeconds = 0;
00219 
00220       // As the boarding date off set is optional, it can be set only
00221       // afterwards, based on the staging date off-set value
00222       // (_flightPeriod._dateOffset).
00223       const stdair::DateOffset_T lDateOffset (_flightPeriod._dateOffset);
00224       _flightPeriod._itLeg._boardingDateOffset = lDateOffset;
00225     }
00226 
00227     // //////////////////////////////////////////////////////////////////
00228     storeElapsedTime::
00229     storeElapsedTime (FlightPeriodStruct& ioFlightPeriod)
00230       : ParserSemanticAction (ioFlightPeriod) {
00231     }
00232     
00233     // //////////////////////////////////////////////////////////////////
00234     void storeElapsedTime::operator() (iterator_t iStr,
00235                                        iterator_t iStrEnd) const {
00236       _flightPeriod._itLeg._elapsed = _flightPeriod.getTime();
00237         
00238       // Reset the number of seconds
00239       _flightPeriod._itSeconds = 0;
00240 
00241       // As the boarding date off set is optional, it can be set only
00242       // afterwards, based on the staging date off-set value
00243       // (_flightPeriod._dateOffset).
00244       const stdair::DateOffset_T lDateOffset (_flightPeriod._dateOffset);
00245       _flightPeriod._itLeg._offDateOffset = lDateOffset;
00246     }
00247 
00248     // //////////////////////////////////////////////////////////////////
00249     storeLegCabinCode::
00250     storeLegCabinCode (FlightPeriodStruct& ioFlightPeriod)
00251       : ParserSemanticAction (ioFlightPeriod) {
00252     }
00253     
00254     // //////////////////////////////////////////////////////////////////
00255     void storeLegCabinCode::operator() (char iChar) const { 
00256       _flightPeriod._itLegCabin._cabinCode = iChar; 
00257       //std::cout << "Cabin code: " << iChar << std::endl;
00258     }
00259 
00260     // //////////////////////////////////////////////////////////////////
00261     storeCapacity::
00262     storeCapacity (FlightPeriodStruct& ioFlightPeriod)
00263       : ParserSemanticAction (ioFlightPeriod) {
00264     }
00265     
00266     // //////////////////////////////////////////////////////////////////
00267     void storeCapacity::operator() (double iReal) const { 
00268       _flightPeriod._itLegCabin._saleableCapacity = iReal; 
00269       //std::cout << "Capacity: " << iReal << std::endl;
00270 
00271       // The capacity is the last (according to the arrival order
00272       // within the schedule input file) detail of the leg cabin. Hence,
00273       // when a capacity is parsed, it means that the full cabin
00274       // details have already been parsed as well: the cabin can
00275       // thus be added to the leg.
00276       _flightPeriod._itLeg._cabinList.push_back (_flightPeriod._itLegCabin);
00277     }
00278 
00279     // //////////////////////////////////////////////////////////////////
00280     storeSegmentSpecificity::
00281     storeSegmentSpecificity (FlightPeriodStruct& ioFlightPeriod)
00282       : ParserSemanticAction (ioFlightPeriod) {
00283     }
00284 
00285     // //////////////////////////////////////////////////////////////////
00286     void storeSegmentSpecificity::operator() (char iChar) const {
00287       if (iChar == '0') {
00288         _flightPeriod._areSegmentDefinitionsSpecific = false;
00289       } else {
00290         _flightPeriod._areSegmentDefinitionsSpecific = true;
00291       }
00292 
00293       // Do a few sanity checks: the two lists should get exactly the same
00294       // content (in terms of airport codes). The only difference is that one
00295       // is a STL set, and the other a STL vector.
00296       assert (_flightPeriod._airportList.size()
00297               == _flightPeriod._airportOrderedList.size());
00298       assert (_flightPeriod._airportList.size() >= 2);
00299         
00300       // Since all the legs have now been parsed, we get all the airports
00301       // and the segments may be built.
00302       _flightPeriod.buildSegments();
00303     }
00304       
00305     // //////////////////////////////////////////////////////////////////
00306     storeSegmentBoardingPoint::
00307     storeSegmentBoardingPoint (FlightPeriodStruct& ioFlightPeriod)
00308       : ParserSemanticAction (ioFlightPeriod) {
00309     }
00310 
00311     // //////////////////////////////////////////////////////////////////
00312     void storeSegmentBoardingPoint::operator() (iterator_t iStr,
00313                                              iterator_t iStrEnd) const {
00314       stdair::AirportCode_T lBoardingPoint (iStr, iStrEnd);
00315       _flightPeriod._itSegment._boardingPoint = lBoardingPoint;
00316     }
00317 
00318     // //////////////////////////////////////////////////////////////////
00319     storeSegmentOffPoint::
00320     storeSegmentOffPoint (FlightPeriodStruct& ioFlightPeriod)
00321       : ParserSemanticAction (ioFlightPeriod) {
00322     }
00323 
00324     // //////////////////////////////////////////////////////////////////
00325     void storeSegmentOffPoint::operator() (iterator_t iStr,
00326                                            iterator_t iStrEnd) const {
00327       stdair::AirportCode_T lOffPoint (iStr, iStrEnd);
00328       _flightPeriod._itSegment._offPoint = lOffPoint;
00329     }
00330 
00331     // //////////////////////////////////////////////////////////////////
00332     storeSegmentCabinCode::
00333     storeSegmentCabinCode (FlightPeriodStruct& ioFlightPeriod)
00334       : ParserSemanticAction (ioFlightPeriod) {
00335     }
00336     
00337     // //////////////////////////////////////////////////////////////////
00338     void storeSegmentCabinCode::operator() (char iChar) const { 
00339       _flightPeriod._itSegmentCabin._cabinCode = iChar; 
00340     }
00341 
00342     // //////////////////////////////////////////////////////////////////
00343     storeClasses::
00344     storeClasses (FlightPeriodStruct& ioFlightPeriod)
00345       : ParserSemanticAction (ioFlightPeriod) {
00346     }
00347 
00348     // //////////////////////////////////////////////////////////////////
00349     void storeClasses::operator() (iterator_t iStr,
00350                                    iterator_t iStrEnd) const {
00351       std::string lClasses (iStr, iStrEnd);
00352       _flightPeriod._itSegmentCabin._itFareFamily._classes = lClasses;
00353 
00354       // The list of classes is the last (according to the arrival order
00355       // within the schedule input file) detail of the segment cabin. Hence,
00356       // when a list of classes is parsed, it means that the full segment
00357       // cabin details have already been parsed as well: the segment cabin
00358       // can thus be added to the segment.
00359       if (_flightPeriod._areSegmentDefinitionsSpecific == true) {
00360         _flightPeriod.addSegmentCabin (_flightPeriod._itSegment,
00361                                        _flightPeriod._itSegmentCabin);
00362       } else {
00363         _flightPeriod.addSegmentCabin (_flightPeriod._itSegmentCabin);
00364       }
00365     }
00366 
00367     // //////////////////////////////////////////////////////////////////
00368     storeFamilyCode::
00369     storeFamilyCode (FlightPeriodStruct& ioFlightPeriod)
00370       : ParserSemanticAction (ioFlightPeriod) {
00371     }
00372     
00373     // //////////////////////////////////////////////////////////////////
00374     void storeFamilyCode::operator() (int iCode) const {
00375       std::ostringstream ostr;
00376       ostr << iCode;
00377       _flightPeriod._itSegmentCabin._itFareFamily._familyCode = ostr.str(); 
00378     }    
00379 
00380     // //////////////////////////////////////////////////////////////////
00381     storeFRAT5CurveKey::
00382     storeFRAT5CurveKey (FlightPeriodStruct& ioFlightPeriod)
00383       : ParserSemanticAction (ioFlightPeriod) {
00384     }
00385     
00386     // //////////////////////////////////////////////////////////////////
00387     void storeFRAT5CurveKey::operator() (iterator_t iStr,
00388                                          iterator_t iStrEnd) const { 
00389       const std::string lKey (iStr, iStrEnd);
00390       _flightPeriod._itSegmentCabin._itFareFamily._frat5CurveKey = lKey;
00391       //STDAIR_LOG_DEBUG ("FRAT5 key: " << lKey);
00392     } 
00393 
00394     // //////////////////////////////////////////////////////////////////
00395     storeFFDisutilityCurveKey::
00396     storeFFDisutilityCurveKey (FlightPeriodStruct& ioFlightPeriod)
00397       : ParserSemanticAction (ioFlightPeriod) {
00398     }
00399     
00400     // //////////////////////////////////////////////////////////////////
00401     void storeFFDisutilityCurveKey::operator() (iterator_t iStr,
00402                                                 iterator_t iStrEnd) const { 
00403       const std::string lKey (iStr, iStrEnd);
00404       _flightPeriod._itSegmentCabin._itFareFamily._ffDisutilityCurveKey = lKey;
00405     }
00406 
00407     // //////////////////////////////////////////////////////////////////
00408     storeFClasses::
00409     storeFClasses (FlightPeriodStruct& ioFlightPeriod)
00410       : ParserSemanticAction (ioFlightPeriod) {
00411     }
00412 
00413     // //////////////////////////////////////////////////////////////////
00414     void storeFClasses::operator() (iterator_t iStr,
00415                                     iterator_t iStrEnd) const {
00416       std::string lClasses (iStr, iStrEnd);
00417       FareFamilyStruct lFareFamily (_flightPeriod._itSegmentCabin._itFareFamily._familyCode, _flightPeriod._itSegmentCabin._itFareFamily._frat5CurveKey, _flightPeriod._itSegmentCabin._itFareFamily._ffDisutilityCurveKey, lClasses);
00418 
00419       // The list of classes is the last (according to the arrival order
00420       // within the schedule input file) detail of the segment cabin. Hence,
00421       // when a list of classes is parsed, it means that the full segment
00422       // cabin details have already been parsed as well: the segment cabin
00423       // can thus be added to the segment.
00424       if (_flightPeriod._areSegmentDefinitionsSpecific == true) {
00425         _flightPeriod.addFareFamily (_flightPeriod._itSegment,
00426                                      _flightPeriod._itSegmentCabin,
00427                                      lFareFamily);
00428       } else {
00429         _flightPeriod.addFareFamily (_flightPeriod._itSegmentCabin,
00430                                      lFareFamily);
00431       }
00432     } 
00433 
00434     // //////////////////////////////////////////////////////////////////
00435     doEndFlight::
00436     doEndFlight (stdair::BomRoot& ioBomRoot,
00437                  FlightPeriodStruct& ioFlightPeriod)
00438       : ParserSemanticAction (ioFlightPeriod),
00439         _bomRoot (ioBomRoot) {
00440     }
00441     
00442     // //////////////////////////////////////////////////////////////////
00443     // void doEndFlight::operator() (char iChar) const {
00444     void doEndFlight::operator() (iterator_t iStr,
00445                                   iterator_t iStrEnd) const {
00446 
00447       assert (_flightPeriod._legAlreadyDefined == true);
00448       _flightPeriod._legList.push_back (_flightPeriod._itLeg);
00449         
00450       // The lists of legs and cabins must be reset
00451       _flightPeriod._legAlreadyDefined = false;
00452       _flightPeriod._itLeg._cabinList.clear();
00453         
00454       // DEBUG: Display the result
00455       STDAIR_LOG_DEBUG ("FlightPeriod: " << _flightPeriod.describe());
00456 
00457       // Create the FlightDate BOM objects, and potentially the intermediary
00458       // objects (e.g., Inventory).
00459       InventoryGenerator::createFlightDate (_bomRoot, _flightPeriod);
00460     }
00461 
00462       
00463     // ///////////////////////////////////////////////////////////////////
00464     //
00465     //  Utility Parsers
00466     //
00467     // ///////////////////////////////////////////////////////////////////
00469     int1_p_t int1_p;
00470     
00472     uint2_p_t uint2_p;
00473     
00475     uint4_p_t uint4_p;
00476     
00478     uint1_4_p_t uint1_4_p;
00479 
00481     repeat_p_t airline_code_p (chset_t("0-9A-Z").derived(), 2, 3);
00482       
00484     bounded1_4_p_t flight_number_p (uint1_4_p.derived(), 0u, 9999u);
00485 
00487     bounded4_p_t year_p (uint4_p.derived(), 2000u, 2099u);
00488       
00490     bounded2_p_t month_p (uint2_p.derived(), 1u, 12u);
00491 
00493     bounded2_p_t day_p (uint2_p.derived(), 1u, 31u);
00494      
00496     repeat_p_t dow_p (chset_t("0-1").derived().derived(), 7, 7);
00497 
00499     repeat_p_t airport_p (chset_t("0-9A-Z").derived(), 3, 3);
00500       
00502     bounded2_p_t hours_p (uint2_p.derived(), 0u, 23u);
00503 
00505     bounded2_p_t minutes_p (uint2_p.derived(), 0u, 59u);
00506 
00508     bounded2_p_t seconds_p (uint2_p.derived(), 0u, 59u);
00509 
00511     chset_t cabin_code_p ("A-Z");
00512 
00514     int1_p_t family_code_p;
00515     
00517     repeat_p_t key_p (chset_t("0-9A-Z").derived(), 1, 10);
00518       
00520     repeat_p_t class_code_list_p (chset_t("A-Z").derived(), 1, 26);
00521 
00522 
00523     // //////////////////////////////////////////////////////////////////
00524     //  (Boost Spirit) Grammar Definition
00525     // //////////////////////////////////////////////////////////////////
00526 
00527     // //////////////////////////////////////////////////////////////////
00528     FlightPeriodParser::
00529     FlightPeriodParser (stdair::BomRoot& ioBomRoot,
00530                         FlightPeriodStruct& ioFlightPeriod) 
00531       : _bomRoot (ioBomRoot),
00532         _flightPeriod (ioFlightPeriod) {
00533     }
00534 
00535     // //////////////////////////////////////////////////////////////////
00536     template<typename ScannerT>
00537     FlightPeriodParser::definition<ScannerT>::
00538     definition (FlightPeriodParser const& self) {
00539 
00540       flight_period_list = *( not_to_be_parsed | flight_period )
00541         ;
00542       
00543       not_to_be_parsed =
00544         bsc::lexeme_d[ bsc::comment_p("//") | bsc::comment_p("/*", "*/")
00545                        | bsc::space_p ]
00546         ;
00547 
00548       flight_period = flight_key
00549         >> +( ';' >> leg )
00550         >> ';' >> segment_section
00551         >> flight_period_end[doEndFlight (self._bomRoot, self._flightPeriod)]
00552         ;
00553 
00554       flight_period_end = bsc::ch_p(';')
00555         ;
00556       
00557       flight_key = airline_code
00558         >> ';' >> flight_number
00559         >> ';' >> date[storeDateRangeStart(self._flightPeriod)]
00560         >> ';' >> date[storeDateRangeEnd(self._flightPeriod)]
00561         >> ';' >> dow[storeDow(self._flightPeriod)]
00562         ;
00563 
00564       airline_code =
00565         bsc::lexeme_d[(airline_code_p)[storeAirlineCode(self._flightPeriod)]]
00566         ;
00567         
00568       flight_number =
00569         bsc::lexeme_d[(flight_number_p)[storeFlightNumber(self._flightPeriod)]]
00570         ;
00571 
00572       date =
00573         bsc::lexeme_d[(year_p)[bsc::assign_a(self._flightPeriod._itYear)]
00574           >> '-' >> (month_p)[bsc::assign_a(self._flightPeriod._itMonth)]
00575           >> '-' >> (day_p)[bsc::assign_a(self._flightPeriod._itDay)]]
00576         ;
00577 
00578       dow = bsc::lexeme_d[ dow_p ]
00579         ;
00580 
00581       leg = !( operating_leg_details >> ';' )
00582         >> leg_key
00583         >> ';' >> leg_details
00584         >> +( ';' >> leg_cabin_details )
00585         ;
00586 
00587       leg_key = (airport_p)[storeLegBoardingPoint(self._flightPeriod)]
00588          >> ';'
00589          >> (airport_p)[storeLegOffPoint(self._flightPeriod)]
00590          ;
00591  
00592       operating_leg_details =
00593         bsc::lexeme_d[(airline_code_p)[storeOperatingAirlineCode(self._flightPeriod)] ]
00594         >> ";"
00595         >> bsc::lexeme_d[(flight_number_p)[storeOperatingFlightNumber(self._flightPeriod)] ]
00596         ;
00597          
00598       leg_details =
00599         time[storeBoardingTime(self._flightPeriod)]
00600         >> !(date_offset)
00601         >> ';'
00602         >> time[storeOffTime(self._flightPeriod)]
00603         >> !(date_offset)
00604         >> ';'
00605         >> time[storeElapsedTime(self._flightPeriod)]
00606         ;
00607         
00608       time =
00609         bsc::lexeme_d[(hours_p)[bsc::assign_a(self._flightPeriod._itHours)]
00610           >> ':' >> (minutes_p)[bsc::assign_a(self._flightPeriod._itMinutes)]
00611           >> !(':' >> (seconds_p)[bsc::assign_a(self._flightPeriod._itSeconds)])]
00612         ;
00613 
00614       date_offset =
00615         bsc::ch_p('/')
00616         >> (int1_p)[bsc::assign_a(self._flightPeriod._dateOffset)]
00617         ;          
00618         
00619       leg_cabin_details =
00620         (cabin_code_p)[storeLegCabinCode(self._flightPeriod)]
00621         >> ';' >> (bsc::ureal_p)[storeCapacity(self._flightPeriod)]
00622         ;
00623         
00624       segment_key =
00625         (airport_p)[storeSegmentBoardingPoint(self._flightPeriod)]
00626         >> ';'
00627         >> (airport_p)[storeSegmentOffPoint(self._flightPeriod)]
00628         ;
00629          
00630       segment_section =
00631         generic_segment | specific_segment_list
00632         ;
00633 
00634       generic_segment =
00635         bsc::ch_p('0')[storeSegmentSpecificity(self._flightPeriod)]
00636         >> +(';' >> segment_cabin_details)
00637         ;
00638 
00639       specific_segment_list =
00640         bsc::ch_p('1')[storeSegmentSpecificity(self._flightPeriod)]
00641         >> +(';' >> segment_key >> full_segment_cabin_details)
00642         ;
00643 
00644       full_segment_cabin_details =
00645         +(';' >> segment_cabin_details)
00646         ;
00647 
00648       segment_cabin_details =
00649         (cabin_code_p)[storeSegmentCabinCode(self._flightPeriod)]
00650         >> ';' >> (class_code_list_p)[storeClasses(self._flightPeriod)]
00651         >> +(';' >> family_cabin_details)
00652         ;
00653 
00654       family_cabin_details =
00655         (family_code_p)[storeFamilyCode(self._flightPeriod)]
00656         >> ';'
00657         >> (key_p)[storeFRAT5CurveKey(self._flightPeriod)]
00658         >> ';'
00659         >> (key_p)[storeFFDisutilityCurveKey(self._flightPeriod)]
00660         >> ';'
00661         >> (class_code_list_p)[storeFClasses(self._flightPeriod)]
00662         ;
00663         
00664       // BOOST_SPIRIT_DEBUG_NODE (FlightPeriodParser);
00665       BOOST_SPIRIT_DEBUG_NODE (flight_period_list);
00666       BOOST_SPIRIT_DEBUG_NODE (not_to_be_parsed);
00667       BOOST_SPIRIT_DEBUG_NODE (flight_period);
00668       BOOST_SPIRIT_DEBUG_NODE (flight_period_end);
00669       BOOST_SPIRIT_DEBUG_NODE (flight_key);
00670       BOOST_SPIRIT_DEBUG_NODE (airline_code);
00671       BOOST_SPIRIT_DEBUG_NODE (flight_number);
00672       BOOST_SPIRIT_DEBUG_NODE (date);
00673       BOOST_SPIRIT_DEBUG_NODE (dow);
00674       BOOST_SPIRIT_DEBUG_NODE (leg);
00675       BOOST_SPIRIT_DEBUG_NODE (leg_key);
00676       BOOST_SPIRIT_DEBUG_NODE (leg_details);
00677       BOOST_SPIRIT_DEBUG_NODE (time);
00678       BOOST_SPIRIT_DEBUG_NODE (date_offset);
00679       BOOST_SPIRIT_DEBUG_NODE (leg_cabin_details);
00680       BOOST_SPIRIT_DEBUG_NODE (segment_section);
00681       BOOST_SPIRIT_DEBUG_NODE (segment_key);
00682       BOOST_SPIRIT_DEBUG_NODE (generic_segment);
00683       BOOST_SPIRIT_DEBUG_NODE (specific_segment_list);
00684       BOOST_SPIRIT_DEBUG_NODE (full_segment_cabin_details);
00685       BOOST_SPIRIT_DEBUG_NODE (segment_cabin_details);
00686       BOOST_SPIRIT_DEBUG_NODE (family_cabin_details);
00687     }
00688 
00689     // //////////////////////////////////////////////////////////////////
00690     template<typename ScannerT>
00691     bsc::rule<ScannerT> const&
00692     FlightPeriodParser::definition<ScannerT>::start() const {
00693       return flight_period_list;
00694     }    
00695   }
00696 
00697 
00699   //
00700   //  Entry class for the file parser
00701   //
00703 
00704   // //////////////////////////////////////////////////////////////////////
00705   FlightPeriodFileParser::
00706   FlightPeriodFileParser (stdair::BomRoot& ioBomRoot,
00707                           const stdair::Filename_T& iFilename)
00708     : _filename (iFilename), _bomRoot (ioBomRoot) {
00709     init();
00710   }
00711 
00712   // //////////////////////////////////////////////////////////////////////
00713   void FlightPeriodFileParser::init() {
00714     // Open the file
00715     _startIterator = iterator_t (_filename);
00716 
00717     // Check the filename exists and can be open
00718     if (!_startIterator) {
00719       std::ostringstream oMessage;
00720       oMessage << "The file " << _filename << " can not be open." << std::endl;
00721       STDAIR_LOG_ERROR (oMessage.str());
00722       throw ScheduleInputFileNotFoundException (oMessage.str());
00723     }
00724 
00725     // Create an EOF iterator
00726     _endIterator = _startIterator.make_end();
00727   }
00728     
00729   // //////////////////////////////////////////////////////////////////////
00730   bool FlightPeriodFileParser::generateInventories () {
00731     bool oResult = false;
00732       
00733     STDAIR_LOG_DEBUG ("Parsing schedule input file: " << _filename);
00734 
00735     // Initialise the parser (grammar) with the helper/staging structure.
00736     ScheduleParserHelper::FlightPeriodParser lFPParser (_bomRoot, _flightPeriod);
00737       
00738     // Launch the parsing of the file and, thanks to the doEndFlight
00739     // call-back structure, the building of the whole BomRoot BOM
00740     // (i.e., including Inventory, FlightDate, LegDate, SegmentDate, etc.)
00741     bsc::parse_info<iterator_t> info = bsc::parse (_startIterator, _endIterator,
00742                                                    lFPParser,
00743                                                    bsc::space_p - bsc::eol_p);
00744 
00745     // Retrieves whether or not the parsing was successful
00746     oResult = info.hit;
00747 
00748     const bool isFull = info.full;
00749       
00750     const std::string hasBeenFullyReadStr = (isFull  == true)?"":"not ";
00751     if (oResult == true && isFull == true) {
00752       STDAIR_LOG_DEBUG ("Parsing of schedule input file: " << _filename
00753                        << " succeeded: read " << info.length
00754                        << " characters. The input file has "
00755                        << hasBeenFullyReadStr
00756                        << "been fully read. Stop point: " << info.stop);
00757         
00758     } else {
00759       STDAIR_LOG_ERROR ("Parsing of schedule input file: " << _filename
00760                        << " failed: read " << info.length
00761                        << " characters. The input file has "
00762                        << hasBeenFullyReadStr
00763                        << "been fully read. Stop point: " << info.stop);
00764       throw ScheduleFileParsingFailedException ("Parsing of schedule input file: "
00765                                                 + _filename + " failed.");
00766     }
00767 
00768     return oResult;
00769   }
00770     
00771 }