$treeview $search $mathjax
AirInv Logo  1.00.1
$projectbrief
$projectbrief
$searchbox

FRAT5ParserHelper.cpp

Go to the documentation of this file.
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 }