/search.css" rel="stylesheet" type="text/css"/> /search.js">
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/spirit.hpp" 00015 #include "boost/spirit/phoenix.hpp" 00016 // ============================================================================ 00027 // ============================================================================ 00028 namespace Gaudi 00029 { 00030 namespace Parsers 00031 { 00032 // ======================================================================== 00033 using namespace boost::spirit ; 00034 // ======================================================================== 00035 using namespace phoenix ; 00036 // ======================================================================== 00045 template <typename T> 00046 struct ClosureGrammar : public boost::spirit::closure < ClosureGrammar<T>,T > 00047 { 00048 typedef boost::spirit::closure<ClosureGrammar, T> closure; 00049 typename closure::member1 val; 00050 }; 00051 // ======================================================================== 00062 template <typename T1,typename T2> 00063 struct AttributesClosureGrammar 00064 : public boost::spirit::closure<AttributesClosureGrammar<T1,T2>,T1,T2> 00065 { 00066 typedef boost::spirit::closure<AttributesClosureGrammar, T1,T2> closure; 00067 typename closure::member1 val; 00068 typename closure::member2 attrs; 00069 }; 00070 // ======================================================================== 00082 class BoolGrammar : public grammar 00083 < 00084 BoolGrammar, 00085 ClosureGrammar<bool>::context_t 00086 > 00087 { 00088 public: 00089 typedef bool ResultT; 00090 public: 00091 template <typename ScannerT> 00092 struct definition 00093 { 00094 definition( BoolGrammar const &self) 00095 { 00096 boolean_literal 00097 = true_literal[self.val = true] | false_literal[self.val = false]; 00098 true_literal 00099 = str_p("true" ) | str_p("True" ) | str_p("TRUE" ) | str_p("1"); 00100 false_literal 00101 = str_p("false") | str_p("False") | str_p("FALSE") | str_p("0"); 00102 } 00103 rule<ScannerT> const& start() const 00104 { return boolean_literal;} 00105 rule<ScannerT> boolean_literal,true_literal,false_literal; 00106 }; 00107 }; 00108 // ======================================================================== 00119 template<typename RT=char> 00120 class CharGrammar : public grammar 00121 < 00122 CharGrammar<RT> , typename ClosureGrammar<RT>::context_t 00123 > 00124 { 00125 public: 00126 typedef RT ResultT; 00127 public: 00128 template <typename ScannerT> 00129 struct definition 00130 { 00131 definition( CharGrammar<RT> const &self) 00132 { 00133 char_literal 00134 = int_parser<RT>()[self.val=arg1] 00135 | ('\'' 00136 >> ( str_p("\\'")[self.val='\''] 00137 | (anychar_p[self.val=arg1]-'\'') )>>'\''); 00138 } 00139 rule<ScannerT> const& start() const 00140 { return char_literal; } 00141 rule<ScannerT> char_literal; 00142 }; 00143 }; 00144 // ======================================================================== 00156 template<typename RT=int> 00157 class IntGrammar : public grammar 00158 < 00159 IntGrammar<RT>, 00160 typename ClosureGrammar<RT>::context_t 00161 > 00162 { 00163 public: 00164 typedef RT ResultT; 00165 public: 00166 template <typename ScannerT> 00167 struct definition 00168 { 00169 definition( IntGrammar<RT> const &self) 00170 { 00171 int_literal = lexeme_d[int_parser<RT>()[self.val=arg1] 00172 >> !(ch_p('u') | ch_p('U') | ch_p('l') | ch_p('L'))]; 00173 } 00174 rule<ScannerT> const& start() const { return int_literal; } 00175 rule<ScannerT> int_literal; 00176 }; 00177 }; 00178 // ======================================================================== 00190 template<typename RT=double> 00191 class RealGrammar : public grammar 00192 < 00193 RealGrammar<RT>,typename ClosureGrammar<RT>::context_t 00194 > 00195 { 00196 public: 00197 typedef RT ResultT; 00198 public: 00199 template <typename ScannerT> 00200 struct definition 00201 { 00202 definition( RealGrammar const &self) 00203 { 00204 real_literal 00205 = lexeme_d[real_parser<RT, 00206 real_parser_policies<RT> >()[self.val = arg1] 00207 >> !(ch_p('f') | ch_p('F') | ch_p('l') | ch_p('L'))]; 00208 } 00209 rule<ScannerT> const& start() const 00210 { return real_literal; } 00211 rule<ScannerT> real_literal; 00212 }; 00213 }; 00214 // ======================================================================== 00229 class StringGrammar : public grammar 00230 < 00231 StringGrammar, ClosureGrammar<std::string>::context_t 00232 > 00233 { 00234 public: 00235 typedef std::string ResultT; 00244 void matchString() const 00245 { 00246 for ( std::string::iterator cur=this->val().begin(); 00247 cur!=this->val().end();cur++) 00248 { if(std::isspace(*cur) ) { *cur = ' '; } } 00249 } 00250 public: 00251 template <typename ScannerT> 00252 struct definition 00253 { 00254 definition( StringGrammar const &self ) 00255 { 00256 string_literal = (lexeme_d 00257 [ 00258 ('"' >> (*( str_p("\\\"") 00259 | 00260 (anychar_p-'"') )) 00261 [self.val = construct_<std::string> 00262 (arg1,arg2)] >> 00263 '"') 00264 | 00265 ('\'' >> (*( str_p("\\'") 00266 | 00267 (anychar_p-'\'') )) 00268 [self.val = construct_<std::string> 00269 (arg1,arg2)]>> 00270 '\'')])[boost::bind(&StringGrammar::matchString,&self)]; 00271 } 00272 rule<ScannerT> const& start() const { return string_literal; } 00273 rule<ScannerT> string_literal; 00274 }; 00275 }; 00276 // ======================================================================== 00289 class SkipperGrammar : public grammar<SkipperGrammar> 00290 { 00291 public: 00295 SkipperGrammar ( const bool skipnewline = true ) 00296 : m_skipnewline(skipnewline){} 00297 public: 00299 bool skipnewline() const{return m_skipnewline;} 00300 public: 00301 template <typename ScannerT> 00302 struct definition 00303 { 00304 definition( SkipperGrammar const& self) 00305 { 00306 if ( self.skipnewline() ) 00307 { 00308 skip 00309 = space_p 00310 | comment_p("//") // C++ comment 00311 | comment_p("/*", "*/") // C comment 00312 ; 00313 } 00314 else 00315 { 00316 skip 00317 = (space_p-eol_p) 00318 | comment_p("//") // C++ comment 00319 | comment_p("/*", "*/") // C comment 00320 ; 00321 } 00322 } 00323 rule<ScannerT> skip; 00324 rule<ScannerT> const& start() const { return skip; } 00325 }; 00326 private: 00327 bool m_skipnewline; 00328 }; 00329 // ======================================================================== 00340 template <typename KeyGrammarT, typename ValueGrammarT> 00341 class PairGrammar : public grammar 00342 < 00343 PairGrammar<KeyGrammarT,ValueGrammarT>, 00344 typename ClosureGrammar< 00345 std::pair<typename KeyGrammarT::ResultT, 00346 typename ValueGrammarT::ResultT> >::context_t 00347 > 00348 { 00349 public: 00350 typedef typename KeyGrammarT::ResultT KeyT; 00351 typedef typename ValueGrammarT::ResultT ValueT; 00352 typedef std::pair<KeyT,ValueT> ResultT; 00353 public: 00357 PairGrammar ( const std::string& delim = "," ) 00358 : m_delim(delim) {} 00359 public: 00361 void matchFirst ( const KeyT& first ) const { this->val().first = first; } 00363 void matchSecond ( const ValueT& second ) const { this->val().second = second; } 00364 public: 00365 template <typename ScannerT> 00366 struct definition 00367 { 00368 definition( PairGrammar const &self) 00369 { 00370 para 00371 = ( 00372 str_p("(") 00373 >> (grkey[boost::bind(&PairGrammar::matchFirst,&self,_1)]) 00374 >> self.delim().c_str() 00375 >> (grvalue[boost::bind(&PairGrammar::matchSecond,&self,_1)]) 00376 >> str_p(")") 00377 ) ; 00378 } 00379 rule<ScannerT> const& start() const { return para; } 00380 rule<ScannerT> para; 00381 KeyGrammarT grkey; 00382 ValueGrammarT grvalue; 00383 }; 00384 public: 00386 const std::string& delim() const { return m_delim ; } 00390 void setDelim ( const std::string& delim ) { m_delim = delim;} 00391 private: 00392 std::string m_delim; 00393 }; 00394 // ======================================================================== 00406 template <typename GrammarT> 00407 class VectorGrammar : public grammar 00408 < 00409 VectorGrammar<GrammarT> , 00410 typename ClosureGrammar<std::vector<typename GrammarT::ResultT> >::context_t 00411 > 00412 { 00413 public: 00414 typedef typename GrammarT::ResultT ValueT; 00415 typedef std::vector<ValueT> ResultT; 00416 typedef VectorGrammar<GrammarT> SelfT; 00417 public: 00419 void matchItem(const ValueT& value) const { this->val().push_back(value); } 00420 public: 00421 template <typename ScannerT> 00422 struct definition 00423 { 00424 definition(SelfT const &self) 00425 { 00426 inner = 00427 !(gr[boost::bind(&VectorGrammar::matchItem,&self,_1)] 00428 >> *(','>>gr[boost::bind(&VectorGrammar::matchItem,&self,_1)])); 00429 vec = 00430 "{">>inner>>"}" | "[">>inner>>"]"; 00431 } 00432 rule<ScannerT> const& start() const { return vec; } 00433 rule<ScannerT> vec,inner; 00434 GrammarT gr; 00435 }; 00436 }; 00437 // ======================================================================== 00452 template <typename KeyGrammarT, typename ValueGrammarT> 00453 class MapGrammar : public grammar 00454 < 00455 MapGrammar<KeyGrammarT,ValueGrammarT>, 00456 typename AttributesClosureGrammar 00457 < std::map<typename KeyGrammarT::ResultT, 00458 typename ValueGrammarT::ResultT>, 00459 std::pair<typename KeyGrammarT::ResultT, 00460 typename ValueGrammarT::ResultT> >::context_t 00461 > 00462 { 00463 public: 00464 typedef typename KeyGrammarT::ResultT KeyT; 00465 typedef typename ValueGrammarT::ResultT ValueT; 00466 typedef std::map<KeyT,ValueT> ResultT; 00467 public: 00469 void matchItem () const 00470 { 00471 //this->val().insert(this->attrs()); 00472 this->val()[this->attrs().first] = this->attrs().second ; 00473 } 00475 void matchFirst ( const KeyT& value ) const { this->attrs().first = value ; } 00477 void matchSecond( const ValueT& value ) const { this->attrs().second = value ; } 00478 public: 00479 template <typename ScannerT> 00480 struct definition 00481 { 00482 definition( MapGrammar const &self) 00483 { 00484 vec 00485 = ('{'>> inner_list >> '}') | ('['>>inner_list>>']'); 00486 inner_list 00487 = 00488 !( inner[boost::bind(&MapGrammar::matchItem,&self)] 00489 >> *( ch_p(',') >> 00490 inner[boost::bind(&MapGrammar::matchItem,&self)] ) 00491 ); 00492 inner 00493 = 00494 grKey[boost ::bind(&MapGrammar::matchFirst,&self,_1)] 00495 >> ( ch_p('=') | ch_p(':')) 00496 >> grValue[boost::bind(&MapGrammar::matchSecond,&self,_1)] ; 00497 } 00498 KeyGrammarT grKey; 00499 ValueGrammarT grValue; 00500 rule<ScannerT> const& start() const { return vec; } 00501 rule<ScannerT> vec,inner, inner_list ; 00502 }; 00503 }; 00504 // ======================================================================== 00505 } // end of namespace Gaudi::Parsers 00506 } // end of namespace Gaudi 00507 // ============================================================================ 00508 // The END 00509 // ============================================================================ 00510 #endif // GAUDIKERNEL_GRAMMARS_H 00511 // ============================================================================