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
00012
00013
00014
00015 #include <cctype>
00016
00017
00018
00019 #include <boost/version.hpp>
00020 #if BOOST_VERSION >= 103800
00021
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("//")
00328 | comment_p("/*", "*/")
00329 ;
00330 }
00331 else
00332 {
00333 skip
00334 = (space_p-eol_p)
00335 | comment_p("//")
00336 | comment_p("/*", "*/")
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 >> ']' |
00448 '(' >> inner >> ')' |
00449 '{' >> inner >> '}' ;
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
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 }
00525 }
00526
00527
00528
00529 #endif // GAUDIKERNEL_GRAMMARS_H
00530