/search.css" rel="stylesheet" type="text/css"/> /search.js">
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

Parser.cc
Go to the documentation of this file.
00001 // $Id: Parser.cpp,v 1.11 2007/12/06 15:14:21 marcocle Exp $
00002 // ============================================================================
00003 // Include files
00004 // ============================================================================
00005 // STD & STL 
00006 // ============================================================================
00007 #include <iostream>
00008 // ============================================================================
00009 // Boost
00010 // ============================================================================
00011 #include <boost/format.hpp>
00012 #include <boost/algorithm/string.hpp>
00013 // ============================================================================
00014 // local 
00015 // ============================================================================
00016 #include "ParserUtils.h"
00017 #include "ParserGrammar.h"
00018 // ============================================================================
00019 // local namespaces:
00020 // ============================================================================
00021 namespace ba = boost::algorithm;
00022 // ============================================================================
00023 namespace 
00024 {
00025   const std::string GPP_COMMENT = "//GP:" ;
00026 }
00027 // ============================================================================
00028 Gaudi::Parsers::Parser::Parser
00029 ( Catalogue&                catalogue , 
00030   std::vector<std::string>& included  , 
00031   std::ostream&             m         )
00032   : m_isPrint(false)
00033   , m_isPrintOptions(true)
00034   , m_catalogue(catalogue)
00035   , m_included(included)
00036   , m_stream ( m )
00037 {
00038 }
00039 // ============================================================================
00040 bool Gaudi::Parsers::Parser::parse ( const std::string& fileName )
00041 {
00042   //m_stream << GPP_COMMENT + std::string(80,'=') << std::endl;
00043   bool sc = parseFile(fileName,Position());
00044   resolveReferences();
00045   if ( sc && m_isPrintOptions ){
00046       m_stream << m_catalogue;
00047       m_stream << "// " << std::string(82,'=') << std::endl;
00048   }
00049   return errorsCount()==0?true:false;
00050 }
00051 // ============================================================================
00052 int Gaudi::Parsers::Parser::errorsCount()
00053 {
00054         int result=0;
00055         for ( MessagesStoreT::const_iterator cur=m_messages.begin();
00056         cur!=m_messages.end() ; ++cur)
00057   { if ( cur->severity() == Message::E_ERROR){ ++result; } }
00058         return result;
00059 }
00060 // ============================================================================
00061 void Gaudi::Parsers::Parser::matchInclude
00062 (const std::string& fileName,const Position& pos)
00063 { parseFile(fileName,pos); }
00064 // ============================================================================
00065 void Gaudi::Parsers::Parser::matchAssign
00066 ( const std::string& objName  ,
00067   const std::string& propName , 
00068   const Sign& oper,
00069   const std::vector<std::string>& vectorValue,
00070   const Position& pos,bool isVector)
00071 {
00072   // --------------------------------------------------------------------------
00073   if( m_isPrint )
00074   {
00075     m_stream 
00076       << boost::format("%2% %3% %4%;%|72t|%5% %1%") 
00077       % posString(pos.line(),pos.column()) 
00078       % (objName+"."+propName) 
00079       % sign(oper) 
00080       % valueToString(vectorValue , isVector) 
00081       % GPP_COMMENT 
00082       << std::endl ;
00083   }
00084   // --------------------------------------------------------------------------
00085   // --------------------------------------------------------------------------
00086   if (oper == S_ASSIGN)
00087   {
00088     // ------------------------------------------------------------------------
00089     PropertyEntry* assignProp;
00090     if(isVector){
00091       assignProp = new PropertyEntry(propName,vectorValue,pos);
00092     }else{
00093       assignProp = new PropertyEntry(propName,vectorValue[0],pos);
00094     }
00095     m_catalogue.addProperty(objName,*assignProp);
00096     delete assignProp;
00097     // ------------------------------------------------------------------------
00098   }
00099   else
00100   {
00101     // += or -=
00102     // ------------------------------------------------------------------------
00103     PropertyEntry foundProp;
00104     bool ok;
00105     ok = m_catalogue.findProperty(objName,propName,foundProp);
00106     if (!ok)
00107     {
00108       foundProp = PropertyEntry(propName,std::vector<std::string>());
00109     }
00110     if(oper == S_PLUSASSIGN)
00111     {
00112       ok = foundProp.addValues(vectorValue);
00113       if(!ok){
00114         addMessage
00115           ( Message::E_ERROR, 
00116             Message::C_CANNOTADDTONOTVECTOR,
00117             boost::str
00118             ( boost::format
00119               ("Cannot add values to not vector property \"%1%.%2%\"")
00120               %  objName % propName),pos);
00121         return;
00122       }
00123       m_catalogue.addProperty(objName,foundProp);
00124     }
00125     // ------------------------------------------------------------------------
00126     if(oper == S_MINUSASSIGN)
00127     {
00128       int count=0;
00129       ok = foundProp.removeValues(vectorValue,count);
00130       if(!ok){
00131         addMessage
00132           ( Message::E_ERROR, 
00133             Message::C_CANNOTREMOVEFROMNOTVECTOR,
00134             boost::str
00135             ( boost::format
00136               ( "Cannot remove values from not vector property \"%1%.%2%\"" ) 
00137               %  objName % propName),pos);
00138         return;
00139       }
00140       // ----------------------------------------------------------------------
00141       if (count == 0)
00142       {
00143         addMessage
00144           ( Message::E_WARNING, 
00145             Message::C_ZEROREMOVED,
00146             boost::str
00147             ( boost::format
00148               ( "Nothing removed from property \"%1%.%2%\"" ) 
00149               %  objName % propName),pos);   
00150       }
00151       else
00152       {
00153         m_catalogue.addProperty(objName,foundProp);
00154       }
00155       
00156     } 
00157     // ------------------------------------------------------------------------
00158   }
00159 }
00160 // ============================================================================
00161 void Gaudi::Parsers::Parser::setIsPrint
00162 ( bool on , const Gaudi::Parsers::Position& pos)
00163 {
00164   // ignore the printout if the full print is activated  
00165   if ( on && m_isPrintOptions ) { return ; }
00166   m_isPrint = on;
00167   //m_stream 
00168   //  << boost::format("%3% printing is %2% %|78t|%1%") 
00169   //  % posString(pos.line(),pos.column()) 
00170   //  % (on?"ON":"OFF") 
00171   //  % GPP_COMMENT 
00172   //  << std::endl ;
00173 }
00174 // ============================================================================
00175 void Gaudi::Parsers::Parser::setIsPrintOptions
00176 ( bool on , const Position& pos)
00177 {
00178   m_isPrintOptions = on;
00179   //m_stream 
00180   //  << boost::format ("%3% printing options is %2% %|78t|%1%") 
00181   //  % posString(pos.line(),pos.column()) 
00182   //  % (on?"ON":"OFF") 
00183   //  % GPP_COMMENT 
00184   //  << std::endl ;
00185   // deactivate the printout if the print of all options is activated 
00186   if ( m_isPrintOptions && m_isPrint ) { setIsPrint ( false , pos ) ; }
00187 }
00188 // ============================================================================
00189 bool Gaudi::Parsers::Parser::parseFile
00190 ( const std::string& fileName ,
00191   const Position& pos)
00192 {
00193   std::string fileToParse;
00194   bool ok = Gaudi::Parsers::Utils::searchFile(fileName,fileToParse);
00195   if(!ok){
00196     addMessage( Message::E_ERROR, Message::C_FILENOTFOUND,
00197                boost::str(boost::format("Couldn't find file \"%1%\"") % fileName),pos);
00198     return false;
00199   }
00200   
00201   ok = isIncluded(fileToParse);
00202   if(ok)
00203   {
00204     const std::string _msg = 
00205       ( boost::format("Skip already included file  \"%1%\"") % fileToParse ).str() ;
00206     addMessage ( Message::E_WARNING , Message::C_OK , _msg , pos ) ;
00207     if ( m_isPrint ) 
00208     { 
00209       m_stream 
00210         << boost::format("%3% skip already included file  \"%2%\" %|78t|%1%") 
00211         % posString(pos.line(), pos.column()) 
00212         % fileToParse 
00213         % GPP_COMMENT
00214         << std::endl ; 
00215     }
00216     return true;
00217   }
00218   std::string input;
00219   ok = Gaudi::Parsers::Utils::readFile(fileToParse,input);
00220   if(!ok)
00221   {
00222     addMessage
00223       ( Message::E_ERROR, Message::C_FILENOTOPENED,
00224        boost::str
00225        (boost::format("Couldn't open file \"%1%\"") % fileToParse),pos);
00226     return false;
00227   }  
00228   m_included.push_back(fileToParse);
00229   
00230   
00231   IteratorT beginpos(input.begin(), input.end(), fileToParse);
00232   IteratorT endpos;
00233   
00234   boost::spirit::parse_info<IteratorT> info; 
00235   SkipperGrammar grSkipper;      
00236   
00237   //m_stream 
00238   //    << boost::format("%3% include \"%2%\" %|78t|%1%") 
00239   //    % posString(pos.line(), pos.column()) 
00240   //    % fileToParse 
00241   //    % GPP_COMMENT 
00242   //    << std::endl ;
00243   ParserGrammar grParser(this);
00244   info = boost::spirit::parse(beginpos, endpos, grParser >> end_p,grSkipper);
00245 
00246   boost::spirit::file_position stoppos = info.stop.get_position();
00247   if (!info.full) {
00248     addMessage(Message::E_ERROR, Message::C_SYNTAXERROR,
00249                "Syntax error",Position(stoppos.file,stoppos.line,stoppos.column));
00250     return false;      
00251   }
00252   {
00253     std::string _msg =
00254       ( boost::format("Parsed file \"%2%\" %|78t|%1%")  
00255         % posString(stoppos.line, stoppos.column) 
00256         % fileToParse ) .str() ;
00257     addMessage ( Message::E_VERBOSE , 
00258                  Message::C_OK , 
00259                  _msg ,
00260                  Position(stoppos.file,stoppos.line,stoppos.column) ) ;
00261     if ( m_isPrint )
00262     { 
00263       m_stream 
00264         << boost::format("%3% end  \"%2%\" %|78t|%1%")
00265         % posString(stoppos.line, stoppos.column) 
00266         % fileToParse 
00267         % GPP_COMMENT 
00268         << std::endl ; 
00269     }
00270   }
00271   return true;  
00272 }
00273 // ============================================================================
00274 std::string Gaudi::Parsers::Parser::severityName
00275 (Message::Severity severity){
00276   switch(severity)
00277   {
00278   case Message::E_ERROR   :
00279     return "ERROR"     ;
00280   case Message::E_WARNING :
00281     return "WARNING"   ;
00282   case Message::E_NOTICE  :
00283     return "NOTICE"    ;
00284   case Message::E_VERBOSE :
00285     return "VERBOSE"   ;
00286   default:
00287     return "UNDEFINED" ; 
00288   }
00289 }
00290 // ============================================================================
00291 void Gaudi::Parsers::Parser::addMessage
00292 ( const Message::Severity& severity ,
00293   const Message::Code&     code     , 
00294   const std::string&       message  , 
00295   const Position&          pos      )
00296 {
00297   Message result
00298     ( severity , code,
00299       boost::str(boost::format("%1%(%2%,%3%) : %4% #%5% : %6%") % pos.fileName()
00300                  % pos.line() % pos.column() % severityName(severity) % code 
00301                  % message));
00302   m_messages.push_back(result);
00303 }
00304 // ============================================================================
00305 // Purpose: Implementation of Parser::isIncluded()
00306 // Comment: Test if file already included
00307 // Parameters:
00308 //  - fileName File name
00309 // Return: true if file already included
00310 // ============================================================================
00311 bool Gaudi::Parsers::Parser::isIncluded(const std::string& fileName)
00312 {
00313   for(std::vector<std::string>::const_iterator cur=m_included.begin();
00314       cur!=m_included.end();cur++)
00315   { if(fileName==*cur){ return true; } }
00316   return false;
00317 }
00318 // ============================================================================
00319 // Purpose: Implementation of Parser::resolveReferences()
00320 // Comment: Resolve references
00321 // TODO: Refactor?
00322 // ============================================================================
00323 void Gaudi::Parsers::Parser::resolveReferences()
00324 {
00325   Catalogue::CatalogueT cat = m_catalogue.catalogue();
00326   // ----------------------------------------------------------------------------
00327   for( Catalogue::CatalogueT::const_iterator curObj = cat.begin();  
00328        curObj!=cat.end();curObj++)
00329   {
00330     std::string objName = curObj->first;
00331     // ------------------------------------------------------------------------
00332     for( std::vector<PropertyEntry>::const_iterator curProp = 
00333            curObj->second.begin();curProp != curObj->second.end(); curProp++)
00334     {
00335       std::string value = curProp->value();
00336       if ( (value.length()>0) && (value[0]=='@'))
00337       {
00338         // --------------------------------------------------------------------
00339         std::vector<std::string> objAndProp;
00340         std::string refprop(value.begin()+1,value.end());
00341         ba::split(objAndProp,
00342                   refprop,
00343                   ba::is_any_of("."));            
00344         PropertyEntry foundProperty;
00345         bool ok;
00346         ok = m_catalogue.findProperty(objAndProp[0],objAndProp[1],
00347                                       foundProperty);
00348         if(!ok)
00349         {
00350           addMessage
00351             ( Message::E_ERROR,
00352               Message::C_PROPERTYNOTFOUND,
00353               boost::str(boost::format("Cannot find property \"%1%.%2%\"")
00354                          % objAndProp[0] % objAndProp[1]),curProp->position());
00355         }
00356         else
00357         {
00358           // -------------------------------------------------------------------
00359           if((ba::to_lower_copy(objAndProp[0]) == objName)
00360              && 
00361              (ba::to_lower_copy(objAndProp[1]) 
00362               == curProp->name()))
00363           {
00364             // ----------------------------------------------------------------
00365             addMessage
00366               ( Message::E_ERROR,
00367                 Message::C_BADREFERENCE,
00368                 boost::str(boost::format("Reference to self \"%1%.%2%\"")
00369                            % objAndProp[0] % objAndProp[1]),curProp->position());
00370             // ----------------------------------------------------------------
00371           }
00372           else
00373           {
00374             PropertyEntry property = foundProperty;
00375             property.setName(curProp->name());
00376             m_catalogue.addProperty(objName,property);
00377           }
00378           // ------------------------------------------------------------------
00379         }
00380         // --------------------------------------------------------------------
00381       }
00382     }
00383     // ------------------------------------------------------------------------
00384   }
00385 }
00386 // ============================================================================
00387 // String representation of sign
00388 // ============================================================================
00389 std::string Gaudi::Parsers::Parser::sign(Sign aSign)
00390 {
00391   switch(aSign)
00392   {
00393   case S_ASSIGN:
00394     return "=";
00395   case S_PLUSASSIGN:
00396     return "+=";
00397   case S_MINUSASSIGN:
00398     return "-=";
00399   default:
00400     return "unknown_operation";
00401   }
00402 }
00403 // ============================================================================
00404 // String representation of value vector
00405 // ============================================================================
00406 std::string Gaudi::Parsers::Parser::valueToString
00407 ( std::vector<std::string> value, bool isVector )
00408 {
00409   if ( !isVector){ return value[0]; }
00410   //
00411   std::string result;
00412   std::string delim;
00413   result+=" [ ";
00414   for ( std::vector<std::string>::const_iterator cur = value.begin();
00415         cur != value.end(); cur++ )
00416   {
00417     result += delim + *cur;
00418     delim = " , ";
00419   }
00420   return result + " ] ";
00421 }
00422 // ============================================================================
00423 /*  Implementation of Gaudi::Parsers::Utils::posString()
00424  *  Comment: Convert position to string
00425  *  Parameters:
00426  *    - line Line
00427  *    - column Column
00428  */
00429 // ============================================================================
00430 std::string Gaudi::Parsers::Parser::posString(int line, int column)
00431 { return boost::str(boost::format("(%1%,%2%)") % line % column); }
00432 // ============================================================================
00433 
00434 // ============================================================================
00435 // The END 
00436 // ============================================================================
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Fri May 16 2014 09:50:18 for LafKernel by doxygen 1.7.4