Go to the documentation of this file.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/OnDParserHelper.hpp>
00012 #include <airsched/command/OnDPeriodGenerator.hpp>
00013
00014 namespace AIRSCHED {
00015
00016 namespace OnDParserHelper {
00017
00018
00019
00020
00021
00022
00023
00024 ParserSemanticAction::
00025 ParserSemanticAction (OnDPeriodStruct& ioOnDPeriod)
00026 : _onDPeriod (ioOnDPeriod) {
00027 }
00028
00029
00030 storeOrigin::storeOrigin (OnDPeriodStruct& ioOnDPeriod)
00031 : ParserSemanticAction (ioOnDPeriod) {
00032 }
00033
00034
00035 void storeOrigin::operator() (iterator_t iStr,
00036 iterator_t iStrEnd) const {
00037 std::string lOrigin (iStr, iStrEnd);
00038
00039
00040
00041 _onDPeriod._origin = lOrigin;
00042 _onDPeriod._nbOfAirlines = 0;
00043 _onDPeriod._airlineCode = "";
00044 _onDPeriod._classCode = "";
00045 _onDPeriod._airlineCodeList.clear();
00046 _onDPeriod._classCodeList.clear();
00047 }
00048
00049
00050 storeDestination::storeDestination (OnDPeriodStruct& ioOnDPeriod)
00051 : ParserSemanticAction (ioOnDPeriod) {
00052 }
00053
00054
00055 void storeDestination::operator() (iterator_t iStr,
00056 iterator_t iStrEnd) const {
00057 std::string lDestination (iStr, iStrEnd);
00058
00059
00060
00061 _onDPeriod._destination = lDestination;
00062 }
00063
00064
00065 storeDateRangeStart::
00066 storeDateRangeStart (OnDPeriodStruct& ioOnDPeriod)
00067 : ParserSemanticAction (ioOnDPeriod) {
00068 }
00069
00070
00071 void storeDateRangeStart::operator() (iterator_t iStr,
00072 iterator_t iStrEnd) const {
00073 _onDPeriod._dateRangeStart = _onDPeriod.getDate();
00074
00075
00076
00077
00078 _onDPeriod._itSeconds = 0;
00079 }
00080
00081
00082 storeDateRangeEnd::
00083 storeDateRangeEnd (OnDPeriodStruct& ioOnDPeriod)
00084 : ParserSemanticAction (ioOnDPeriod) {
00085 }
00086
00087
00088 void storeDateRangeEnd::operator() (iterator_t iStr,
00089 iterator_t iStrEnd) const {
00090
00091
00092
00093 const stdair::DateOffset_T oneDay (1);
00094 _onDPeriod._dateRangeEnd = _onDPeriod.getDate() + oneDay;
00095
00096
00097
00098
00099 _onDPeriod._datePeriod =
00100 stdair::DatePeriod_T (_onDPeriod._dateRangeStart,
00101 _onDPeriod._dateRangeEnd);
00102
00103
00104 _onDPeriod._itSeconds = 0;
00105 }
00106
00107
00108 storeStartRangeTime::
00109 storeStartRangeTime (OnDPeriodStruct& ioOnDPeriod)
00110 : ParserSemanticAction (ioOnDPeriod) {
00111 }
00112
00113
00114 void storeStartRangeTime::operator() (iterator_t iStr,
00115 iterator_t iStrEnd) const {
00116 _onDPeriod._timeRangeStart = _onDPeriod.getTime();
00117
00118
00119 _onDPeriod._itSeconds = 0;
00120 }
00121
00122
00123 storeEndRangeTime::
00124 storeEndRangeTime (OnDPeriodStruct& ioOnDPeriod)
00125 : ParserSemanticAction (ioOnDPeriod) {
00126 }
00127
00128
00129 void storeEndRangeTime::operator() (iterator_t iStr,
00130 iterator_t iStrEnd) const {
00131 _onDPeriod._timeRangeEnd = _onDPeriod.getTime();
00132
00133
00134 _onDPeriod._itSeconds = 0;
00135 }
00136
00137
00138 storeAirlineCode::
00139 storeAirlineCode (OnDPeriodStruct& ioOnDPeriod)
00140 : ParserSemanticAction (ioOnDPeriod) {
00141 }
00142
00143
00144 void storeAirlineCode::operator() (iterator_t iStr,
00145 iterator_t iStrEnd) const {
00146 const std::string lAirlineCodeStr (iStr, iStrEnd);
00147 const stdair::AirlineCode_T lAirlineCode(lAirlineCodeStr);
00148
00149 if (_onDPeriod._airlineCodeList.size() > 0) {
00150
00151 std::ostringstream ostr;
00152 ostr << _onDPeriod._airlineCode << lAirlineCode;
00153 _onDPeriod._airlineCode = ostr.str();
00154
00155 const stdair::AirlineCode_T lPreviousAirlineCode =
00156 _onDPeriod._airlineCodeList.back();
00157 if (lPreviousAirlineCode != lAirlineCode) {
00158 _onDPeriod._nbOfAirlines = _onDPeriod._nbOfAirlines + 1;
00159 }
00160 }
00161 else {
00162 _onDPeriod._airlineCode = lAirlineCode;
00163 _onDPeriod._nbOfAirlines = 1;
00164 }
00165 _onDPeriod._airlineCodeList.push_back (lAirlineCode);
00166
00167
00168 }
00169
00170
00171 storeClassCode::
00172 storeClassCode (OnDPeriodStruct& ioOnDPeriod)
00173 : ParserSemanticAction (ioOnDPeriod) {
00174 }
00175
00176
00177 void storeClassCode::operator() (char iChar) const {
00178 std::ostringstream ostr;
00179 ostr << iChar;
00180 std::string classCodeStr = ostr.str();
00181 const stdair::ClassCode_T lClassCode (classCodeStr);
00182 _onDPeriod._classCodeList.push_back(lClassCode);
00183
00184
00185
00186 std::ostringstream ostrr;
00187 ostrr << _onDPeriod._classCode << classCodeStr;
00188 _onDPeriod._classCode = ostrr.str();
00189
00190 }
00191
00192
00193 doEndOnD::doEndOnD (stdair::BomRoot& ioBomRoot, OnDPeriodStruct& ioOnDPeriod)
00194 : ParserSemanticAction (ioOnDPeriod),
00195 _bomRoot (ioBomRoot) {
00196 }
00197
00198
00199 void doEndOnD::operator() (iterator_t iStr, iterator_t iStrEnd) const {
00200
00201
00202
00203
00204
00205 OnDPeriodGenerator::createOnDPeriod (_bomRoot, _onDPeriod);
00206 }
00207
00208
00209
00210
00211
00212
00213
00215 uint2_p_t uint2_p;
00216
00218 uint4_p_t uint4_p;
00219
00221 uint1_4_p_t uint1_4_p;
00222
00224 chset_t alpha_cap_set_p ("A-Z");
00225
00227 repeat_p_t airport_p (chset_t("0-9A-Z").derived(), 3, 3);
00228
00230 repeat_p_t airline_code_p (alpha_cap_set_p.derived(), 2, 3);
00231
00233 bounded4_p_t year_p (uint4_p.derived(), 2000u, 2099u);
00234
00236 bounded2_p_t month_p (uint2_p.derived(), 1u, 12u);
00237
00239 bounded2_p_t day_p (uint2_p.derived(), 1u, 31u);
00240
00242 bounded2_p_t hours_p (uint2_p.derived(), 0u, 23u);
00243
00245 bounded2_p_t minutes_p (uint2_p.derived(), 0u, 59u);
00246
00248 bounded2_p_t seconds_p (uint2_p.derived(), 0u, 59u);
00249
00251 chset_t class_code_p ("A-Z");
00252
00254
00255
00256
00258
00259
00260 OnDParser::
00261 OnDParser (stdair::BomRoot& ioBomRoot, OnDPeriodStruct& ioOnDPeriod)
00262 : _bomRoot (ioBomRoot), _onDPeriod (ioOnDPeriod) {
00263 }
00264
00265
00266 template<typename ScannerT>
00267 OnDParser::definition<ScannerT>::definition (OnDParser const& self) {
00268
00269 ond_list = *( boost::spirit::classic::comment_p("//")
00270 | boost::spirit::classic::comment_p("/*", "*/")
00271 | ond )
00272 ;
00273
00274 ond = ond_key
00275 >> +( ';' >> segment )
00276 >> ond_end[doEndOnD(self._bomRoot, self._onDPeriod)]
00277 ;
00278
00279 ond_end = boost::spirit::classic::ch_p(';')
00280 ;
00281
00282 ond_key = (airport_p)[storeOrigin(self._onDPeriod)]
00283 >> ';' >> (airport_p)[storeDestination(self._onDPeriod)]
00284 >> ';' >> date[storeDateRangeStart(self._onDPeriod)]
00285 >> ';' >> date[storeDateRangeEnd(self._onDPeriod)]
00286 >> ';' >> time[storeStartRangeTime(self._onDPeriod)]
00287 >> ';' >> time[storeEndRangeTime(self._onDPeriod)]
00288 ;
00289
00290 date = boost::spirit::classic::
00291 lexeme_d[(year_p)[boost::spirit::classic::
00292 assign_a(self._onDPeriod._itYear)]
00293 >> '-'
00294 >> (month_p)[boost::spirit::classic::
00295 assign_a(self._onDPeriod._itMonth)]
00296 >> '-'
00297 >> (day_p)[boost::spirit::classic::
00298 assign_a(self._onDPeriod._itDay)]]
00299 ;
00300
00301 time = boost::spirit::classic::
00302 lexeme_d[(hours_p)[boost::spirit::classic::
00303 assign_a(self._onDPeriod._itHours)]
00304 >> ':'
00305 >> (minutes_p)[boost::spirit::classic::
00306 assign_a(self._onDPeriod._itMinutes)]
00307 >> !(':' >> (seconds_p)[boost::spirit::classic::
00308 assign_a(self._onDPeriod._itSeconds)])]
00309 ;
00310
00311 segment = boost::spirit::classic::
00312 lexeme_d[(airline_code_p)[storeAirlineCode(self._onDPeriod)]]
00313 >> ';' >> (class_code_p)[storeClassCode(self._onDPeriod)]
00314 ;
00315
00316
00317 BOOST_SPIRIT_DEBUG_NODE (ond_list);
00318 BOOST_SPIRIT_DEBUG_NODE (ond);
00319 BOOST_SPIRIT_DEBUG_NODE (segment);
00320 BOOST_SPIRIT_DEBUG_NODE (ond_key);
00321 BOOST_SPIRIT_DEBUG_NODE (ond_end);
00322 BOOST_SPIRIT_DEBUG_NODE (date);
00323 BOOST_SPIRIT_DEBUG_NODE (time);
00324
00325 }
00326
00327
00328 template<typename ScannerT>
00329 boost::spirit::classic::rule<ScannerT> const&
00330 OnDParser::definition<ScannerT>::start() const {
00331 return ond_list;
00332 }
00333 }
00334
00336
00337
00338
00340
00341
00342 OnDPeriodFileParser::OnDPeriodFileParser (const stdair::Filename_T& iFilename,
00343 stdair::BomRoot& ioBomRoot)
00344 : _filename (iFilename), _bomRoot (ioBomRoot) {
00345 init();
00346 }
00347
00348
00349 void OnDPeriodFileParser::init() {
00350
00351 const bool doesExistAndIsReadable =
00352 stdair::BasFileMgr::doesExistAndIsReadable (_filename);
00353
00354 if (doesExistAndIsReadable == false) {
00355 STDAIR_LOG_ERROR ("The O&D file " << _filename
00356 << " does not exist or can not be read.");
00357
00358 throw OnDInputFileNotFoundException ("The O&D file " + _filename
00359 + " does not exist or can not be read");
00360 }
00361
00362
00363 _startIterator = iterator_t (_filename);
00364
00365
00366 if (!_startIterator) {
00367 STDAIR_LOG_DEBUG ("The O&D file " << _filename << " can not be open."
00368 << std::endl);
00369 throw OnDInputFileNotFoundException ("The file " + _filename
00370 + " does not exist or can not be read");
00371 }
00372
00373
00374 _endIterator = _startIterator.make_end();
00375 }
00376
00377
00378 bool OnDPeriodFileParser::generateOnDPeriods () {
00379 bool oResult = false;
00380
00381 STDAIR_LOG_DEBUG ("Parsing O&D input file: " << _filename);
00382
00383
00384 OnDParserHelper::OnDParser lODParser (_bomRoot, _onDPeriod);
00385
00386
00387
00388 boost::spirit::classic::parse_info<iterator_t> info =
00389 boost::spirit::classic::parse (_startIterator, _endIterator, lODParser,
00390 boost::spirit::classic::space_p);
00391
00392
00393 oResult = info.hit;
00394
00395 const std::string hasBeenFullyReadStr = (info.full == true)?"":"not ";
00396 if (oResult == true) {
00397 STDAIR_LOG_DEBUG ("Parsing of O&D input file: " << _filename
00398 << " succeeded: read " << info.length
00399 << " characters. The input file has "
00400 << hasBeenFullyReadStr
00401 << "been fully read. Stop point: " << info.stop);
00402
00403 } else {
00404
00405 STDAIR_LOG_ERROR ("Parsing of O&D input file: " << _filename
00406 << " failed: read " << info.length
00407 << " characters. The input file has "
00408 << hasBeenFullyReadStr
00409 << "been fully read. Stop point: " << info.stop);
00410 }
00411
00412 return oResult;
00413 }
00414 }