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