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

In This Package:

ParserGrammar.h
Go to the documentation of this file.
00001 // $Id: ParserGrammar.h,v 1.11 2008/12/08 13:49:57 marcocle Exp $
00002 // ============================================================================
00003 #ifndef JOBOPTIONSSVC_PARSERGRAMMAR_H
00004 #define JOBOPTIONSSVC_PARSERGRAMMAR_H 1
00005 // ============================================================================
00006 // Include files
00007 // ============================================================================
00008 // STD & STL
00009 // ============================================================================
00010 #include <string>
00011 #include <vector>
00012 // ============================================================================
00013 // Boost
00014 // ============================================================================
00015 #include <boost/spirit.hpp>
00016 #include <boost/bind.hpp>
00017 #include <boost/tuple/tuple.hpp>
00018 // ============================================================================
00019 #include "Grammars.h"
00020 #include "ToStream.h"
00021 // ============================================================================
00022 // Local
00023 // ============================================================================
00024 #include "ParserUtils.h"
00025 #include "ParserActions.h"
00026 // ============================================================================
00027 namespace Gaudi
00028 {
00029   namespace Parsers
00030   {
00031     // ========================================================================
00032     using namespace boost::spirit ;
00033     using namespace phoenix;
00034     // ========================================================================
00035     typedef boost::spirit::position_iterator<std::string::const_iterator>
00036     IteratorT;
00037     // ========================================================================
00046     class IdentifierGrammar : public grammar
00047     <
00048       IdentifierGrammar, ClosureGrammar<std::string>::context_t
00049     >
00050     {
00051     public:
00052       typedef std::string ResultT;
00053     public:
00054       template <typename ScannerT>
00055       struct definition
00056       {
00057         definition( IdentifierGrammar const &self )
00058         {
00059           //-----------------------------------------------------------------
00060           // KEYWORDS
00061           //-----------------------------------------------------------------
00062           keywords =
00063             "#include" ,
00064             "#units"   ,
00065             "#ifdef"   ,
00066             "#ifndef"  ,
00067             "#endif"   ,
00068             "#else"    ,
00069             "WIN32"    ;
00070           identifier
00071             = (lexeme_d[ (alpha_p >> *(alnum_p | '_'))
00072                          - (keywords >>
00073                             (anychar_p - (alnum_p | '_')))])
00074             [self.val = construct_<std::string>(arg1,arg2)];
00075         }
00076         symbols<> keywords;
00077         rule<ScannerT> const& start() const
00078         { return identifier; }
00079         rule<ScannerT> identifier;
00080       };
00081     };
00082     // ========================================================================
00091     class PropertyGrammar: public grammar
00092         <
00093                 PropertyGrammar,
00094                 ClosureGrammar<std::vector<std::string> >::context_t
00095         >
00096     {
00097         public:
00098           typedef std::vector<std::string> ResultT;
00099         public:
00100               template <typename ScannerT>
00101               struct definition
00102               {
00103                 definition(PropertyGrammar const &self )
00104                 {
00105                                 ns = (ident >> *("::">>ident))[ns.val = construct_<std::string>(arg1,arg2)]>>".";
00106                                 property = +(ns[PushBack(self.val)]) >> ident[PushBack(self.val)];
00107 
00108                 }
00109                 IdentifierGrammar ident;
00110                 rule<ScannerT> const& start() const
00111                 { return property; }
00112                 rule<ScannerT,ClosureGrammar<std::string>::context_t>  ns;
00113                 rule<ScannerT> property;
00114               };
00115     };
00116     // ========================================================================
00126     class RealUnitsGrammar : public boost::spirit::grammar
00127     < RealUnitsGrammar,AttributesClosureGrammar<std::string,
00128                              boost::tuple<IteratorT, long double> >::context_t >
00129     {
00130     public:
00131       typedef long double ResultT;
00132       RealUnitsGrammar():m_parser(NULL){}
00133     public:
00134       template <typename ScannerT>
00135       struct definition
00136       {
00137         definition(RealUnitsGrammar const &self)
00138         {
00139           real_literal
00140             = (
00141                longest_d[grInt[boost::bind(&RealUnitsGrammar::matchReal,&self,_1)]
00142                 |grReal[boost::bind(&RealUnitsGrammar::matchReal,&self,_1)]]
00143                >> eps_p[boost::bind(&RealUnitsGrammar::matchPosition,&self,_2)]
00144                >>!(!ch_p('*')
00145                >>grUnit
00146                [boost::bind(&RealUnitsGrammar::matchUnit,&self,_1)]
00147                )) [boost::bind(&RealUnitsGrammar::matchRealUnits,&self)];
00148         }
00149         RealGrammar<long double> grReal;
00150         IntGrammar<int> grInt;
00151         IdentifierGrammar grUnit;
00152         boost::spirit::rule<ScannerT> const& start() const
00153         { return real_literal; }
00154         boost::spirit::rule<ScannerT> real_literal;
00155       };
00156       // Action when we recognize real with unit
00157       void matchRealUnits() const
00158       {
00159         val() = Gaudi::Utils::toString ( attrs().get<1>() );
00160       }
00161 
00162       // Action when we recognize real (without unit)
00163       void matchReal(ResultT value) const
00164       { attrs().get<1>()=value; }
00165 
00166       // Action for saving position
00167       void matchPosition(IteratorT value) const
00168       { attrs().get<0>()=value; }
00169 
00170       // Action when we recognize unit
00171       void matchUnit(const std::string& /*unit*/) const
00172       {
00173       }
00174 
00178       void setParser(Parser* parser){m_parser = parser;}
00179     private:
00180       Parser* m_parser;
00181     };
00182     // ========================================================================
00183     typedef AttributesClosureGrammar
00184     <boost::tuple<std::string,std::vector<std::string> > ,
00185      boost::tuple<int> > ValueClosureT;
00186     // ========================================================================
00219     class ValueGrammar : public boost::spirit::grammar
00220     <ValueGrammar, ValueClosureT::context_t>
00221     {
00222     public:
00223       ValueGrammar() : m_parser(NULL){}
00224     public:
00229       void matchBrace(bool isopen) const
00230       {
00231         if ( isopen ){ attrs().get<0>()++; }
00232         else         { attrs().get<0>()--; }
00233       }
00238       void matchVectorValue(std::string value) const
00239       { if(attrs().get<0>()==1){val().get<1>().push_back(value); } }
00240 
00245       void matchValue(std::string value) const{ val().get<0>() = value; }
00246 
00248       Parser* parser() const { return m_parser;}
00249 
00251       void setParser(Parser* parser){ m_parser = parser; }
00252 
00253     public:
00254 
00255       template <typename ScannerT>
00256       struct definition
00257       {
00258         definition(ValueGrammar const &self)
00259         {
00260           realunits_grammar.setParser(self.parser());
00261           //-----------------------------------------------------------------
00262           // OPERATORS
00263           //-----------------------------------------------------------------
00264           chlit<>     O_DOT('.');
00265           chlit<>     O_COMMA(',');
00266           value_rule = value[boost::bind(&ValueGrammar::matchValue,&self,_1)];
00267           value =
00268             vectorvalue[value.val=arg1]
00269             | vector_type[value.val="["+arg1+"]"]
00270             | property_link[value.val=arg1]
00271             ;
00272           // ------------------------------------------------------------------
00273           vectorvalue_list
00274             = !(
00275                 value[vectorvalue_list.val=arg1][boost::bind(&ValueGrammar::matchVectorValue,&self,_1)]
00276                 >> *(',' >>value[vectorvalue_list.val+=","+arg1][boost::bind(&ValueGrammar::matchVectorValue,&self,_1)])
00277                 );
00278           // ------------------------------------------------------------------
00279           vector_type =
00280             (
00281              ch_p('{')[boost::bind(&ValueGrammar::matchBrace,&self,true)]
00282              >> vectorvalue_list
00283              [vector_type.val=arg1]
00284              >> ch_p('}')[boost::bind(&ValueGrammar::matchBrace,&self,false)]
00285              )
00286             |
00287             (ch_p('[') [boost::bind(&ValueGrammar::matchBrace,&self,true)]
00288              >> vectorvalue_list
00289              [vector_type.val=arg1]
00290              >> ch_p(']')[boost::bind(&ValueGrammar::matchBrace,&self,false)]
00291              );
00292           // ------------------------------------------------------------------
00293           vectorvalue =
00294             listvalue[vectorvalue.val=arg1]
00295             | longest_d[
00296                         literalvalue[vectorvalue.val=arg1]
00297                         | mapvalue[vectorvalue.val=arg1]
00298             ];
00299           // ------------------------------------------------------------------
00300           listvalue = '(' >> vectorvalue[listvalue.val="("+arg1]
00301                           >> *(O_COMMA[listvalue.val+=","]
00302                           >> vectorvalue[listvalue.val+=arg1]) >>ch_p(')')[listvalue.val+=")"];
00303           // ------------------------------------------------------------------
00304           mapvalue = literalvalue[mapvalue.val=arg1]
00305             >> (ch_p('=')[mapvalue.val+="="] | ch_p(':')[mapvalue.val+=":"])
00306             >> value[mapvalue.val+=arg1]
00307             ;
00308           // ------------------------------------------------------------------
00309           literalvalue =
00310             realunits_grammar[literalvalue.val = arg1]
00311             |
00312             boolean_grammar[AssignBoolToString(literalvalue.val)]
00313             |
00314             string_grammar[literalvalue.val = std::string("\"")+arg1+std::string("\"")];
00315           // ------------------------------------------------------------------
00316           property_link = ('@'>>property_grammar)
00317             [property_link.val=construct_<std::string>(arg1,arg2)];
00318           // ------------------------------------------------------------------
00319         }
00320         PropertyGrammar   property_grammar;
00321         StringGrammar     string_grammar;
00322         BoolGrammar       boolean_grammar;
00323         IntGrammar<long>  int_grammar;
00324         RealUnitsGrammar  realunits_grammar;
00325 
00326         boost::spirit::rule<ScannerT> value_rule;
00327         boost::spirit::rule
00328         <ScannerT,ClosureGrammar<std::string>::context_t> value,literalvalue,
00329           vectorvalue,listvalue,mapvalue,vectorvalue_list, vector_type,
00330           property_link;
00331         boost::spirit::rule<ScannerT> const& start() const { return value_rule; }
00332       };
00333       // ============================================================================
00334     private:
00335       Parser* m_parser;
00336     };
00337     // ========================================================================
00338     typedef AttributesClosureGrammar
00339     <IteratorT,boost::tuple<bool,std::string,std::vector<std::string> > > ParserClosureT;
00340     // ========================================================================
00380     class ParserGrammar :
00381       public grammar<ParserGrammar, ParserClosureT::context_t> {
00382     public:
00387       ParserGrammar(Parser* parser){m_parser=parser;}
00388       virtual ~ParserGrammar() {}
00389 
00391       Parser* parser() const {return m_parser;}
00392 
00397       void matchInclude(const std::string& fileName) const{
00398         if(!doActions()) return;
00399         file_position fpos = this->val().get_position();
00400         Position pos(fpos.file,fpos.line,fpos.column);
00401         m_parser->matchInclude(fileName,pos);
00402       }
00406       void matchUnits(const std::string& /*fileName*/) const{
00407       }
00415       void matchAssign(std::vector<std::string> params) const{
00416         if(!doActions()) return;
00417 
00418         // position where statement appears
00419         file_position fpos = val().get_position();
00420         Position pos(fpos.file,fpos.line,fpos.column);
00421 
00422         // get value representation. It's two modes string and vector of strings
00423         std::string value = attrs().get<1>();
00424         std::vector<std::string> vectorValues = attrs().get<2>();
00425 
00426         // check if value is vector
00427         bool isVector = false;
00428         if(vectorValues.size()>0 || value=="[]"){
00429           isVector = true;
00430         }else{
00431           vectorValues.push_back(value);
00432         }
00433 
00434         // extract object, option name and sign
00435         std::string objectName;
00436         std::string delim;
00437         std::vector< std::string >::const_iterator cur;
00438         for ( cur  = params.begin();
00439               *(cur+1) != "#"; cur++ ){
00440           objectName += delim + *cur;
00441           delim = ".";
00442         }
00443 
00444         std::string optionName = *cur;
00445         std::string sign = *(cur+2);
00446 
00447         Parser::Sign oper;
00448         if(sign == "+="){
00449           oper = Parser::S_PLUSASSIGN;
00450         }else if(sign == "-="){
00451           oper = Parser::S_MINUSASSIGN;
00452         }else{
00453           oper = Parser::S_ASSIGN;
00454         }
00455 
00456         m_parser->matchAssign
00457           (objectName, optionName, oper,
00458            vectorValues,pos,isVector);
00459         vectorValues.clear();
00460       }
00461       // ======================================================================
00466       void matchPlatform(const std::string& directive) const{
00467         if(directive=="endif" || directive=="ifndef"){
00468           attrs().get<0>() = true;
00469         } else {
00470           attrs().get<0>() = !attrs().get<0>();
00471         }
00472       }
00473       // ======================================================================
00478       void matchPrint(bool on) const{
00479         file_position fpos = this->val().get_position();
00480         Position pos(fpos.file,fpos.line,fpos.column);
00481         m_parser->setIsPrint(on,pos);
00482       }
00483       // ======================================================================
00488       void matchPrintOptions(bool on) const{
00489         file_position fpos = this->val().get_position();
00490         Position pos(fpos.file,fpos.line,fpos.column);
00491         m_parser->setIsPrintOptions(on,pos);
00492       }
00493       // ======================================================================
00498       void matchValue(boost::tuple<std::string,std::vector<std::string> > value) const{
00499         if(!doActions()) return;
00500         attrs().get<1>() = value.get<0>();
00501         attrs().get<2>() = value.get<1>();
00502       }
00503       // ======================================================================
00507       bool doActions() const{ return  attrs().get<0>();}
00508       // ======================================================================
00509       template <typename ScannerT>
00510       struct definition {
00511 
00512         definition(ParserGrammar const &self) {
00513           value_grammar.setParser(self.parser());
00514           boost::tuples::get<0>(self.attrs()) = true;
00515           // ------------------------------------------------------------------
00516           // OPERATORS
00517           // ------------------------------------------------------------------
00518           chlit<>     O_SEMI(';');
00519           chlit<>     O_DOT('.');
00520 
00521           strlit<>    O_ASSIGN("=");
00522           strlit<>    O_PLUSASSIGN("+=");
00523           strlit<>    O_MINUSASSIGN("-=");
00524 
00525           // ------------------------------------------------------------------
00526           // TOKENS
00527           // ------------------------------------------------------------------
00528                                         strlit<> T_SHELL("#!");
00529           strlit<> T_IFDEF("#ifdef");
00530           strlit<> T_IFNDEF("#ifndef");
00531           strlit<> T_ELSE("#else");
00532           strlit<> T_ENDIF("#endif");
00533           strlit<> T_WIN32("WIN32");
00534           strlit<> T_INCLUDE("#include");
00535           strlit<> T_UNITS("#units");
00536           strlit<> T_PRAGMA("#pragma");
00537           strlit<> T_PRINTOPTIONS("#printOptions");
00538           // ------------------------------------------------------------------
00539           job_options_file =
00540             !shell_statement >> *(platform_statement | platform_dependency);
00541           // ------------------------------------------------------------------
00542                                         shell_statement = comment_p(T_SHELL);
00543           // ------------------------------------------------------------------
00544                             platform_statement = assertable_statement | pragma_statement;
00545           // ------------------------------------------------------------------
00546           assertable_statement =
00547             include_statement
00548             [boost::bind(&ParserGrammar::matchInclude,&self,_1)]
00549             | units_statement
00550             [boost::bind(&ParserGrammar::matchUnits,&self,_1)]
00551             | assign_statement
00552             [boost::bind(&ParserGrammar::matchAssign,&self,_1)];
00553           // ------------------------------------------------------------------
00554           assertion_statement =
00555             T_IFDEF
00556             [boost::bind(&ParserGrammar::matchPlatform,&self,"ifdef")]
00557             |
00558             T_IFNDEF
00559             [boost::bind(&ParserGrammar::matchPlatform,&self,"ifndef")];
00560           // ------------------------------------------------------------------
00561           platform_dependency =
00562             assertion_statement
00563               >> T_WIN32
00564               >> *platform_statement
00565               >> !(
00566                    T_ELSE[boost::bind(&ParserGrammar::matchPlatform,&self,"else")]
00567                    >> *platform_statement
00568                    )
00569               >> T_ENDIF
00570             [boost::bind(&ParserGrammar::matchPlatform,&self,"endif")];
00571           // ------------------------------------------------------------------
00572           include_statement =
00573             T_INCLUDE
00574               >> (string_grammar[include_statement.val=arg1]>>eps_p)
00575             [self.val=arg1];
00576           // ------------------------------------------------------------------
00577           units_statement =
00578             T_UNITS
00579               >> (string_grammar[units_statement.val=arg1]>>eps_p)
00580             [self.val=arg1];;
00581           // ------------------------------------------------------------------
00582           pragma_statement = pragma | printopt_statement;
00583           // ------------------------------------------------------------------
00584           pragma = (T_PRAGMA>>eps_p)[self.val=arg1] >> str_p("print")
00585                             >> ((str_p("on") | str_p("ON"))
00586                                 [boost::bind(&ParserGrammar::matchPrint,&self,true)]
00587                                 | (str_p("off") | str_p("OFF"))
00588                                 [boost::bind(&ParserGrammar::matchPrint,&self,false)]) ;
00589           // ------------------------------------------------------------------
00590           printopt_statement = ((T_PRINTOPTIONS>>eps_p)[self.val = arg1] >>
00591             !as_lower_d["full"])
00592             [boost::bind(&ParserGrammar::matchPrintOptions,&self,true)];
00593           // ------------------------------------------------------------------
00594           assign_statement =
00595                   property_grammar[assign_statement.val=arg1]
00596               >> eps_p[PushBack(assign_statement.val,"#")]
00597               >> (
00598                   O_ASSIGN[PushBack(assign_statement.val,"=")]
00599                   |O_PLUSASSIGN[PushBack(assign_statement.val,"+=")]
00600                   |O_MINUSASSIGN[PushBack(assign_statement.val,"-=")]
00601                   )
00602               >>  value_grammar[boost::bind(&ParserGrammar::matchValue,&self,_1)]
00603               >> O_SEMI;
00604           // ------------------------------------------------------------------
00605         }
00606         // --------------------------------------------------------------------
00607         PropertyGrammar property_grammar;
00608         IdentifierGrammar identifier_grammar;
00609         StringGrammar string_grammar;
00610         ValueGrammar value_grammar;
00611         // --------------------------------------------------------------------
00612         rule<ScannerT,ClosureGrammar<std::string>::context_t>  include_statement,
00613           units_statement;
00614 
00615         rule<ScannerT,ClosureGrammar<std::vector<std::string> >::context_t> assign_statement;
00616 
00617         rule<ScannerT>
00618         job_options_file,
00619                                         shell_statement,
00620           platform_statement,
00621           assertable_statement,
00622           assertion_statement,
00623           platform_dependency,
00624           pragma_statement,
00625           pragma,
00626           printopt_statement;
00627         // --------------------------------------------------------------------
00628         rule<ScannerT> const& start() const {
00629           return job_options_file;
00630         }
00631         // --------------------------------------------------------------------
00632       };
00633       // ======================================================================
00634     private:
00635       Parser* m_parser;
00636     };
00637   } // end of namespace Parsers
00638 } // end of namespace Gaudi
00639 // ============================================================================
00640 // The END
00641 // ============================================================================
00642 #endif // JOBOPTIONSSVC_PARSERGRAMMAR_H
00643 // ============================================================================
00644 
| 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