| # Gaudi Framework, version v23r1 |

Home |  | Generated: Wed Feb 29 2012

# Grammars.h

Go to the documentation of this file.

    00001 // ============================================================================
    00002 #ifndef GAUDIKERNEL_GRAMMARS_H
    00003 #define GAUDIKERNEL_GRAMMARS_H 1
    00004 #ifdef __GNUC__
    00005 #warning \
    00006   The headers GaudiKernel/Grammars.h and GaudiKernel/Parsers.icpp are deprecated \
    00007   and will be removed from the next release of Gaudi. You should migrate your \
    00008   code the new pasers based on Boost.Spirit 2.
    00009 #endif
    00010 // ============================================================================
    00011 // Include files
    00012 // ============================================================================
    00013 // STD & STL
    00014 // ============================================================================
    00015 #include <cctype>
    00016 // ============================================================================
    00017 // Boost.Spirit
    00018 // ============================================================================
    00019 #include <boost/version.hpp>
    00020 #if BOOST_VERSION >= 103800
    00021 // FIXME: Move to the new boost::spirit::classic namespace
    00022 #if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
    00023 #define BOOST_SPIRIT_USE_OLD_NAMESPACE
    00024 #endif
    00025 #include <boost/spirit/include/classic.hpp>
    00026 #include <boost/spirit/include/phoenix1.hpp>
    00027 #else
    00028 #include <boost/spirit.hpp>
    00029 #include <boost/spirit/phoenix.hpp>
    00030 #endif
    00031 #include <boost/bind.hpp>
    00032
    00033 // ============================================================================
    00044 // ============================================================================
    00045 namespace Gaudi
    00046 {
    00047   namespace Parsers
    00048   {
    00049     // ========================================================================
    00050     using namespace boost::spirit ;
    00051     // ========================================================================
    00052     using namespace phoenix ;
    00053     // ========================================================================
    00062    template <typename T>
    00063     struct ClosureGrammar : public boost::spirit::closure < ClosureGrammar<T>,T >
    00064     {
    00065       typedef  boost::spirit::closure<ClosureGrammar, T> closure;
    00066       typename closure::member1 val;
    00067     };
    00068     // ========================================================================
    00079     template <typename T1,typename T2>
    00080     struct AttributesClosureGrammar
    00081       : public boost::spirit::closure<AttributesClosureGrammar<T1,T2>,T1,T2>
    00082     {
    00083       typedef boost::spirit::closure<AttributesClosureGrammar, T1,T2> closure;
    00084       typename closure::member1 val;
    00085       typename closure::member2 attrs;
    00086     };
    00087     // ========================================================================
    00099     class BoolGrammar : public grammar
    00100     <
    00101       BoolGrammar,
    00102       ClosureGrammar<bool>::context_t
    00103     >
    00104     {
    00105     public:
    00106       typedef bool ResultT;
    00107     public:
    00108       template <typename ScannerT>
    00109       struct definition
    00110       {
    00111         definition( BoolGrammar const &self)
    00112         {
    00113           boolean_literal
    00114             = true_literal[self.val = true] | false_literal[self.val = false];
    00115           true_literal
    00116             = str_p("true" ) | str_p("True" ) | str_p("TRUE" ) | str_p("1");
    00117           false_literal
    00118             = str_p("false") | str_p("False") | str_p("FALSE") | str_p("0");
    00119         }
    00120         rule<ScannerT> const& start() const
    00121         { return boolean_literal;}
    00122         rule<ScannerT> boolean_literal,true_literal,false_literal;
    00123       };
    00124     };
    00125     // ========================================================================
    00136     template<typename RT=char>
    00137     class CharGrammar : public grammar
    00138     <
    00139       CharGrammar<RT> , typename ClosureGrammar<RT>::context_t
    00140     >
    00141     {
    00142     public:
    00143       typedef RT ResultT;
    00144     public:
    00145       template <typename ScannerT>
    00146       struct definition
    00147       {
    00148         definition( CharGrammar<RT> const &self)
    00149         {
    00150           char_literal
    00151             = int_parser<RT>()[self.val=arg1]
    00152             | ('\''
    00153                >> ( str_p("\\'")[self.val='\'']
    00154                     | (anychar_p[self.val=arg1]-'\'') )>>'\'');
    00155         }
    00156         rule<ScannerT> const& start() const
    00157         { return char_literal; }
    00158         rule<ScannerT> char_literal;
    00159       };
    00160     };
    00161     // ========================================================================
    00173     template<typename RT=int>
    00174     class IntGrammar : public grammar
    00175     <
    00176       IntGrammar<RT>,
    00177       typename ClosureGrammar<RT>::context_t
    00178     >
    00179     {
    00180     public:
    00181       typedef RT ResultT;
    00182     public:
    00183       template <typename ScannerT>
    00184       struct definition
    00185       {
    00186         definition( IntGrammar<RT> const &self)
    00187         {
    00188           int_literal = lexeme_d[int_parser<RT>()[self.val=arg1]
    00189             >> !(ch_p('u') | ch_p('U') | ch_p('l') | ch_p('L'))];
    00190         }
    00191         rule<ScannerT> const& start() const { return int_literal; }
    00192         rule<ScannerT> int_literal;
    00193       };
    00194     };
    00195     // ========================================================================
    00207     template<typename RT=double>
    00208     class RealGrammar : public grammar
    00209     <
    00210       RealGrammar<RT>,typename ClosureGrammar<RT>::context_t
    00211     >
    00212     {
    00213     public:
    00214       typedef RT ResultT;
    00215     public:
    00216       template <typename ScannerT>
    00217       struct definition
    00218       {
    00219         definition( RealGrammar const &self)
    00220         {
    00221           real_literal
    00222             = lexeme_d[real_parser<RT,
    00223             real_parser_policies<RT> >()[self.val = arg1]
    00224             >> !(ch_p('f') | ch_p('F') | ch_p('l') | ch_p('L'))];
    00225         }
    00226         rule<ScannerT> const& start() const
    00227         { return real_literal; }
    00228         rule<ScannerT> real_literal;
    00229       };
    00230     };
    00231     // ========================================================================
    00246     class StringGrammar : public grammar
    00247     <
    00248       StringGrammar, ClosureGrammar<std::string>::context_t
    00249     >
    00250     {
    00251     public:
    00252       typedef std::string ResultT;
    00261       void matchString() const
    00262       {
    00263         for ( std::string::iterator cur=this->val().begin();
    00264               cur!=this->val().end();cur++)
    00265         { if(std::isspace(*cur) ) { *cur = ' '; } }
    00266       }
    00267     public:
    00268         template <typename ScannerT>
    00269         struct definition
    00270         {
    00271           definition( StringGrammar const &self )
    00272           {
    00273             string_literal = (lexeme_d
    00274               [
    00275                ('"' >> (*( str_p("\\\"")
    00276                            |
    00277                            (anychar_p-'"') ))
    00278                 [self.val = construct_<std::string>
    00279                  (arg1,arg2)] >>
    00280                 '"')
    00281                |
    00282                ('\'' >> (*( str_p("\\'")
    00283                             |
    00284                             (anychar_p-'\'') ))
    00285                 [self.val = construct_<std::string>
    00286                  (arg1,arg2)]>>
    00287                 '\'')])[boost::bind(&StringGrammar::matchString,&self)];
    00288           }
    00289           rule<ScannerT> const& start() const { return string_literal; }
    00290           rule<ScannerT> string_literal;
    00291         };
    00292       };
    00293     // ========================================================================
    00306     class SkipperGrammar : public grammar<SkipperGrammar>
    00307     {
    00308     public:
    00312       SkipperGrammar ( const bool skipnewline = true )
    00313         : m_skipnewline(skipnewline){}
    00314     public:
    00316       bool skipnewline() const{return m_skipnewline;}
    00317     public:
    00318       template <typename ScannerT>
    00319       struct definition
    00320       {
    00321         definition( SkipperGrammar const& self)
    00322         {
    00323           if ( self.skipnewline() )
    00324           {
    00325             skip
    00326               =   space_p
    00327               |   comment_p("//")     // C++ comment
    00328               |   comment_p("/*", "*/")     // C comment
    00329               ;
    00330           }
    00331           else
    00332           {
    00333             skip
    00334               =   (space_p-eol_p)
    00335               |   comment_p("//")     // C++ comment
    00336               |   comment_p("/*", "*/")     // C comment
    00337               ;
    00338           }
    00339         }
    00340         rule<ScannerT>  skip;
    00341         rule<ScannerT> const& start() const { return skip; }
    00342       };
    00343     private:
    00344       bool m_skipnewline;
    00345     };
    00346     // ========================================================================
    00357     template <typename KeyGrammarT, typename ValueGrammarT>
    00358     class PairGrammar : public grammar
    00359     <
    00360       PairGrammar<KeyGrammarT,ValueGrammarT>,
    00361       typename ClosureGrammar<
    00362       std::pair<typename KeyGrammarT::ResultT,
    00363                 typename ValueGrammarT::ResultT> >::context_t
    00364     >
    00365     {
    00366     public:
    00367       typedef typename KeyGrammarT::ResultT KeyT;
    00368       typedef typename ValueGrammarT::ResultT ValueT;
    00369       typedef std::pair<KeyT,ValueT> ResultT;
    00370     public:
    00374       PairGrammar ( const std::string&  delim = "," )
    00375         : m_delim(delim) {}
    00376     public:
    00378       void matchFirst  ( const KeyT&   first  ) const { this->val().first = first; }
    00380       void matchSecond ( const ValueT& second ) const { this->val().second = second; }
    00381     public:
    00382       template <typename ScannerT>
    00383       struct definition
    00384       {
    00385         definition( PairGrammar const &self)
    00386         {
    00387           para
    00388             = (
    00389                str_p("(")
    00390                >> (grkey[boost::bind(&PairGrammar::matchFirst,&self,_1)])
    00391                >> self.delim().c_str()
    00392                >> (grvalue[boost::bind(&PairGrammar::matchSecond,&self,_1)])
    00393                >> str_p(")")
    00394                ) ;
    00395         }
    00396         rule<ScannerT> const& start() const { return para; }
    00397         rule<ScannerT> para;
    00398         KeyGrammarT grkey;
    00399         ValueGrammarT grvalue;
    00400       };
    00401     public:
    00403       const std::string& delim() const { return m_delim ; }
    00407       void setDelim ( const std::string& delim ) { m_delim = delim;}
    00408     private:
    00409       std::string m_delim;
    00410     };
    00411     // ========================================================================
    00423     template <typename GrammarT>
    00424     class VectorGrammar : public grammar
    00425     <
    00426       VectorGrammar<GrammarT> ,
    00427       typename ClosureGrammar<std::vector<typename GrammarT::ResultT> >::context_t
    00428     >
    00429     {
    00430     public:
    00431       typedef typename GrammarT::ResultT ValueT;
    00432       typedef std::vector<ValueT> ResultT;
    00433       typedef VectorGrammar<GrammarT> SelfT;
    00434     public:
    00436       void matchItem(const ValueT& value) const { this->val().push_back(value); }
    00437     public:
    00438       template <typename ScannerT>
    00439       struct definition
    00440       {
    00441         definition(SelfT const &self)
    00442         {
    00443           inner =
    00444             !(gr[boost::bind(&VectorGrammar::matchItem,&self,_1)]
    00445               >> *(','>>gr[boost::bind(&VectorGrammar::matchItem,&self,_1)]));
    00446           vec =
    00447             '[' >> inner >> ']' |  // a'la python list
    00448             '(' >> inner >> ')' |  // a'la python tuple
    00449             '{' >> inner >> '}' ;  // like obsolete list from opts-grammar
    00450         }
    00451         rule<ScannerT> const& start() const { return vec; }
    00452         rule<ScannerT> vec,inner;
    00453         GrammarT gr;
    00454       };
    00455     };
    00456     // ========================================================================
    00471     template <typename KeyGrammarT, typename ValueGrammarT>
    00472     class MapGrammar : public grammar
    00473     <
    00474       MapGrammar<KeyGrammarT,ValueGrammarT>,
    00475       typename AttributesClosureGrammar
    00476       < std::map<typename KeyGrammarT::ResultT,
    00477                  typename ValueGrammarT::ResultT>,
    00478         std::pair<typename KeyGrammarT::ResultT,
    00479                   typename ValueGrammarT::ResultT> >::context_t
    00480     >
    00481     {
    00482     public:
    00483       typedef typename KeyGrammarT::ResultT KeyT;
    00484       typedef typename ValueGrammarT::ResultT ValueT;
    00485       typedef std::map<KeyT,ValueT> ResultT;
    00486     public:
    00488       void matchItem  () const
    00489       {
    00490         //this->val().insert(this->attrs());
    00491         this->val()[this->attrs().first] = this->attrs().second ;
    00492       }
    00494       void matchFirst ( const KeyT&   value ) const {  this->attrs().first = value ; }
    00496       void matchSecond( const ValueT& value ) const { this->attrs().second = value ; }
    00497     public:
    00498       template <typename ScannerT>
    00499       struct definition
    00500       {
    00501         definition( MapGrammar const &self)
    00502         {
    00503           vec
    00504             = ('{'>> inner_list >> '}') | ('['>>inner_list>>']');
    00505           inner_list
    00506             =
    00507             !( inner[boost::bind(&MapGrammar::matchItem,&self)]
    00508                >> *( ch_p(',') >>
    00509                      inner[boost::bind(&MapGrammar::matchItem,&self)] )
    00510                );
    00511           inner
    00512             =
    00513             grKey[boost ::bind(&MapGrammar::matchFirst,&self,_1)]
    00514               >> ( ch_p('=') | ch_p(':'))
    00515               >> grValue[boost::bind(&MapGrammar::matchSecond,&self,_1)] ;
    00516         }
    00517         KeyGrammarT grKey;
    00518         ValueGrammarT grValue;
    00519         rule<ScannerT> const& start() const { return vec; }
    00520         rule<ScannerT> vec,inner, inner_list ;
    00521       };
    00522     };
    00523     // ========================================================================
    00524   } // end of namespace Gaudi::Parsers
    00525 } // end of namespace Gaudi
    00526 // ============================================================================
    00527 // The END
    00528 // ============================================================================
    00529 #endif // GAUDIKERNEL_GRAMMARS_H
    00530 // ============================================================================

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines