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

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