TraDemGen Logo  0.2.2
C++ Simulated Travel Demand Generation Library
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
DemandParserHelper.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 // StdAir
7 #include <stdair/basic/RandomGeneration.hpp>
8 #include <stdair/basic/BasFileMgr.hpp>
9 #include <stdair/bom/EventQueue.hpp>
10 #include <stdair/service/Logger.hpp>
11 // TraDemGen
13 //#define BOOST_SPIRIT_DEBUG
16 
17 namespace bsc = boost::spirit::classic;
18 
19 namespace TRADEMGEN {
20 
21  namespace DemandParserHelper {
22 
23  // //////////////////////////////////////////////////////////////////
24  // Semantic actions
25  // //////////////////////////////////////////////////////////////////
26 
28  : _demand (ioDemand) {
29  }
30 
31  // //////////////////////////////////////////////////////////////////
34  : ParserSemanticAction (ioDemand) {
35  }
36 
37  // //////////////////////////////////////////////////////////////////
39  iterator_t iStrEnd) const {
41 
42  // Reset the number of seconds
43  _demand._itSeconds = 0;
44  }
45 
46  // //////////////////////////////////////////////////////////////////
49  : ParserSemanticAction (ioDemand) {
50  }
51 
52  // //////////////////////////////////////////////////////////////////
54  iterator_t iStrEnd) const {
55  // As a Boost date period (DatePeriod_T) defines the last day of
56  // the period to be end-date - one day, we have to add one day to that
57  // end date before.
58  const stdair::DateOffset_T oneDay (1);
60 
61  // Transform the date pair (i.e., the date range) into a date period
63  stdair::DatePeriod_T (_demand._prefDepDateStart,
65 
66  // Reset the number of seconds
67  _demand._itSeconds = 0;
68  }
69 
70  // //////////////////////////////////////////////////////////////////
72  : ParserSemanticAction (ioDemand) {
73  }
74 
75  // //////////////////////////////////////////////////////////////////
76  void storeDow::operator() (iterator_t iStr, iterator_t iStrEnd) const {
77  stdair::DOW_String_T lDow (iStr, iStrEnd);
78  _demand._dow = lDow;
79  }
80 
81  // //////////////////////////////////////////////////////////////////
83  : ParserSemanticAction (ioDemand) {
84  }
85 
86  // //////////////////////////////////////////////////////////////////
87  void storeOrigin::operator() (iterator_t iStr, iterator_t iStrEnd) const {
88  stdair::AirportCode_T lOrigin (iStr, iStrEnd);
89  _demand._origin = lOrigin;
90  }
91 
92  // //////////////////////////////////////////////////////////////////
94  : ParserSemanticAction (ioDemand) {
95  }
96 
97  // //////////////////////////////////////////////////////////////////
99  iterator_t iStrEnd) const {
100  stdair::AirportCode_T lDestination (iStr, iStrEnd);
101  _demand._destination = lDestination;
102  }
103 
104  // //////////////////////////////////////////////////////////////////
106  : ParserSemanticAction (ioDemand) {
107  }
108 
109  // //////////////////////////////////////////////////////////////////
111  iterator_t iStrEnd) const {
112  stdair::CabinCode_T lPrefCabin (iStr, iStrEnd);
113  _demand._prefCabin = lPrefCabin;
114  //STDAIR_LOG_DEBUG ("Preferred cabin: " << lPrefCabin);
115  }
116 
117  // //////////////////////////////////////////////////////////////////
119  : ParserSemanticAction (ioDemand) {
120  }
121 
122  // //////////////////////////////////////////////////////////////////
123  void storeDemandMean::operator() (double iReal) const {
124  _demand._demandMean = iReal;
125  //STDAIR_LOG_DEBUG ("Demand mean: " << iReal);
126  }
127 
128  // //////////////////////////////////////////////////////////////////
130  : ParserSemanticAction (ioDemand) {
131  }
132 
133  // //////////////////////////////////////////////////////////////////
134  void storeDemandStdDev::operator() (double iReal) const {
135  _demand._demandStdDev = iReal;
136  //STDAIR_LOG_DEBUG ("Demand stddev: " << iReal);
137  }
138 
139  // //////////////////////////////////////////////////////////////////
141  : ParserSemanticAction (ioDemand) {
142  }
143 
144  // //////////////////////////////////////////////////////////////////
145  void storePosCode::operator() (iterator_t iStr, iterator_t iStrEnd) const {
146  const stdair::AirportCode_T lPosCode (iStr, iStrEnd);
147  _demand._itPosCode = lPosCode;
148  //STDAIR_LOG_DEBUG ("Pos code: " << lPosCode);
149  }
150 
151  // //////////////////////////////////////////////////////////////////
153  : ParserSemanticAction (ioDemand) {
154  }
155 
156  // //////////////////////////////////////////////////////////////////
157  void storePosProbMass::operator() (double iReal) const {
158  const bool hasInsertBeenSuccessfull =
161  value_type (_demand._itPosCode, iReal)).second;
162  if (hasInsertBeenSuccessfull == false) {
163  STDAIR_LOG_ERROR ("The same POS code ('" << _demand._itPosCode
164  << "') has probably been given twice");
165  throw stdair::CodeDuplicationException ("The same POS code ('"
167  + "') has probably been given twice");
168  }
169 
170  //STDAIR_LOG_DEBUG ("PosProbMass: " << iReal);
171  }
172 
173  // //////////////////////////////////////////////////////////////////
175  : ParserSemanticAction (ioDemand) {
176  }
177 
178  // //////////////////////////////////////////////////////////////////
180  iterator_t iStrEnd) const {
181  _demand._itChannelCode = std::string (iStr, iStrEnd);
182  //STDAIR_LOG_DEBUG ("Channel code: " << _demand._itChannelCode);
183  }
184 
185  // //////////////////////////////////////////////////////////////////
187  : ParserSemanticAction (ioDemand) {
188  }
189 
190  // //////////////////////////////////////////////////////////////////
191  void storeChannelProbMass::operator() (double iReal) const {
192  const bool hasInsertBeenSuccessfull =
195  value_type (_demand._itChannelCode, iReal)).second;
196  if (hasInsertBeenSuccessfull == false) {
197  STDAIR_LOG_ERROR ("The same channel type code ('"
199  << "') has probably been given twice");
200  throw stdair::CodeDuplicationException ("The same channel type code ('"
202  + "') has probably been given twice");
203  }
204 
205  //STDAIR_LOG_DEBUG ("ChannelProbMass: " << iReal);
206  }
207 
208  // //////////////////////////////////////////////////////////////////
210  : ParserSemanticAction (ioDemand) {
211  }
212 
213  // //////////////////////////////////////////////////////////////////
215  iterator_t iStrEnd) const {
216  _demand._itTripCode = std::string (iStr, iStrEnd);
217  //STDAIR_LOG_DEBUG ("Trip code: " << _demand._itTripCode);
218  }
219 
220  // //////////////////////////////////////////////////////////////////
222  : ParserSemanticAction (ioDemand) {
223  }
224 
225  // //////////////////////////////////////////////////////////////////
226  void storeTripProbMass::operator() (double iReal) const {
227  const bool hasInsertBeenSuccessfull =
230  value_type (_demand._itTripCode, iReal)).second;
231  if (hasInsertBeenSuccessfull == false) {
232  STDAIR_LOG_ERROR ("The same trip type code ('"
234  << "') has probably been given twice");
235  throw stdair::CodeDuplicationException ("The same trip type code ('"
237  + "') has probably been given twice");
238  }
239 
240  //STDAIR_LOG_DEBUG ("TripProbMass: " << iReal);
241  }
242 
243  // //////////////////////////////////////////////////////////////////
245  : ParserSemanticAction (ioDemand) {
246  }
247 
248  // //////////////////////////////////////////////////////////////////
249  void storeStayCode::operator() (unsigned int iInteger) const {
250  const stdair::DayDuration_T lStayDuration (iInteger);
251  _demand._itStayDuration = lStayDuration;
252  // STDAIR_LOG_DEBUG ("Stay duration: " << lStayDuration);
253  }
254 
255  // //////////////////////////////////////////////////////////////////
257  : ParserSemanticAction (ioDemand) {
258  }
259 
260  // //////////////////////////////////////////////////////////////////
261  void storeStayProbMass::operator() (double iReal) const {
262  const bool hasInsertBeenSuccessfull =
265  value_type (_demand._itStayDuration, iReal)).second;
266  if (hasInsertBeenSuccessfull == false) {
267  std::ostringstream oStr;
268  oStr << "The same stay duration ('" << _demand._itStayDuration
269  << "') has probably been given twice";
270  STDAIR_LOG_ERROR (oStr.str());
271  throw stdair::CodeDuplicationException (oStr.str());
272  }
273 
274  // STDAIR_LOG_DEBUG ("StayProbMass: " << iReal);
275  }
276 
277  // //////////////////////////////////////////////////////////////////
279  : ParserSemanticAction (ioDemand) {
280  }
281 
282  // //////////////////////////////////////////////////////////////////
283  void storeFFCode::operator() (iterator_t iStr, iterator_t iStrEnd) const {
284  _demand._itFFCode = std::string (iStr, iStrEnd);
285  //STDAIR_LOG_DEBUG ("FF code: " << _demand._itFFCode);
286  }
287 
288  // //////////////////////////////////////////////////////////////////
290  : ParserSemanticAction (ioDemand) {
291  }
292 
293  // //////////////////////////////////////////////////////////////////
294  void storeFFProbMass::operator() (double iReal) const {
295  const bool hasInsertBeenSuccessfull =
298  value_type (_demand._itFFCode, iReal)).second;
299  if (hasInsertBeenSuccessfull == false) {
300  STDAIR_LOG_ERROR ("The same Frequent Flyer code ('"
301  << _demand._itFFCode
302  << "') has probably been given twice");
303  throw stdair::CodeDuplicationException("The same Frequent Flyer code ('"
305  + "') has probably been given twice");
306  }
307 
308  //STDAIR_LOG_DEBUG ("FfProbMass: " << iReal);
309  }
310 
311  // //////////////////////////////////////////////////////////////////
313  : ParserSemanticAction (ioDemand) {
314  }
315 
316  // //////////////////////////////////////////////////////////////////
318  iterator_t iStrEnd) const {
320 
321  // DEBUG
322  // STDAIR_LOG_DEBUG ("Pref dep time: " << _demand._itHours << ":"
323  // << _demand._itMinutes << ":" << _demand._itSeconds
324  // << " ==> " << _demand._itPrefDepTime);
325 
326  // Reset the number of minutes and seconds
327  _demand._itMinutes = 0;
328  _demand._itSeconds = 0;
329  }
330 
331  // //////////////////////////////////////////////////////////////////
333  : ParserSemanticAction (ioDemand) {
334  }
335 
336  // //////////////////////////////////////////////////////////////////
337  void storePrefDepTimeProbMass::operator() (double iReal) const {
338  const stdair::IntDuration_T lIntDuration =
339  _demand._itPrefDepTime.total_seconds();
340 
343  value_type (lIntDuration, iReal));
344  //STDAIR_LOG_DEBUG ("PrefDepTimeProbMass: " << iReal);
345  }
346 
347  // //////////////////////////////////////////////////////////////////
349  : ParserSemanticAction (ioDemand) {
350  }
351 
352  // //////////////////////////////////////////////////////////////////
353  void storeWTP::operator() (double iReal) const {
354  _demand._minWTP = iReal;
355  //STDAIR_LOG_DEBUG ("WTP: " << iReal);
356  }
357 
358  // //////////////////////////////////////////////////////////////////
360  : ParserSemanticAction (ioDemand) {
361  }
362 
363  // //////////////////////////////////////////////////////////////////
364  void storeTimeValue::operator() (double iReal) const {
365  _demand._itTimeValue = iReal;
366  //STDAIR_LOG_DEBUG ("Time value: " << iReal);
367  }
368 
369  // //////////////////////////////////////////////////////////////////
371  : ParserSemanticAction (ioDemand) {
372  }
373 
374  // //////////////////////////////////////////////////////////////////
375  void storeTimeValueProbMass::operator() (double iReal) const {
378  value_type (_demand._itTimeValue, iReal));
379  //STDAIR_LOG_DEBUG ("TimeValueProbMass: " << iReal);
380  }
381 
382  // //////////////////////////////////////////////////////////////////
384  : ParserSemanticAction (ioDemand) {
385  }
386 
387  // //////////////////////////////////////////////////////////////////
388  void storeDTD::operator() (unsigned int iInteger) const {
389  const stdair::DayDuration_T lDTD (iInteger);
390  _demand._itDTD = lDTD;
391  //STDAIR_LOG_DEBUG ("DTD: " << lDTD);
392  }
393 
394  // //////////////////////////////////////////////////////////////////
396  : ParserSemanticAction (ioDemand) {
397  }
398 
399  // //////////////////////////////////////////////////////////////////
400  void storeDTDProbMass::operator() (double iReal) const {
401  const stdair::FloatDuration_T lZeroDTDFloat = 0.0;
402  stdair::FloatDuration_T lDTDFloat =
403  static_cast<stdair::FloatDuration_T> (_demand._itDTD);
404  lDTDFloat = lZeroDTDFloat - lDTDFloat;
405 
407  value_type (lDTDFloat, iReal));
408  //STDAIR_LOG_DEBUG ("DTDProbMass: " << iReal);
409  }
410 
411  // //////////////////////////////////////////////////////////////////
412  doEndDemand::doEndDemand (stdair::EventQueue& ioEventQueue,
413  stdair::RandomGeneration& ioSharedGenerator,
414  const POSProbabilityMass_T& iPOSProbMass,
415  DemandStruct& ioDemand)
416  : ParserSemanticAction (ioDemand), _eventQueue (ioEventQueue),
417  _uniformGenerator (ioSharedGenerator),
418  _posProbabilityMass (iPOSProbMass) {
419  }
420 
421  // //////////////////////////////////////////////////////////////////
422  // void doEndDemand::operator() (char iChar) const {
423  void doEndDemand::operator() (iterator_t iStr, iterator_t iStrEnd) const {
424 
425  // DEBUG: Display the result
426  // STDAIR_LOG_DEBUG ("Demand: " << _demand.describe());
427 
428  // Create the Demand BOM objects
429  DemandManager::createDemandCharacteristics (_eventQueue, _uniformGenerator,
431 
432  // Clean the lists
433  _demand._posProbDist.clear();
434  _demand._channelProbDist.clear();
435  _demand._tripProbDist.clear();
436  _demand._stayProbDist.clear();
437  _demand._ffProbDist.clear();
438  _demand._prefDepTimeProbDist.clear();
439  _demand._timeValueProbDist.clear();
440  _demand._dtdProbDist.clear();
441  }
442 
443 
444  // ///////////////////////////////////////////////////////////////////
445  //
446  // Utility Parsers
447  //
448  // ///////////////////////////////////////////////////////////////////
451 
454 
457 
460 
463 
466 
468  repeat_p_t airline_code_p (chset_t("0-9A-Z").derived(), 2, 3);
469 
471  bounded1_4_p_t flight_number_p (uint1_4_p.derived(), 0u, 9999u);
472 
474  bounded4_p_t year_p (uint4_p.derived(), 2000u, 2099u);
475 
477  bounded2_p_t month_p (uint2_p.derived(), 1u, 12u);
478 
480  bounded2_p_t day_p (uint2_p.derived(), 1u, 31u);
481 
483  repeat_p_t dow_p (chset_t("0-1").derived().derived(), 7, 7);
484 
486  repeat_p_t airport_p (chset_t("0-9A-Z").derived(), 3, 3);
487 
489  bounded1_2_p_t hours_p (uint1_2_p.derived(), 0u, 23u);
490 
492  bounded2_p_t minutes_p (uint2_p.derived(), 0u, 59u);
493 
495  bounded2_p_t seconds_p (uint2_p.derived(), 0u, 59u);
496 
498  chset_t cabin_code_p ("A-Z");
499 
501  chset_t passenger_type_p ("A-Z");
502 
504  chset_t ff_type_p ("A-Z");
505 
508 
510  repeat_p_t class_code_list_p (chset_t("A-Z").derived(), 1, 26);
511 
513  bounded1_3_p_t stay_duration_p (uint1_3_p.derived(), 0u, 999u);
514 
515 
516  // //////////////////////////////////////////////////////////////////
517  // (Boost Spirit) Grammar Definition
518  // //////////////////////////////////////////////////////////////////
519 
520  // //////////////////////////////////////////////////////////////////
521  DemandParser::DemandParser (stdair::EventQueue& ioEventQueue,
522  stdair::RandomGeneration& ioSharedGenerator,
523  const POSProbabilityMass_T& iPOSProbMass,
524  DemandStruct& ioDemand)
525  : _eventQueue (ioEventQueue), _uniformGenerator (ioSharedGenerator),
526  _posProbabilityMass (iPOSProbMass), _demand (ioDemand) {
527  }
528 
529  // //////////////////////////////////////////////////////////////////
530  template<typename ScannerT>
532  definition (DemandParser const& self) {
533 
534  demand_list = *( not_to_be_parsed |
535  demand)
536  ;
537 
538  not_to_be_parsed = bsc::
539  lexeme_d[bsc::comment_p("//")
540  | bsc::comment_p("/*", "*/")
541  | bsc::eol_p]
542  ;
543 
544  demand =
545  pref_dep_date_range
546  >> ';' >> origin >> ';' >> destination
547  >> ';' >> pref_cabin[storePrefCabin(self._demand)]
548  >> ';' >> pos_dist
549  >> ';' >> channel_dist
550  >> ';' >> trip_dist
551  >> ';' >> stay_dist
552  >> ';' >> ff_dist
553  >> ';' >> pref_dep_time_dist
554  >> ';' >> wtp
555  >> ';' >> time_value_dist
556  >> ';' >> dtd_dist
557  >> ';' >> demand_params
558  >> demand_end[doEndDemand (self._eventQueue, self._uniformGenerator,
559  self._posProbabilityMass, self._demand)]
560  ;
561 
562  demand_end = bsc::ch_p(';')
563  ;
564 
565  pref_dep_date_range = date[storePrefDepDateRangeStart(self._demand)]
566  >> ';' >> date[storePrefDepDateRangeEnd(self._demand)]
567  >> ';' >> dow[storeDow(self._demand)]
568  ;
569 
570  date =
571  bsc::lexeme_d[(year_p)[bsc::assign_a(self._demand._itYear)]
572  >> '-' >> (month_p)[bsc::assign_a(self._demand._itMonth)]
573  >> '-' >> (day_p)[bsc::assign_a(self._demand._itDay)]
574  ]
575  ;
576 
577  dow = bsc::lexeme_d[ dow_p ]
578  ;
579 
580  origin =
581  (airport_p)[storeOrigin(self._demand)]
582  ;
583 
584  destination =
585  (airport_p)[storeDestination(self._demand)]
586  ;
587 
588  pref_cabin = cabin_code_p;
589 
590  pos_dist =
591  pos_pair >> *( ',' >> pos_pair )
592  ;
593 
594  pos_pair =
595  pos_code[storePosCode(self._demand)]
596  >> ':' >> pos_share
597  ;
598 
599  pos_code =
600  airport_p
601  | bsc::chseq_p("row")
602  ;
603 
604  pos_share =
605  (bsc::ureal_p)[storePosProbMass(self._demand)]
606  ;
607 
608  channel_dist =
609  channel_pair >> *( ',' >> channel_pair )
610  ;
611 
612  channel_pair =
613  channel_code[storeChannelCode(self._demand)]
614  >> ':' >> channel_share
615  ;
616 
617  channel_code =
618  bsc::chseq_p("DF") | bsc::chseq_p("DN")
619  | bsc::chseq_p("IF") | bsc::chseq_p("IN")
620  ;
621 
622  channel_share =
623  (bsc::ureal_p)[storeChannelProbMass(self._demand)]
624  ;
625 
626  trip_dist =
627  trip_pair >> *( ',' >> trip_pair )
628  ;
629 
630  trip_pair =
631  trip_code[storeTripCode(self._demand)]
632  >> ':' >> trip_share
633  ;
634 
635  trip_code =
636  bsc::chseq_p("RO") | bsc::chseq_p("RI") | bsc::chseq_p("OW")
637  ;
638 
639  trip_share =
640  (bsc::ureal_p)[storeTripProbMass(self._demand)]
641  ;
642 
643  stay_dist =
644  stay_pair >> *( ',' >> stay_pair )
645  ;
646 
647  stay_pair =
648  (stay_duration_p)[storeStayCode(self._demand)]
649  >> ':' >> stay_share
650  ;
651 
652  stay_share =
653  (bsc::ureal_p)[storeStayProbMass(self._demand)]
654  ;
655 
656  ff_dist =
657  ff_pair >> *( ',' >> ff_pair )
658  ;
659 
660  ff_pair =
661  ff_code[storeFFCode(self._demand)]
662  >> ':' >> ff_share
663  ;
664 
665  ff_code = ff_type_p;
666 
667  ff_share =
668  (bsc::ureal_p)[storeFFProbMass(self._demand)]
669  ;
670 
671  pref_dep_time_dist =
672  pref_dep_time_pair >> *( ',' >> pref_dep_time_pair )
673  ;
674 
675  pref_dep_time_pair =
676  (time)[storePrefDepTime(self._demand)]
677  >> ':' >> pref_dep_time_share
678  ;
679 
680  pref_dep_time_share =
681  (bsc::ureal_p)[storePrefDepTimeProbMass(self._demand)]
682  ;
683 
684  time =
685  bsc::lexeme_d[
686  (hours_p)[bsc::assign_a(self._demand._itHours)]
687  >> !('.' >> (minutes_p)[bsc::assign_a(self._demand._itMinutes)])
688  >> !('.' >> (seconds_p)[bsc::assign_a(self._demand._itSeconds)])
689  ]
690  ;
691 
692  wtp =
693  (bsc::ureal_p)[storeWTP(self._demand)]
694  ;
695 
696  time_value_dist =
697  time_value_pair >> *( ',' >> time_value_pair )
698  ;
699 
700  time_value_pair =
701  (bsc::ureal_p)[storeTimeValue(self._demand)]
702  >> ':' >> time_value_share
703  ;
704 
705  time_value_share =
706  (bsc::ureal_p)[storeTimeValueProbMass(self._demand)]
707  ;
708 
709  dtd_dist =
710  dtd_pair >> *( ',' >> dtd_pair )
711  ;
712 
713  dtd_pair =
714  (bsc::ureal_p)[storeDTD(self._demand)]
715  >> ':' >> dtd_share
716  ;
717 
718  dtd_share =
719  (bsc::ureal_p)[storeDTDProbMass(self._demand)]
720  ;
721 
722  demand_params =
723  bsc::ch_p('N')
724  >> ','
725  >> (bsc::ureal_p)[storeDemandMean(self._demand)]
726  >> ','
727  >> (bsc::ureal_p)[storeDemandStdDev(self._demand)]
728  ;
729 
730  // BOOST_SPIRIT_DEBUG_NODE (DemandParser);
731  BOOST_SPIRIT_DEBUG_NODE (demand_list);
732  BOOST_SPIRIT_DEBUG_NODE (not_to_be_parsed);
733  BOOST_SPIRIT_DEBUG_NODE (demand);
734  BOOST_SPIRIT_DEBUG_NODE (demand_end);
735  BOOST_SPIRIT_DEBUG_NODE (pref_dep_date);
736  BOOST_SPIRIT_DEBUG_NODE (date);
737  BOOST_SPIRIT_DEBUG_NODE (origin);
738  BOOST_SPIRIT_DEBUG_NODE (destination);
739  BOOST_SPIRIT_DEBUG_NODE (pref_cabin);
740  BOOST_SPIRIT_DEBUG_NODE (pos_dist);
741  BOOST_SPIRIT_DEBUG_NODE (pos_pair);
742  BOOST_SPIRIT_DEBUG_NODE (pos_code);
743  BOOST_SPIRIT_DEBUG_NODE (pos_share);
744  BOOST_SPIRIT_DEBUG_NODE (channel_dist);
745  BOOST_SPIRIT_DEBUG_NODE (channel_pair);
746  BOOST_SPIRIT_DEBUG_NODE (channel_code);
747  BOOST_SPIRIT_DEBUG_NODE (channel_share);
748  BOOST_SPIRIT_DEBUG_NODE (trip_dist);
749  BOOST_SPIRIT_DEBUG_NODE (trip_pair);
750  BOOST_SPIRIT_DEBUG_NODE (trip_code);
751  BOOST_SPIRIT_DEBUG_NODE (trip_share);
752  BOOST_SPIRIT_DEBUG_NODE (stay_dist);
753  BOOST_SPIRIT_DEBUG_NODE (stay_pair);
754  BOOST_SPIRIT_DEBUG_NODE (stay_share);
755  BOOST_SPIRIT_DEBUG_NODE (ff_dist);
756  BOOST_SPIRIT_DEBUG_NODE (ff_pair);
757  BOOST_SPIRIT_DEBUG_NODE (ff_code);
758  BOOST_SPIRIT_DEBUG_NODE (ff_share);
759  BOOST_SPIRIT_DEBUG_NODE (pref_dep_time_dist);
760  BOOST_SPIRIT_DEBUG_NODE (pref_dep_time_pair);
761  BOOST_SPIRIT_DEBUG_NODE (pref_dep_time_share);
762  BOOST_SPIRIT_DEBUG_NODE (time);
763  BOOST_SPIRIT_DEBUG_NODE (wtp);
764  BOOST_SPIRIT_DEBUG_NODE (time_value_dist);
765  BOOST_SPIRIT_DEBUG_NODE (time_value_pair);
766  BOOST_SPIRIT_DEBUG_NODE (time_value_share);
767  BOOST_SPIRIT_DEBUG_NODE (dtd_dist);
768  BOOST_SPIRIT_DEBUG_NODE (dtd_pair);
769  BOOST_SPIRIT_DEBUG_NODE (dtd_share);
770  BOOST_SPIRIT_DEBUG_NODE (demand_params);
771  }
772 
773  // //////////////////////////////////////////////////////////////////
774  template<typename ScannerT>
775  bsc::rule<ScannerT> const&
777  return demand_list;
778  }
779 
780  }
781 
782 
784  //
785  // Entry class for the file parser
786  //
788 
789  // //////////////////////////////////////////////////////////////////////
791  DemandFileParser (stdair::EventQueue& ioEventQueue,
792  stdair::RandomGeneration& ioSharedGenerator,
793  const POSProbabilityMass_T& iPOSProbMass,
794  const std::string& iFilename)
795  : _filename (iFilename), _eventQueue (ioEventQueue),
796  _uniformGenerator (ioSharedGenerator),
797  _posProbabilityMass (iPOSProbMass) {
798  init();
799  }
800 
801  // //////////////////////////////////////////////////////////////////////
802  void DemandFileParser::init() {
803  // Check that the file exists and is readable
804  const bool doesExistAndIsReadable =
805  stdair::BasFileMgr::doesExistAndIsReadable (_filename);
806 
807  if (doesExistAndIsReadable == false) {
808  STDAIR_LOG_ERROR ("The demand file " << _filename
809  << " does not exist or can not be read.");
810 
811  throw DemandInputFileNotFoundException ("The demand file " + _filename
812  + " does not exist or can not "
813  + "be read");
814  }
815 
816  // Open the file
817  _startIterator = iterator_t (_filename);
818 
819  // Check the filename exists and can be open
820  if (!_startIterator) {
821  STDAIR_LOG_ERROR ("The demand file " << _filename << " can not be open.");
822 
823  throw DemandInputFileNotFoundException ("The demand file " + _filename
824  + " does not exist or can not "
825  + "be read");
826  }
827 
828  // Create an EOF iterator
829  _endIterator = _startIterator.make_end();
830  }
831 
832  // //////////////////////////////////////////////////////////////////////
834  bool oResult = false;
835 
836  STDAIR_LOG_DEBUG ("Parsing demand input file: " << _filename);
837 
838  // Initialise the parser (grammar) with the helper/staging structure.
839  DemandParserHelper::DemandParser lDemandParser (_eventQueue,
840  _uniformGenerator,
841  _posProbabilityMass,
842  _demand);
843 
844  // Launch the parsing of the file and, thanks to the doEndDemand
845  // call-back structure, the building of the whole EventQueue BOM
846  // (i.e., including Inventory, FlightDate, LegDate, SegmentDate, etc.)
847  bsc::parse_info<iterator_t> info =
848  bsc::parse (_startIterator, _endIterator, lDemandParser,
849  bsc::space_p - bsc::eol_p);
850 
851  // Retrieves whether or not the parsing was successful
852  oResult = info.hit;
853 
854  const std::string hasBeenFullyReadStr = (info.full == true)?"":"not ";
855  if (oResult == true) {
856  STDAIR_LOG_DEBUG ("Parsing of demand input file: " << _filename
857  << " succeeded: read " << info.length
858  << " characters. The input file has "
859  << hasBeenFullyReadStr
860  << "been fully read. Stop point: " << info.stop);
861 
862  } else {
863  std::ostringstream oStr;
864  oStr << "Parsing of demand input file: " << _filename << " failed: read "
865  << info.length << " characters. The input file has "
866  << hasBeenFullyReadStr << "been fully read. Stop point: "
867  << info.stop;
868  STDAIR_LOG_ERROR (oStr.str());
869  throw stdair::ParserException (oStr.str());
870  }
871 
872  return oResult;
873  }
874 
875 }