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