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