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
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
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
00043
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
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
00083
00084
00085 const stdair::DateOffset_T oneDay (1);
00086 _flightPeriod._dateRangeEnd = _flightPeriod.getDate() + oneDay;
00087
00088
00089 _flightPeriod._dateRange =
00090 stdair::DatePeriod_T (_flightPeriod._dateRangeStart,
00091 _flightPeriod._dateRangeEnd);
00092
00093
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
00120 if (_flightPeriod._legAlreadyDefined == true) {
00121 _flightPeriod._legList.push_back (_flightPeriod._itLeg);
00122 } else {
00123 _flightPeriod._legAlreadyDefined = true;
00124 }
00125
00126
00127 _flightPeriod._itLeg._boardingPoint = lBoardingPoint;
00128
00129
00130
00131 _flightPeriod._itLeg._cabinList.clear();
00132
00133
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
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
00165 _flightPeriod._itSeconds = 0;
00166
00167
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
00183 _flightPeriod._itSeconds = 0;
00184
00185
00186
00187
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
00204 _flightPeriod._itSeconds = 0;
00205
00206
00207
00208
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
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
00235
00236
00237
00238
00239
00240
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
00259
00260
00261 assert (_flightPeriod._airportList.size()
00262 == _flightPeriod._airportOrderedList.size());
00263 assert (_flightPeriod._airportList.size() >= 2);
00264
00265
00266
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
00320
00321
00322
00323
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
00359
00360
00361
00362
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
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
00390 _flightPeriod._legAlreadyDefined = false;
00391 _flightPeriod._itLeg._cabinList.clear();
00392
00393
00394 STDAIR_LOG_DEBUG ("FlightPeriod: " << _flightPeriod.describe());
00395
00396
00397
00398 InventoryGenerator::createFlightPeriod (_bomRoot, _flightPeriod);
00399 }
00400
00401
00402
00403
00404
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
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
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
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
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
00657 _startIterator = iterator_t (_filename);
00658
00659
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
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
00679 ScheduleParserHelper::FlightPeriodParser lFPParser (_bomRoot,
00680 _flightPeriod);
00681
00682
00683
00684
00685 bsc::parse_info<iterator_t> info =
00686 bsc::parse (_startIterator, _endIterator, lFPParser,
00687 bsc::space_p - bsc::eol_p);
00688
00689
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
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 }