| # Gaudi Framework, version v21r6 |

Home |  | Generated: 11 Nov 2009

# Grammars.h

Go to the documentation of this file.

    00001 // $Id: Grammars.h,v 1.10 2008/10/27 16:41:33 marcocle Exp $
    00002 // ============================================================================
    00003 #ifndef GAUDIKERNEL_GRAMMARS_H
    00004 #define GAUDIKERNEL_GRAMMARS_H 1
    00005 // ============================================================================
    00006 // Include files
    00007 // ============================================================================
    00008 // STD & STL
    00009 // ============================================================================
    00010 #include <cctype>
    00011 // ============================================================================
    00012 // Boost.Spirit
    00013 // ============================================================================
    00014 #include <boost/version.hpp>
    00015 #if BOOST_VERSION >= 103800
    00016 // FIXME: Move to the new boost::spirit::classic namespace
    00017 #if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
    00018 #define BOOST_SPIRIT_USE_OLD_NAMESPACE
    00019 #endif
    00020 #include <boost/spirit/include/classic.hpp>
    00021 #include <boost/spirit/include/phoenix1.hpp>
    00022 #else
    00023 #include <boost/spirit.hpp>
    00024 #include <boost/spirit/phoenix.hpp>
    00025 #endif
    00026 #include <boost/bind.hpp>
    00027
    00028 // ============================================================================
    00039 // ============================================================================
    00040 namespace Gaudi
    00041 {
    00042   namespace Parsers
    00043   {
    00044     // ========================================================================
    00045     using namespace boost::spirit ;
    00046     // ========================================================================
    00047     using namespace phoenix ;
    00048     // ========================================================================
    00057    template <typename T>
    00058     struct ClosureGrammar : public boost::spirit::closure < ClosureGrammar<T>,T >
    00059     {
    00060       typedef  boost::spirit::closure<ClosureGrammar, T> closure;
    00061       typename closure::member1 val;
    00062     };
    00063     // ========================================================================
    00074     template <typename T1,typename T2>
    00075     struct AttributesClosureGrammar
    00076       : public boost::spirit::closure<AttributesClosureGrammar<T1,T2>,T1,T2>
    00077     {
    00078       typedef boost::spirit::closure<AttributesClosureGrammar, T1,T2> closure;
    00079       typename closure::member1 val;
    00080       typename closure::member2 attrs;
    00081     };
    00082     // ========================================================================
    00094     class BoolGrammar : public grammar
    00095     <
    00096       BoolGrammar,
    00097       ClosureGrammar<bool>::context_t
    00098     >
    00099     {
    00100     public:
    00101       typedef bool ResultT;
    00102     public:
    00103       template <typename ScannerT>
    00104       struct definition
    00105       {
    00106         definition( BoolGrammar const &self)
    00107         {
    00108           boolean_literal
    00109             = true_literal[self.val = true] | false_literal[self.val = false];
    00110           true_literal
    00111             = str_p("true" ) | str_p("True" ) | str_p("TRUE" ) | str_p("1");
    00112           false_literal
    00113             = str_p("false") | str_p("False") | str_p("FALSE") | str_p("0");
    00114         }
    00115         rule<ScannerT> const& start() const
    00116         { return boolean_literal;}
    00117         rule<ScannerT> boolean_literal,true_literal,false_literal;
    00118       };
    00119     };
    00120     // ========================================================================
    00131     template<typename RT=char>
    00132     class CharGrammar : public grammar
    00133     <
    00134       CharGrammar<RT> , typename ClosureGrammar<RT>::context_t
    00135     >
    00136     {
    00137     public:
    00138       typedef RT ResultT;
    00139     public:
    00140       template <typename ScannerT>
    00141       struct definition
    00142       {
    00143         definition( CharGrammar<RT> const &self)
    00144         {
    00145           char_literal
    00146             = int_parser<RT>()[self.val=arg1]
    00147             | ('\''
    00148                >> ( str_p("\\'")[self.val='\'']
    00149                     | (anychar_p[self.val=arg1]-'\'') )>>'\'');
    00150         }
    00151         rule<ScannerT> const& start() const
    00152         { return char_literal; }
    00153         rule<ScannerT> char_literal;
    00154       };
    00155     };
    00156     // ========================================================================
    00168     template<typename RT=int>
    00169     class IntGrammar : public grammar
    00170     <
    00171       IntGrammar<RT>,
    00172       typename ClosureGrammar<RT>::context_t
    00173     >
    00174     {
    00175     public:
    00176       typedef RT ResultT;
    00177     public:
    00178       template <typename ScannerT>
    00179       struct definition
    00180       {
    00181         definition( IntGrammar<RT> const &self)
    00182         {
    00183           int_literal = lexeme_d[int_parser<RT>()[self.val=arg1]
    00184             >> !(ch_p('u') | ch_p('U') | ch_p('l') | ch_p('L'))];
    00185         }
    00186         rule<ScannerT> const& start() const { return int_literal; }
    00187         rule<ScannerT> int_literal;
    00188       };
    00189     };
    00190     // ========================================================================
    00202     template<typename RT=double>
    00203     class RealGrammar : public grammar
    00204     <
    00205       RealGrammar<RT>,typename ClosureGrammar<RT>::context_t
    00206     >
    00207     {
    00208     public:
    00209       typedef RT ResultT;
    00210     public:
    00211       template <typename ScannerT>
    00212       struct definition
    00213       {
    00214         definition( RealGrammar const &self)
    00215         {
    00216           real_literal
    00217             = lexeme_d[real_parser<RT,
    00218             real_parser_policies<RT> >()[self.val = arg1]
    00219             >> !(ch_p('f') | ch_p('F') | ch_p('l') | ch_p('L'))];
    00220         }
    00221         rule<ScannerT> const& start() const
    00222         { return real_literal; }
    00223         rule<ScannerT> real_literal;
    00224       };
    00225     };
    00226     // ========================================================================
    00241     class StringGrammar : public grammar
    00242     <
    00243       StringGrammar, ClosureGrammar<std::string>::context_t
    00244     >
    00245     {
    00246     public:
    00247       typedef std::string ResultT;
    00256       void matchString() const
    00257       {
    00258         for ( std::string::iterator cur=this->val().begin();
    00259               cur!=this->val().end();cur++)
    00260         { if(std::isspace(*cur) ) { *cur = ' '; } }
    00261       }
    00262     public:
    00263         template <typename ScannerT>
    00264         struct definition
    00265         {
    00266           definition( StringGrammar const &self )
    00267           {
    00268             string_literal = (lexeme_d
    00269               [
    00270                ('"' >> (*( str_p("\\\"")
    00271                            |
    00272                            (anychar_p-'"') ))
    00273                 [self.val = construct_<std::string>
    00274                  (arg1,arg2)] >>
    00275                 '"')
    00276                |
    00277                ('\'' >> (*( str_p("\\'")
    00278                             |
    00279                             (anychar_p-'\'') ))
    00280                 [self.val = construct_<std::string>
    00281                  (arg1,arg2)]>>
    00282                 '\'')])[boost::bind(&StringGrammar::matchString,&self)];
    00283           }
    00284           rule<ScannerT> const& start() const { return string_literal; }
    00285           rule<ScannerT> string_literal;
    00286         };
    00287       };
    00288     // ========================================================================
    00301     class SkipperGrammar : public grammar<SkipperGrammar>
    00302     {
    00303     public:
    00307       SkipperGrammar ( const bool skipnewline = true )
    00308         : m_skipnewline(skipnewline){}
    00309     public:
    00311       bool skipnewline() const{return m_skipnewline;}
    00312     public:
    00313       template <typename ScannerT>
    00314       struct definition
    00315       {
    00316         definition( SkipperGrammar const& self)
    00317         {
    00318           if ( self.skipnewline() )
    00319           {
    00320             skip
    00321               =   space_p
    00322               |   comment_p("//")     // C++ comment
    00323               |   comment_p("/*", "*/")     // C comment
    00324               ;
    00325           }
    00326           else
    00327           {
    00328             skip
    00329               =   (space_p-eol_p)
    00330               |   comment_p("//")     // C++ comment
    00331               |   comment_p("/*", "*/")     // C comment
    00332               ;
    00333           }
    00334         }
    00335         rule<ScannerT>  skip;
    00336         rule<ScannerT> const& start() const { return skip; }
    00337       };
    00338     private:
    00339       bool m_skipnewline;
    00340     };
    00341     // ========================================================================
    00352     template <typename KeyGrammarT, typename ValueGrammarT>
    00353     class PairGrammar : public grammar
    00354     <
    00355       PairGrammar<KeyGrammarT,ValueGrammarT>,
    00356       typename ClosureGrammar<
    00357       std::pair<typename KeyGrammarT::ResultT,
    00358                 typename ValueGrammarT::ResultT> >::context_t
    00359     >
    00360     {
    00361     public:
    00362       typedef typename KeyGrammarT::ResultT KeyT;
    00363       typedef typename ValueGrammarT::ResultT ValueT;
    00364       typedef std::pair<KeyT,ValueT> ResultT;
    00365     public:
    00369       PairGrammar ( const std::string&  delim = "," )
    00370         : m_delim(delim) {}
    00371     public:
    00373       void matchFirst  ( const KeyT&   first  ) const { this->val().first = first; }
    00375       void matchSecond ( const ValueT& second ) const { this->val().second = second; }
    00376     public:
    00377       template <typename ScannerT>
    00378       struct definition
    00379       {
    00380         definition( PairGrammar const &self)
    00381         {
    00382           para
    00383             = (
    00384                str_p("(")
    00385                >> (grkey[boost::bind(&PairGrammar::matchFirst,&self,_1)])
    00386                >> self.delim().c_str()
    00387                >> (grvalue[boost::bind(&PairGrammar::matchSecond,&self,_1)])
    00388                >> str_p(")")
    00389                ) ;
    00390         }
    00391         rule<ScannerT> const& start() const { return para; }
    00392         rule<ScannerT> para;
    00393         KeyGrammarT grkey;
    00394         ValueGrammarT grvalue;
    00395       };
    00396     public:
    00398       const std::string& delim() const { return m_delim ; }
    00402       void setDelim ( const std::string& delim ) { m_delim = delim;}
    00403     private:
    00404       std::string m_delim;
    00405     };
    00406     // ========================================================================
    00418     template <typename GrammarT>
    00419     class VectorGrammar : public grammar
    00420     <
    00421       VectorGrammar<GrammarT> ,
    00422       typename ClosureGrammar<std::vector<typename GrammarT::ResultT> >::context_t
    00423     >
    00424     {
    00425     public:
    00426       typedef typename GrammarT::ResultT ValueT;
    00427       typedef std::vector<ValueT> ResultT;
    00428       typedef VectorGrammar<GrammarT> SelfT;
    00429     public:
    00431       void matchItem(const ValueT& value) const { this->val().push_back(value); }
    00432     public:
    00433       template <typename ScannerT>
    00434       struct definition
    00435       {
    00436         definition(SelfT const &self)
    00437         {
    00438           inner =
    00439             !(gr[boost::bind(&VectorGrammar::matchItem,&self,_1)]
    00440               >> *(','>>gr[boost::bind(&VectorGrammar::matchItem,&self,_1)]));
    00441           vec =
    00442             '[' >> inner >> ']' |  // a'la python list
    00443             '(' >> inner >> ')' |  // a'la python tuple
    00444             '{' >> inner >> '}' ;  // like obsolete list from opts-grammar
    00445         }
    00446         rule<ScannerT> const& start() const { return vec; }
    00447         rule<ScannerT> vec,inner;
    00448         GrammarT gr;
    00449       };
    00450     };
    00451     // ========================================================================
    00466     template <typename KeyGrammarT, typename ValueGrammarT>
    00467     class MapGrammar : public grammar
    00468     <
    00469       MapGrammar<KeyGrammarT,ValueGrammarT>,
    00470       typename AttributesClosureGrammar
    00471       < std::map<typename KeyGrammarT::ResultT,
    00472                  typename ValueGrammarT::ResultT>,
    00473         std::pair<typename KeyGrammarT::ResultT,
    00474                   typename ValueGrammarT::ResultT> >::context_t
    00475     >
    00476     {
    00477     public:
    00478       typedef typename KeyGrammarT::ResultT KeyT;
    00479       typedef typename ValueGrammarT::ResultT ValueT;
    00480       typedef std::map<KeyT,ValueT> ResultT;
    00481     public:
    00483       void matchItem  () const
    00484       {
    00485         //this->val().insert(this->attrs());
    00486         this->val()[this->attrs().first] = this->attrs().second ;
    00487       }
    00489       void matchFirst ( const KeyT&   value ) const {  this->attrs().first = value ; }
    00491       void matchSecond( const ValueT& value ) const { this->attrs().second = value ; }
    00492     public:
    00493       template <typename ScannerT>
    00494       struct definition
    00495       {
    00496         definition( MapGrammar const &self)
    00497         {
    00498           vec
    00499             = ('{'>> inner_list >> '}') | ('['>>inner_list>>']');
    00500           inner_list
    00501             =
    00502             !( inner[boost::bind(&MapGrammar::matchItem,&self)]
    00503                >> *( ch_p(',') >>
    00504                      inner[boost::bind(&MapGrammar::matchItem,&self)] )
    00505                );
    00506           inner
    00507             =
    00508             grKey[boost ::bind(&MapGrammar::matchFirst,&self,_1)]
    00509               >> ( ch_p('=') | ch_p(':'))
    00510               >> grValue[boost::bind(&MapGrammar::matchSecond,&self,_1)] ;
    00511         }
    00512         KeyGrammarT grKey;
    00513         ValueGrammarT grValue;
    00514         rule<ScannerT> const& start() const { return vec; }
    00515         rule<ScannerT> vec,inner, inner_list ;
    00516       };
    00517     };
    00518     // ========================================================================
    00519   } // end of namespace Gaudi::Parsers
    00520 } // end of namespace Gaudi
    00521 // ============================================================================
    00522 // The END
    00523 // ============================================================================
    00524 #endif // GAUDIKERNEL_GRAMMARS_H
    00525 // ============================================================================