$treeview $search $mathjax
00001 // ////////////////////////////////////////////////////////////////////// 00002 // Import section 00003 // ////////////////////////////////////////////////////////////////////// 00004 // STL 00005 #include <cassert> 00006 #include <ostream> 00007 // StdAir 00008 #include <stdair/stdair_exceptions.hpp> 00009 #include <stdair/stdair_types.hpp> 00010 #include <stdair/bom/BomRoot.hpp> 00011 #include <stdair/service/Logger.hpp> 00012 // #define BOOST_SPIRIT_DEBUG 00013 #include <airinv/command/FRAT5ParserHelper.hpp> 00014 00015 // 00016 namespace bsc = boost::spirit::classic; 00017 00018 namespace AIRINV { 00019 00020 namespace FRAT5ParserHelper { 00021 00022 // ////////////////////////////////////////////////////////////////// 00023 // Semantic actions 00024 // ////////////////////////////////////////////////////////////////// 00025 00026 ParserSemanticAction:: 00027 ParserSemanticAction (FRAT5Struct& ioFRAT5) 00028 : _frat5 (ioFRAT5) { 00029 } 00030 00031 // ////////////////////////////////////////////////////////////////// 00032 storeCurveKey:: 00033 storeCurveKey (FRAT5Struct& ioFRAT5) 00034 : ParserSemanticAction (ioFRAT5) { 00035 } 00036 00037 // ////////////////////////////////////////////////////////////////// 00038 void storeCurveKey::operator() (iterator_t iStr, 00039 iterator_t iStrEnd) const { 00040 const std::string lKey (iStr, iStrEnd); 00041 _frat5._key = lKey; 00042 //STDAIR_LOG_DEBUG ("Key: " << lKey); 00043 } 00044 00045 // ////////////////////////////////////////////////////////////////// 00046 storeDTD::storeDTD (FRAT5Struct& ioFRAT5) 00047 : ParserSemanticAction (ioFRAT5) { 00048 } 00049 00050 // ////////////////////////////////////////////////////////////////// 00051 void storeDTD::operator() (int iDTD) const { 00052 _frat5._dtd = iDTD; 00053 //STDAIR_LOG_DEBUG ("DTD: " << iDTD); 00054 } 00055 00056 // ////////////////////////////////////////////////////////////////// 00057 storeFRAT5Value::storeFRAT5Value (FRAT5Struct& ioFRAT5) 00058 : ParserSemanticAction (ioFRAT5) { 00059 } 00060 00061 // ////////////////////////////////////////////////////////////////// 00062 void storeFRAT5Value::operator() (double iReal) const { 00063 const bool hasInsertBeenSuccessfull = 00064 _frat5._curve. 00065 insert (stdair::FRAT5Curve_T:: 00066 value_type (_frat5._dtd, iReal)).second; 00067 if (hasInsertBeenSuccessfull == false) { 00068 std::ostringstream oStr; 00069 oStr << "The same DTD ('" << _frat5._dtd 00070 << "') has probably been given twice"; 00071 STDAIR_LOG_ERROR (oStr.str()); 00072 throw stdair::KeyDuplicationException (oStr.str()); 00073 } 00074 00075 //STDAIR_LOG_DEBUG ("Value: " << iReal); 00076 } 00077 00078 // ////////////////////////////////////////////////////////////////// 00079 doEndCurve:: 00080 doEndCurve (stdair::BomRoot& ioBomRoot, 00081 FRAT5Struct& ioFRAT5) 00082 : ParserSemanticAction (ioFRAT5), 00083 _bomRoot (ioBomRoot) { 00084 } 00085 00086 // ////////////////////////////////////////////////////////////////// 00087 // void doEndCurve::operator() (char iChar) const { 00088 void doEndCurve::operator() (iterator_t iStr, 00089 iterator_t iStrEnd) const { 00090 // DEBUG: Display the result 00091 STDAIR_LOG_DEBUG ("FRAT5: " << _frat5.describe()); 00092 00093 // Add the curve to the BomRoot. 00094 _bomRoot.addFRAT5Curve (_frat5._key, _frat5._curve); 00095 00096 // As that's the end of a curve, the values must be cleared. 00097 _frat5._curve.clear(); 00098 } 00099 00100 00101 // /////////////////////////////////////////////////////////////////// 00102 // 00103 // Utility Parsers 00104 // 00105 // /////////////////////////////////////////////////////////////////// 00107 repeat_p_t key_p (chset_t("0-9A-Z").derived(), 1, 10); 00108 00109 // ////////////////////////////////////////////////////////////////// 00110 // (Boost Spirit) Grammar Definition 00111 // ////////////////////////////////////////////////////////////////// 00112 00113 // ////////////////////////////////////////////////////////////////// 00114 FRAT5Parser:: 00115 FRAT5Parser (stdair::BomRoot& ioBomRoot, 00116 FRAT5Struct& ioFRAT5) 00117 : _bomRoot (ioBomRoot), 00118 _frat5 (ioFRAT5) { 00119 } 00120 00121 // ////////////////////////////////////////////////////////////////// 00122 template<typename ScannerT> 00123 FRAT5Parser::definition<ScannerT>:: 00124 definition (FRAT5Parser const& self) { 00125 00126 curve_list = *( not_to_be_parsed | curve ) 00127 ; 00128 00129 not_to_be_parsed = 00130 bsc::lexeme_d[ bsc::comment_p("//") | bsc::comment_p("/*", "*/") 00131 | bsc::space_p ] 00132 ; 00133 00134 curve = key >> ';' >> map 00135 >> curve_end[doEndCurve(self._bomRoot, self._frat5)] 00136 ; 00137 00138 curve_end = bsc::ch_p(';') 00139 ; 00140 00141 key = 00142 bsc::lexeme_d[(key_p)[storeCurveKey(self._frat5)]] 00143 ; 00144 00145 map = 00146 value_pair >> *( ';' >> value_pair) 00147 ; 00148 00149 value_pair = bsc::uint_p[storeDTD(self._frat5)] 00150 >> ":" >> bsc::ureal_p[storeFRAT5Value(self._frat5)] 00151 ; 00152 00153 // BOOST_SPIRIT_DEBUG_NODE (FRAT5Parser); 00154 BOOST_SPIRIT_DEBUG_NODE (curve_list); 00155 BOOST_SPIRIT_DEBUG_NODE (not_to_be_parsed); 00156 BOOST_SPIRIT_DEBUG_NODE (key); 00157 BOOST_SPIRIT_DEBUG_NODE (map); 00158 BOOST_SPIRIT_DEBUG_NODE (value_pair); 00159 } 00160 00161 // ////////////////////////////////////////////////////////////////// 00162 template<typename ScannerT> 00163 bsc::rule<ScannerT> const& 00164 FRAT5Parser::definition<ScannerT>::start() const { 00165 return curve_list; 00166 } 00167 } 00168 00169 00171 // 00172 // Entry class for the file parser 00173 // 00175 00176 // ////////////////////////////////////////////////////////////////////// 00177 FRAT5FileParser:: 00178 FRAT5FileParser (stdair::BomRoot& ioBomRoot, 00179 const stdair::Filename_T& iFilename) 00180 : _filename (iFilename), _bomRoot (ioBomRoot) { 00181 init(); 00182 } 00183 00184 // ////////////////////////////////////////////////////////////////////// 00185 void FRAT5FileParser::init() { 00186 // Open the file 00187 _startIterator = iterator_t (_filename); 00188 00189 // Check the filename exists and can be open 00190 if (!_startIterator) { 00191 std::ostringstream oMessage; 00192 oMessage << "The file " << _filename << " can not be open." << std::endl; 00193 STDAIR_LOG_ERROR (oMessage.str()); 00194 throw FRAT5InputFileNotFoundException (oMessage.str()); 00195 } 00196 00197 // Create an EOF iterator 00198 _endIterator = _startIterator.make_end(); 00199 } 00200 00201 // ////////////////////////////////////////////////////////////////////// 00202 bool FRAT5FileParser::generateFRAT5Curves () { 00203 bool oResult = false; 00204 00205 STDAIR_LOG_DEBUG ("Parsing FRAT5 input file: " << _filename); 00206 00207 // Initialise the parser (grammar) with the helper/staging structure. 00208 FRAT5ParserHelper::FRAT5Parser lFRAT5Parser (_bomRoot, _frat5); 00209 00210 // Launch the parsing of the file and, thanks to the doEndCurve 00211 // call-back structure, the building of the whole BomRoot BOM 00212 // (i.e., including Inventory, FlightDate, LegDate, SegmentDate, etc.) 00213 bsc::parse_info<iterator_t> info = bsc::parse (_startIterator, _endIterator, 00214 lFRAT5Parser, 00215 bsc::space_p - bsc::eol_p); 00216 00217 // Retrieves whether or not the parsing was successful 00218 oResult = info.hit; 00219 00220 const bool isFull = info.full; 00221 00222 const std::string hasBeenFullyReadStr = (isFull == true)?"":"not "; 00223 if (oResult == true && isFull == true) { 00224 STDAIR_LOG_DEBUG ("Parsing of FRAT5 input file: " << _filename 00225 << " succeeded: read " << info.length 00226 << " characters. The input file has " 00227 << hasBeenFullyReadStr 00228 << "been fully read. Stop point: " << info.stop); 00229 00230 } else { 00231 STDAIR_LOG_ERROR ("Parsing of FRAT5 input file: " << _filename 00232 << " failed: read " << info.length 00233 << " characters. The input file has " 00234 << hasBeenFullyReadStr 00235 << "been fully read. Stop point: " << info.stop); 00236 throw FRAT5FileParsingFailedException ("Parsing of FRAT5 input file: " 00237 + _filename + " failed."); 00238 } 00239 00240 return oResult; 00241 } 00242 00243 }