AirInv Logo  1.00.0
C++ Simulated Airline Inventory Management System library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FFDisutilityParserHelper.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 #include <ostream>
7 // StdAir
8 #include <stdair/stdair_exceptions.hpp>
9 #include <stdair/stdair_types.hpp>
10 #include <stdair/bom/BomRoot.hpp>
11 #include <stdair/service/Logger.hpp>
12 // #define BOOST_SPIRIT_DEBUG
14 
15 //
16 namespace bsc = boost::spirit::classic;
17 
18 namespace AIRINV {
19 
20  namespace FFDisutilityParserHelper {
21 
22  // //////////////////////////////////////////////////////////////////
23  // Semantic actions
24  // //////////////////////////////////////////////////////////////////
25 
28  : _ffDisutility (ioFFDisutility) {
29  }
30 
31  // //////////////////////////////////////////////////////////////////
34  : ParserSemanticAction (ioFFDisutility) {
35  }
36 
37  // //////////////////////////////////////////////////////////////////
39  iterator_t iStrEnd) const {
40  const std::string lKey (iStr, iStrEnd);
41  _ffDisutility._key = lKey;
42  }
43 
44  // //////////////////////////////////////////////////////////////////
46  : ParserSemanticAction (ioFFDisutility) {
47  }
48 
49  // //////////////////////////////////////////////////////////////////
50  void storeDTD::operator() (int iDTD) const {
51  _ffDisutility._dtd = iDTD;
52  //STDAIR_LOG_DEBUG ("DTD: " << iDTD);
53  }
54 
55  // //////////////////////////////////////////////////////////////////
57  : ParserSemanticAction (ioFFDisutility) {
58  }
59 
60  // //////////////////////////////////////////////////////////////////
61  void storeFFDisutilityValue::operator() (double iReal) const {
62  const bool hasInsertBeenSuccessfull =
64  insert (stdair::FFDisutilityCurve_T::
65  value_type (_ffDisutility._dtd, iReal)).second;
66  if (hasInsertBeenSuccessfull == false) {
67  std::ostringstream oStr;
68  oStr << "The same DTD ('" << _ffDisutility._dtd
69  << "') has probably been given twice";
70  STDAIR_LOG_ERROR (oStr.str());
71  throw stdair::KeyDuplicationException (oStr.str());
72  }
73 
74  //STDAIR_LOG_DEBUG ("PosProbMass: " << iReal);
75  }
76 
77  // //////////////////////////////////////////////////////////////////
79  doEndCurve (stdair::BomRoot& ioBomRoot,
80  FFDisutilityStruct& ioFFDisutility)
81  : ParserSemanticAction (ioFFDisutility),
82  _bomRoot (ioBomRoot) {
83  }
84 
85  // //////////////////////////////////////////////////////////////////
86  // void doEndCurve::operator() (char iChar) const {
88  iterator_t iStrEnd) const {
89  // DEBUG: Display the result
90  STDAIR_LOG_DEBUG ("FFDisutility: " << _ffDisutility.describe());
91 
92  // Add the curve to the BomRoot.
93  _bomRoot.addFFDisutilityCurve (_ffDisutility._key, _ffDisutility._curve);
94 
95  // As that's the end of a curve, the values must be cleared.
96  _ffDisutility._curve.clear();
97  }
98 
99 
100  // ///////////////////////////////////////////////////////////////////
101  //
102  // Utility Parsers
103  //
104  // ///////////////////////////////////////////////////////////////////
106  repeat_p_t key_p (chset_t("0-9A-Z").derived(), 1, 10);
107 
108  // //////////////////////////////////////////////////////////////////
109  // (Boost Spirit) Grammar Definition
110  // //////////////////////////////////////////////////////////////////
111 
112  // //////////////////////////////////////////////////////////////////
114  FFDisutilityParser (stdair::BomRoot& ioBomRoot,
115  FFDisutilityStruct& ioFFDisutility)
116  : _bomRoot (ioBomRoot),
117  _ffDisutility (ioFFDisutility) {
118  }
119 
120  // //////////////////////////////////////////////////////////////////
121  template<typename ScannerT>
124 
125  curve_list = *( not_to_be_parsed | curve )
126  ;
127 
128  not_to_be_parsed =
129  bsc::lexeme_d[ bsc::comment_p("//") | bsc::comment_p("/*", "*/")
130  | bsc::space_p ]
131  ;
132 
133  curve = key >> ';' >> map
134  >> curve_end[doEndCurve(self._bomRoot, self._ffDisutility)]
135  ;
136 
137  curve_end = bsc::ch_p(';')
138  ;
139 
140  key =
141  bsc::lexeme_d[(key_p)[storeCurveKey(self._ffDisutility)]]
142  ;
143 
144  map =
145  value_pair >> *( ';' >> value_pair)
146  ;
147 
148  value_pair = bsc::uint_p[storeDTD(self._ffDisutility)]
149  >> ":" >> bsc::ureal_p[storeFFDisutilityValue(self._ffDisutility)]
150  ;
151 
152  // BOOST_SPIRIT_DEBUG_NODE (FFDisutilityParser);
153  BOOST_SPIRIT_DEBUG_NODE (curve_list);
154  BOOST_SPIRIT_DEBUG_NODE (not_to_be_parsed);
155  BOOST_SPIRIT_DEBUG_NODE (key);
156  BOOST_SPIRIT_DEBUG_NODE (map);
157  BOOST_SPIRIT_DEBUG_NODE (value_pair);
158  }
159 
160  // //////////////////////////////////////////////////////////////////
161  template<typename ScannerT>
162  bsc::rule<ScannerT> const&
164  return curve_list;
165  }
166  }
167 
168 
170  //
171  // Entry class for the file parser
172  //
174 
175  // //////////////////////////////////////////////////////////////////////
177  FFDisutilityFileParser (stdair::BomRoot& ioBomRoot,
178  const stdair::Filename_T& iFilename)
179  : _filename (iFilename), _bomRoot (ioBomRoot) {
180  init();
181  }
182 
183  // //////////////////////////////////////////////////////////////////////
184  void FFDisutilityFileParser::init() {
185  // Open the file
186  _startIterator = iterator_t (_filename);
187 
188  // Check the filename exists and can be open
189  if (!_startIterator) {
190  std::ostringstream oMessage;
191  oMessage << "The file " << _filename << " can not be open." << std::endl;
192  STDAIR_LOG_ERROR (oMessage.str());
193  throw FFDisutilityInputFileNotFoundException (oMessage.str());
194  }
195 
196  // Create an EOF iterator
197  _endIterator = _startIterator.make_end();
198  }
199 
200  // //////////////////////////////////////////////////////////////////////
202  bool oResult = false;
203 
204  STDAIR_LOG_DEBUG ("Parsing FFDisutility input file: " << _filename);
205 
206  // Initialise the parser (grammar) with the helper/staging structure.
207  FFDisutilityParserHelper::FFDisutilityParser lFFDisutilityParser (_bomRoot, _ffDisutility);
208 
209  // Launch the parsing of the file and, thanks to the doEndCurve
210  // call-back structure, the building of the whole BomRoot BOM
211  // (i.e., including Inventory, FlightDate, LegDate, SegmentDate, etc.)
212  bsc::parse_info<iterator_t> info = bsc::parse (_startIterator, _endIterator,
213  lFFDisutilityParser,
214  bsc::space_p - bsc::eol_p);
215 
216  // Retrieves whether or not the parsing was successful
217  oResult = info.hit;
218 
219  const bool isFull = info.full;
220 
221  const std::string hasBeenFullyReadStr = (isFull == true)?"":"not ";
222  if (oResult == true && isFull == true) {
223  STDAIR_LOG_DEBUG ("Parsing of FFDisutility input file: " << _filename
224  << " succeeded: read " << info.length
225  << " characters. The input file has "
226  << hasBeenFullyReadStr
227  << "been fully read. Stop point: " << info.stop);
228 
229  } else {
230  STDAIR_LOG_ERROR ("Parsing of FFDisutility input file: " << _filename
231  << " failed: read " << info.length
232  << " characters. The input file has "
233  << hasBeenFullyReadStr
234  << "been fully read. Stop point: " << info.stop);
235  throw FFDisutilityFileParsingFailedException ("Parsing of FFDisutility input file: " + _filename + " failed.");
236  }
237 
238  return oResult;
239  }
240 
241 }