00001
00002 #ifndef GAUDIKERNEL_GRAMMARSV2_H
00003 #define GAUDIKERNEL_GRAMMARSV2_H 1
00004 #ifdef __GNUC__
00005 #pragma GCC system_header
00006 #endif
00007
00008
00009
00010
00011
00012 #include <string>
00013 #include <vector>
00014 #include <list>
00015 #include <set>
00016 #include <map>
00017
00018
00019
00020 #include <boost/spirit/include/qi.hpp>
00021 #include <boost/fusion/include/unused.hpp>
00022 #include <boost/fusion/include/std_pair.hpp>
00023
00024 #include <boost/spirit/include/phoenix_core.hpp>
00025 #include <boost/spirit/include/phoenix_operator.hpp>
00026
00027 #include <boost/utility/enable_if.hpp>
00028 #include <boost/type_traits.hpp>
00029
00030 #include <boost/spirit/repository/include/qi_confix.hpp>
00031
00032
00033
00034 #include "GaudiKernel/VectorMap.h"
00035 #include "GaudiKernel/HashMap.h"
00036 #include "GaudiKernel/StringKey.h"
00037 #include "GaudiKernel/Point3DTypes.h"
00038 #include "GaudiKernel/Point4DTypes.h"
00039 #include "GaudiKernel/HistoDef.h"
00040
00041 namespace Gaudi { namespace Parsers {
00042
00043
00044
00045 namespace sp = boost::spirit;
00046 namespace ph = boost::phoenix;
00047 namespace qi = sp::qi;
00048 namespace enc = sp::ascii;
00049 namespace rep = sp::repository;
00050
00051
00052
00053 typedef std::string::const_iterator DefaultIterator;
00054 typedef enc::space_type DefaultSkipper;
00055
00056 template <typename Iterator, typename T, typename Skipper,
00057 class Enable = void>
00058 struct Grammar_ {
00059
00060
00061
00062
00063
00064
00065 BOOST_MPL_ASSERT_MSG(false, GRAMMAR_FOR_TYPE_DOES_NOT_EXISTS, (T));
00066 };
00067
00068 #define REGISTER_GRAMMAR(ResultType, GrammarName) \
00069 template <typename Iterator, typename Skipper>\
00070 struct Grammar_<Iterator, ResultType, Skipper> \
00071 { \
00072 typedef GrammarName<Iterator, Skipper> Grammar;\
00073 }
00074
00075 template< typename Iterator>
00076 struct SkipperGrammar : qi::grammar<Iterator>
00077 {
00078 SkipperGrammar() : SkipperGrammar::base_type(comments) {
00079 comments = enc::space | rep::confix("/*", "*/")[*(qi::char_ - "*/")]
00080 |
00081 rep::confix("//", sp::eol)[*(qi::char_ - sp::eol)];
00082 }
00083 qi::rule<Iterator> comments;
00084 };
00085
00086 template< typename Iterator, typename Skipper>
00087 struct StringGrammar : qi::grammar<Iterator, std::string(), qi::locals<char>,
00088 Skipper>
00089 {
00090
00091 typedef std::string ResultT;
00092
00093 StringGrammar() : StringGrammar::base_type( str ) {
00094 begin_quote = enc::char_("\"'");
00095 quote = enc::char_(qi::_r1);
00096
00097 str = qi::lexeme[begin_quote[qi::_a = qi::_1]
00098 > *( (enc::char_('\\') >> quote(qi::_a))[qi::_val += qi::_a]
00099 | (enc::char_[qi::_val += qi::_1] - quote(qi::_a))) >
00100 quote(qi::_a)]
00101 ;
00102 }
00103
00104 qi::rule<Iterator, std::string(), qi::locals<char>, Skipper> str;
00105 qi::rule<Iterator, char()> begin_quote;
00106 qi::rule<Iterator, void(char)> quote;
00107
00108 };
00109 REGISTER_GRAMMAR(std::string, StringGrammar);
00110 REGISTER_GRAMMAR(Gaudi::StringKey, StringGrammar);
00111
00112 template< typename Iterator, typename Skipper>
00113 struct CharGrammar : qi::grammar<Iterator, char(), Skipper>
00114 {
00115 typedef char ResultT;
00116 CharGrammar() : CharGrammar::base_type( ch ) {
00117 ch = qi::int_parser<char>()
00118 |
00119 '\'' >> (qi::char_-'\'') >> '\'';
00120 }
00121 qi::rule<Iterator, char(), Skipper> ch;
00122 };
00123 REGISTER_GRAMMAR(char, CharGrammar);
00124
00125 template< typename Iterator, typename Skipper>
00126 struct BoolGrammar : qi::grammar<Iterator, bool(), Skipper>
00127 {
00128 typedef bool ResultT;
00129 BoolGrammar() : BoolGrammar::base_type( boolean_literal ) {
00130 boolean_literal =
00131 (qi::lit("true") | "True" | "TRUE" | "1")[qi::_val=true]
00132 |
00133 (qi::lit("false") | "False" | "FALSE" | "0")[qi::_val=false];
00134 }
00135 qi::rule<Iterator, bool(), Skipper> boolean_literal;
00136 };
00137 REGISTER_GRAMMAR(bool, BoolGrammar);
00138
00139 template< typename Iterator, typename RT , typename Skipper>
00140 struct IntGrammar : qi::grammar<Iterator, RT(), Skipper>
00141 {
00142 typedef RT ResultT;
00143 IntGrammar() : IntGrammar::base_type( integer ) {
00144 integer = qi::int_parser<RT>();
00145 }
00146 qi::rule<Iterator, RT(), Skipper> integer;
00147 };
00148
00149
00150
00151 template <typename Iterator, typename T, typename Skipper>
00152 struct Grammar_<Iterator, T, Skipper,
00153 typename boost::enable_if<boost::is_integral<T> >::type>
00154 {
00155 typedef IntGrammar<Iterator, T, Skipper> Grammar;
00156 };
00157
00158 template< typename Iterator, typename RT, typename Skipper>
00159 struct RealGrammar : qi::grammar<Iterator, RT(), Skipper>
00160 {
00161 typedef RT ResultT;
00162 RealGrammar() : RealGrammar::base_type(real) {
00163 real = qi::real_parser<RT>();
00164 }
00165 qi::rule<Iterator, RT(), Skipper> real;
00166 };
00167
00168
00169
00170 template <typename Iterator, typename T, typename Skipper >
00171 struct Grammar_<Iterator, T, Skipper,
00172 typename boost::enable_if<boost::is_floating_point<T> >::type >
00173 {
00174 typedef RealGrammar<Iterator, T, Skipper> Grammar;
00175 };
00176
00177 template< typename Iterator, typename VectorT, typename Skipper>
00178 struct VectorGrammar : qi::grammar<Iterator,
00179 VectorT(), qi::locals<char>,Skipper>
00180 {
00181
00182 typedef VectorT ResultT;
00183
00184 VectorGrammar() : VectorGrammar::base_type(vec) {
00185 begin = enc::char_('[')[qi::_val=']'] | enc::char_('{')[qi::_val='}']
00186 | enc::char_('(')[qi::_val=')'];
00187 end = enc::char_(qi::_r1);
00188 list = elementGrammar % ',';
00189 vec = begin[qi::_a = qi::_1] >> -list[qi::_val=qi::_1] >> end(qi::_a);
00190 }
00191
00192 typename
00193 Grammar_<Iterator, typename VectorT::value_type, Skipper>::Grammar
00194 elementGrammar;
00195 qi::rule<Iterator, char()> begin;
00196 qi::rule<Iterator, void(char)> end;
00197
00198 qi::rule<Iterator, ResultT(), qi::locals<char>,Skipper> vec;
00199 qi::rule<Iterator, ResultT(), Skipper> list;
00200
00201 };
00202
00203
00204
00205 template <typename Iterator, typename InnerT, typename AllocatorT,
00206 typename Skipper>
00207 struct Grammar_<Iterator, std::vector<InnerT, AllocatorT>, Skipper >
00208 {
00209 typedef
00210 VectorGrammar<Iterator, std::vector<InnerT, AllocatorT>,Skipper>
00211 Grammar;
00212 };
00213
00214
00215
00216 template <typename Iterator, typename InnerT, typename AllocatorT,
00217 typename Skipper>
00218 struct Grammar_<Iterator, std::list<InnerT, AllocatorT>, Skipper >
00219 {
00220 typedef
00221 VectorGrammar<Iterator, std::list<InnerT, AllocatorT>,Skipper>
00222 Grammar;
00223 };
00224
00225
00226
00227 template <typename Iterator, typename InnerT, typename CompareT,
00228 typename AllocatorT, typename Skipper>
00229 struct Grammar_<Iterator, std::set<InnerT, CompareT, AllocatorT>, Skipper >
00230 {
00231 typedef
00232 VectorGrammar<Iterator, std::set<InnerT, CompareT, AllocatorT>,Skipper>
00233 Grammar;
00234 };
00235
00236
00237 template< typename Iterator, typename PairT, typename Skipper>
00238 struct PairGrammar :
00239 qi::grammar<Iterator,PairT(), qi::locals<char>, Skipper> {
00240
00241 typedef PairT ResultT;
00242 typedef typename PairT::first_type first_type;
00243 typedef typename PairT::second_type second_type;
00244
00245 PairGrammar() : PairGrammar::base_type(pair) {
00246 init(",");
00247 }
00248
00249 PairGrammar(const std::string& delimeter) : PairGrammar::base_type(pair) {
00250 init(delimeter);
00251 }
00252
00253 struct first {};
00254 struct second {};
00255 void init(const std::string& delimeter) {
00256 begin = enc::char_('(')[qi::_val=')']
00257 |
00258 enc::char_('[')[qi::_val=']'];
00259 end = qi::char_(qi::_r1);
00260 pair = begin[qi::_a = qi::_1] >> pair_in[qi::_val = qi::_1] >> end(qi::_a);
00261 pair_in = key >> qi::lit(delimeter) >> value;
00262 }
00263
00264 typename
00265 Grammar_<Iterator, typename PairT::first_type, Skipper>::Grammar key;
00266 typename
00267 Grammar_<Iterator, typename PairT::second_type, Skipper>::Grammar
00268 value;
00269 qi::rule<Iterator, char()> begin;
00270 qi::rule<Iterator, void(char)> end;
00271 qi::rule<Iterator, ResultT(), qi::locals<char>, Skipper> pair;
00272 qi::rule<Iterator, ResultT(), Skipper> pair_in;
00273
00274
00275 };
00276
00277
00278
00279 template <typename Iterator, typename KeyT, typename ValueT,
00280 typename Skipper>
00281 struct Grammar_<Iterator, std::pair<KeyT, ValueT>, Skipper >
00282 {
00283 typedef PairGrammar<Iterator, std::pair<KeyT, ValueT>, Skipper> Grammar;
00284 };
00285
00286 template< typename Iterator, typename MapT, typename Skipper>
00287 struct MapGrammar : qi::grammar<Iterator,MapT(), Skipper>
00288 {
00289
00290 typedef MapT ResultT;
00291 typedef typename MapT::key_type KeyT;
00292 typedef typename MapT::mapped_type MappedT;
00293 typedef std::pair<KeyT, MappedT> PairT;
00294
00295 typedef std::vector<PairT> VectorPairT;
00296
00297 struct tag_key{};
00298 struct tag_mapped{};
00299 struct Operations
00300 {
00301 template <typename A, typename B = boost::fusion::unused_type,
00302 typename C = boost::fusion::unused_type,
00303 typename D = boost::fusion::unused_type>
00304 struct result { typedef void type; };
00305
00306 void operator()(ResultT& res, const VectorPairT& vec) const{
00307 for(typename VectorPairT::const_iterator cur = vec.begin();
00308 cur != vec.end(); cur++){
00309 res.insert(*cur);
00310 }
00311 }
00312 void operator()(PairT& res, const KeyT& key, tag_key) const{
00313 res.first = key;
00314 }
00315 void operator()(PairT& res, const MappedT& value, tag_mapped) const{
00316 res.second = value;
00317 }
00318
00319 };
00320
00321 MapGrammar() : MapGrammar::base_type(map) {
00322 pair = key[op(qi::_val,qi::_1, tag_key())] > (qi::lit(':') | '=') >
00323 value[op(qi::_val,qi::_1, tag_mapped())];
00324 list = -(pair % enc::char_(','));
00325 map = (('[' >> list >> ']')
00326 | ('{' >> list >> '}'))[op(qi::_val,qi::_1)];
00327 }
00328
00329 typename
00330 Grammar_<Iterator, typename MapT::key_type, Skipper>::Grammar key;
00331 typename
00332 Grammar_<Iterator, typename MapT::mapped_type, Skipper>::Grammar value;
00333 qi::rule<Iterator, PairT(), Skipper> pair;
00334 qi::rule<Iterator, VectorPairT(), Skipper> list;
00335 qi::rule<Iterator, ResultT(), Skipper> map;
00336 ph::function<Operations> op;
00337
00338 };
00339
00340
00341
00342 template <typename Iterator, typename KeyT, typename ValueT,
00343 typename KeyCompareT, typename AllocatorT, typename Skipper>
00344 struct Grammar_<Iterator, std::map<KeyT, ValueT, KeyCompareT, AllocatorT>,
00345 Skipper > {
00346 typedef MapGrammar<Iterator,
00347 std::map<KeyT, ValueT, KeyCompareT, AllocatorT>, Skipper> Grammar;
00348 };
00349
00350
00351
00352 template <typename Iterator, typename KeyT, typename ValueT,
00353 typename KeyCompareT, typename AllocatorT, typename Skipper>
00354 struct Grammar_<Iterator, GaudiUtils::VectorMap<KeyT, ValueT,
00355 KeyCompareT, AllocatorT>, Skipper>
00356 {
00357 typedef MapGrammar<Iterator,
00358 GaudiUtils::VectorMap<KeyT, ValueT, KeyCompareT, AllocatorT>,
00359 Skipper> Grammar;
00360 };
00361
00362 template< typename Iterator, typename PointT, typename Skipper>
00363 struct Pnt3DGrammar : qi::grammar<Iterator, PointT(), Skipper> {
00364 typedef PointT ResultT;
00365 typedef typename PointT::Scalar Scalar;
00366
00367 struct Operations {
00368 template <typename A, typename B = boost::fusion::unused_type,
00369 typename C = boost::fusion::unused_type,
00370 typename D = boost::fusion::unused_type>
00371 struct result { typedef void type; };
00372 void operator()(ResultT& res, const Scalar& scalar,
00373 const char xyz) const{
00374 switch(xyz){
00375 case 'x': res.SetX(scalar); break;
00376 case 'y': res.SetY(scalar); break;
00377 case 'z': res.SetZ(scalar); break;
00378 default: break;
00379 }
00380 }
00381 };
00382
00383 Pnt3DGrammar() : Pnt3DGrammar::base_type(point) {
00384 point = list | ('(' >> list >> ')') | ('[' >> list >> ']');
00385 list = -(enc::no_case[qi::lit("x") | qi::lit("px")] >> ':')
00386 >> scalar[op(qi::_val,qi::_1,'x')] >>
00387 ',' >> -(enc::no_case[qi::lit("y") | qi::lit("py")] >> ':')
00388 >> scalar[op(qi::_val,qi::_1,'y')] >>
00389 ',' >> -(enc::no_case[qi::lit("z") | qi::lit("pz")] >> ':')
00390 >> scalar[op(qi::_val,qi::_1,'z')];
00391 }
00392
00393 qi::rule<Iterator, ResultT(), Skipper> point, list;
00394 typename Grammar_<Iterator, Scalar, Skipper>::Grammar scalar;
00395 ph::function<Operations> op;
00396
00397 };
00398
00399
00400
00401 template <typename Iterator, typename T1, typename T2, typename Skipper>
00402 struct Grammar_<Iterator, ROOT::Math::PositionVector3D<T1,T2>, Skipper>{
00403 typedef
00404 Pnt3DGrammar<Iterator, ROOT::Math::PositionVector3D<T1,T2>, Skipper>
00405 Grammar;
00406 };
00407
00408
00409
00410 template <typename Iterator, typename T1, typename T2, typename Skipper>
00411 struct Grammar_<Iterator, ROOT::Math::DisplacementVector3D<T1,T2>, Skipper>{
00412 typedef
00413 Pnt3DGrammar<Iterator,
00414 ROOT::Math::DisplacementVector3D<T1,T2>, Skipper> Grammar;
00415 };
00416
00417 template< typename Iterator, typename PointT, typename Skipper>
00418 struct Pnt4DGrammar : qi::grammar<Iterator, PointT(), Skipper>
00419 {
00420 typedef PointT ResultT;
00421 typedef typename PointT::Scalar ScalarT;
00422
00423 struct Operations {
00424 template <typename A, typename B = boost::fusion::unused_type,
00425 typename C = boost::fusion::unused_type,
00426 typename D = boost::fusion::unused_type>
00427 struct result { typedef void type; };
00428
00429 void operator()(ResultT& res, const ScalarT& scalar,
00430 const char xyz) const{
00431 switch(xyz){
00432 case 'x': res.SetPx(scalar); break;
00433 case 'y': res.SetPy(scalar); break;
00434 case 'z': res.SetPz(scalar); break;
00435 case 'e': res.SetE(scalar); break;
00436 default: break;
00437 }
00438 }
00439 void operator()(ResultT& res, const ResultT& xyz) const{
00440 res.SetPx(xyz.Px());
00441 res.SetPy(xyz.Py());
00442 res.SetPz(xyz.Pz());
00443 }
00444 };
00445
00446 Pnt4DGrammar() : Pnt4DGrammar::base_type(point4d) {
00447 point4d = list4d | ('(' >> list4d >> ')') | ('[' >> list4d >> ']');
00448 list4d = (point3d[op(qi::_val,qi::_1)] >> enc::char_(";,")
00449 >> e[op(qi::_val, qi::_1, 'e')])
00450 |
00451 (e[op(qi::_val,qi::_1, 'e')] >> enc::char_(";,")
00452 >> point3d[op(qi::_val, qi::_1)]);
00453 e = -(enc::no_case[enc::char_("te")] >> ':')
00454 >> scalar[qi::_val = qi::_1];
00455
00456 point3d = list3d | ('(' >> list3d >> ')') | ('[' >> list3d >> ']');
00457 list3d = -(enc::no_case[qi::lit("x") | qi::lit("px")] >> ':')
00458 >> scalar[op(qi::_val, qi::_1,'x')] >>
00459 ',' >> -(enc::no_case[qi::lit("y") | qi::lit("py")] >> ':')
00460 >> scalar[op(qi::_val, qi::_1,'y')] >>
00461 ',' >> -(enc::no_case[qi::lit("z") | qi::lit("pz")] >> ':')
00462 >> scalar[op(qi::_val, qi::_1,'z')];
00463 }
00464
00465 qi::rule<Iterator, ResultT(), Skipper> point3d, point4d, list3d,
00466 list4d;
00467 qi::rule<Iterator, ScalarT(), Skipper> e;
00468 typename Grammar_<Iterator, ScalarT, Skipper>::Grammar scalar;
00469 ph::function<Operations> op;
00470
00471 };
00472
00473
00474
00475 template <typename Iterator, typename T1, typename Skipper>
00476 struct Grammar_<Iterator, ROOT::Math::LorentzVector<T1>, Skipper >
00477 {
00478 typedef Pnt4DGrammar<Iterator, ROOT::Math::LorentzVector<T1>, Skipper>
00479 Grammar;
00480 };
00481
00482 template< typename Iterator, typename Skipper>
00483 struct Histo1DGrammar : qi::grammar<Iterator, Gaudi::Histo1DDef(),
00484 qi::locals<char>, Skipper>
00485 {
00486 typedef Gaudi::Histo1DDef ResultT;
00487
00488 struct Operations {
00489 template <typename A, typename B = boost::fusion::unused_type,
00490 typename C = boost::fusion::unused_type,
00491 typename D = boost::fusion::unused_type>
00492 struct result { typedef void type; };
00493 void operator()(ResultT& res, const std::string& title) const{
00494 res.setTitle(title);
00495 }
00496 void operator()(ResultT& res, const double& val, const char lh) const{
00497 switch (lh) {
00498 case 'l': res.setLowEdge(val); break;
00499 case 'h': res.setHighEdge(val); break;
00500 default: break;
00501 }
00502 }
00503 void operator()(ResultT& res, int val) const{
00504 res.setBins(val);
00505 }
00506 void operator()(ResultT& res) const{}
00507 };
00508
00509 Histo1DGrammar() : Histo1DGrammar::base_type(hist) {
00510 val1 = title[op(qi::_val, qi::_1)] >> ','
00511 >> qi::double_[op(qi::_val, qi::_1, 'l')] >> ','
00512 >> qi::double_[op(qi::_val, qi::_1, 'h')]
00513 >> -(',' >> qi::int_[op(qi::_val, qi::_1)]);
00514 val2 = qi::double_[op(qi::_val, qi::_1, 'l')] >> ','
00515 >> qi::double_[op(qi::_val, qi::_1, 'h')] >> ','
00516 >> title[op(qi::_val, qi::_1)] >> -(','
00517 >> qi::int_[op(qi::_val, qi::_1)]);
00518 val3 = qi::double_[op(qi::_val, qi::_1, 'l')] >> ','
00519 >> qi::double_[op(qi::_val, qi::_1, 'h')]
00520 >> -(',' >> title[op(qi::_val, qi::_1)])
00521 >> -(',' >> qi::int_[op(qi::_val, qi::_1)]);
00522 begin = enc::char_('[')[qi::_val=']'] | enc::char_('(')[qi::_val=')'];
00523 end = enc::char_(qi::_r1);
00524 hist = begin[qi::_a = qi::_1] >> (val1 | val2 | val3)[qi::_val=qi::_1]
00525 >> end(qi::_a);
00526 }
00527
00528 qi::rule<Iterator, ResultT(), qi::locals<char>, Skipper> hist;
00529 qi::rule<Iterator, ResultT(), Skipper> val1, val2, val3;
00530 qi::rule<Iterator, char()> begin;
00531 qi::rule<Iterator, void(char)> end;
00532 StringGrammar<Iterator, Skipper> title;
00533 ph::function<Operations> op;
00534
00535 };
00536
00537 REGISTER_GRAMMAR(Gaudi::Histo1DDef, Histo1DGrammar);
00538
00539 template< typename Iterator, typename Skipper>
00540 struct KeyValueGrammar :
00541 qi::grammar<Iterator, std::pair<std::string, std::string>(), Skipper> {
00542
00543 typedef std::pair<std::string, std::string> ResultT;
00544
00545 struct first {};
00546 struct second {};
00547
00548 KeyValueGrammar() : KeyValueGrammar::base_type(pair) {
00549
00550 pair = gstring >> ":" >> +enc::char_;
00551 }
00552
00553 StringGrammar<Iterator, Skipper> gstring;
00554 qi::rule<Iterator, ResultT(), Skipper> pair;
00555
00556 };
00557
00558
00559 }}
00560
00561 #endif