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 | sp::eoi))[*(qi::char_ - (sp::eol|sp::eoi))];
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>()[qi::_val = qi::_1]
00145 >> -qi::no_case[qi::char_('L')];
00146 }
00147 qi::rule<Iterator, RT(), Skipper> integer;
00148 };
00149
00150
00151
00152 template <typename Iterator, typename T, typename Skipper>
00153 struct Grammar_<Iterator, T, Skipper,
00154 typename boost::enable_if<boost::is_integral<T> >::type>
00155 {
00156 typedef IntGrammar<Iterator, T, Skipper> Grammar;
00157 };
00158
00159 template< typename Iterator, typename RT, typename Skipper>
00160 struct RealGrammar : qi::grammar<Iterator, RT(), Skipper>
00161 {
00162 typedef RT ResultT;
00163 RealGrammar() : RealGrammar::base_type(real) {
00164 real = qi::real_parser<RT>();
00165 }
00166 qi::rule<Iterator, RT(), Skipper> real;
00167 };
00168
00169
00170
00171 template <typename Iterator, typename T, typename Skipper >
00172 struct Grammar_<Iterator, T, Skipper,
00173 typename boost::enable_if<boost::is_floating_point<T> >::type >
00174 {
00175 typedef RealGrammar<Iterator, T, Skipper> Grammar;
00176 };
00177
00178 template< typename Iterator, typename VectorT, typename Skipper>
00179 struct VectorGrammar : qi::grammar<Iterator,
00180 VectorT(), qi::locals<char>,Skipper>
00181 {
00182
00183 typedef VectorT ResultT;
00184
00185 VectorGrammar() : VectorGrammar::base_type(vec) {
00186 begin = enc::char_('[')[qi::_val=']'] | enc::char_('{')[qi::_val='}']
00187 | enc::char_('(')[qi::_val=')'];
00188 end = enc::char_(qi::_r1);
00189 list = elementGrammar % ',';
00190 vec = begin[qi::_a = qi::_1] >> -list[qi::_val=qi::_1] >> end(qi::_a);
00191 }
00192
00193 typename
00194 Grammar_<Iterator, typename VectorT::value_type, Skipper>::Grammar
00195 elementGrammar;
00196 qi::rule<Iterator, char()> begin;
00197 qi::rule<Iterator, void(char)> end;
00198
00199 qi::rule<Iterator, ResultT(), qi::locals<char>,Skipper> vec;
00200 qi::rule<Iterator, ResultT(), Skipper> list;
00201
00202 };
00203
00204
00205
00206 template <typename Iterator, typename InnerT, typename AllocatorT,
00207 typename Skipper>
00208 struct Grammar_<Iterator, std::vector<InnerT, AllocatorT>, Skipper >
00209 {
00210 typedef
00211 VectorGrammar<Iterator, std::vector<InnerT, AllocatorT>,Skipper>
00212 Grammar;
00213 };
00214
00215
00216
00217 template <typename Iterator, typename InnerT, typename AllocatorT,
00218 typename Skipper>
00219 struct Grammar_<Iterator, std::list<InnerT, AllocatorT>, Skipper >
00220 {
00221 typedef
00222 VectorGrammar<Iterator, std::list<InnerT, AllocatorT>,Skipper>
00223 Grammar;
00224 };
00225
00226
00227
00228 template <typename Iterator, typename InnerT, typename CompareT,
00229 typename AllocatorT, typename Skipper>
00230 struct Grammar_<Iterator, std::set<InnerT, CompareT, AllocatorT>, Skipper >
00231 {
00232 typedef
00233 VectorGrammar<Iterator, std::set<InnerT, CompareT, AllocatorT>,Skipper>
00234 Grammar;
00235 };
00236
00237
00238 template< typename Iterator, typename PairT, typename Skipper>
00239 struct PairGrammar :
00240 qi::grammar<Iterator,PairT(), qi::locals<char>, Skipper> {
00241
00242 typedef PairT ResultT;
00243 typedef typename PairT::first_type first_type;
00244 typedef typename PairT::second_type second_type;
00245
00246 PairGrammar() : PairGrammar::base_type(pair) {
00247 init(",");
00248 }
00249
00250 PairGrammar(const std::string& delimeter) : PairGrammar::base_type(pair) {
00251 init(delimeter);
00252 }
00253
00254 struct first {};
00255 struct second {};
00256 void init(const std::string& delimeter) {
00257 begin = enc::char_('(')[qi::_val=')']
00258 |
00259 enc::char_('[')[qi::_val=']'];
00260 end = qi::char_(qi::_r1);
00261 pair = begin[qi::_a = qi::_1] >> pair_in[qi::_val = qi::_1] >> end(qi::_a);
00262 pair_in = key >> qi::lit(delimeter) >> value;
00263 }
00264
00265 typename
00266 Grammar_<Iterator, typename PairT::first_type, Skipper>::Grammar key;
00267 typename
00268 Grammar_<Iterator, typename PairT::second_type, Skipper>::Grammar
00269 value;
00270 qi::rule<Iterator, char()> begin;
00271 qi::rule<Iterator, void(char)> end;
00272 qi::rule<Iterator, ResultT(), qi::locals<char>, Skipper> pair;
00273 qi::rule<Iterator, ResultT(), Skipper> pair_in;
00274
00275
00276 };
00277
00278
00279
00280 template <typename Iterator, typename KeyT, typename ValueT,
00281 typename Skipper>
00282 struct Grammar_<Iterator, std::pair<KeyT, ValueT>, Skipper >
00283 {
00284 typedef PairGrammar<Iterator, std::pair<KeyT, ValueT>, Skipper> Grammar;
00285 };
00286
00287 template< typename Iterator, typename MapT, typename Skipper>
00288 struct MapGrammar : qi::grammar<Iterator,MapT(), Skipper>
00289 {
00290
00291 typedef MapT ResultT;
00292 typedef typename MapT::key_type KeyT;
00293 typedef typename MapT::mapped_type MappedT;
00294 typedef std::pair<KeyT, MappedT> PairT;
00295
00296 typedef std::vector<PairT> VectorPairT;
00297
00298 struct tag_key{};
00299 struct tag_mapped{};
00300 struct Operations
00301 {
00302 template <typename A, typename B = boost::fusion::unused_type,
00303 typename C = boost::fusion::unused_type,
00304 typename D = boost::fusion::unused_type>
00305 struct result { typedef void type; };
00306
00307 void operator()(ResultT& res, const VectorPairT& vec) const{
00308 for(typename VectorPairT::const_iterator cur = vec.begin();
00309 cur != vec.end(); cur++){
00310 res.insert(*cur);
00311 }
00312 }
00313 void operator()(PairT& res, const KeyT& key, tag_key) const{
00314 res.first = key;
00315 }
00316 void operator()(PairT& res, const MappedT& value, tag_mapped) const{
00317 res.second = value;
00318 }
00319
00320 };
00321
00322 MapGrammar() : MapGrammar::base_type(map) {
00323 pair = key[op(qi::_val,qi::_1, tag_key())] > (qi::lit(':') | '=') >
00324 value[op(qi::_val,qi::_1, tag_mapped())];
00325 list = -(pair % enc::char_(','));
00326 map = (('[' >> list >> ']')
00327 | ('{' >> list >> '}'))[op(qi::_val,qi::_1)];
00328 }
00329
00330 typename
00331 Grammar_<Iterator, typename MapT::key_type, Skipper>::Grammar key;
00332 typename
00333 Grammar_<Iterator, typename MapT::mapped_type, Skipper>::Grammar value;
00334 qi::rule<Iterator, PairT(), Skipper> pair;
00335 qi::rule<Iterator, VectorPairT(), Skipper> list;
00336 qi::rule<Iterator, ResultT(), Skipper> map;
00337 ph::function<Operations> op;
00338
00339 };
00340
00341
00342
00343 template <typename Iterator, typename KeyT, typename ValueT,
00344 typename KeyCompareT, typename AllocatorT, typename Skipper>
00345 struct Grammar_<Iterator, std::map<KeyT, ValueT, KeyCompareT, AllocatorT>,
00346 Skipper > {
00347 typedef MapGrammar<Iterator,
00348 std::map<KeyT, ValueT, KeyCompareT, AllocatorT>, Skipper> Grammar;
00349 };
00350
00351
00352
00353 template <typename Iterator, typename KeyT, typename ValueT,
00354 typename KeyCompareT, typename AllocatorT, typename Skipper>
00355 struct Grammar_<Iterator, GaudiUtils::VectorMap<KeyT, ValueT,
00356 KeyCompareT, AllocatorT>, Skipper>
00357 {
00358 typedef MapGrammar<Iterator,
00359 GaudiUtils::VectorMap<KeyT, ValueT, KeyCompareT, AllocatorT>,
00360 Skipper> Grammar;
00361 };
00362
00363 template< typename Iterator, typename PointT, typename Skipper>
00364 struct Pnt3DGrammar : qi::grammar<Iterator, PointT(), Skipper> {
00365 typedef PointT ResultT;
00366 typedef typename PointT::Scalar Scalar;
00367
00368 struct Operations {
00369 template <typename A, typename B = boost::fusion::unused_type,
00370 typename C = boost::fusion::unused_type,
00371 typename D = boost::fusion::unused_type>
00372 struct result { typedef void type; };
00373 void operator()(ResultT& res, const Scalar& scalar,
00374 const char xyz) const{
00375 switch(xyz){
00376 case 'x': res.SetX(scalar); break;
00377 case 'y': res.SetY(scalar); break;
00378 case 'z': res.SetZ(scalar); break;
00379 default: break;
00380 }
00381 }
00382 };
00383
00384 Pnt3DGrammar() : Pnt3DGrammar::base_type(point) {
00385 point = list | ('(' >> list >> ')') | ('[' >> list >> ']');
00386 list = -(enc::no_case[qi::lit("x") | qi::lit("px")] >> ':')
00387 >> scalar[op(qi::_val,qi::_1,'x')] >>
00388 ',' >> -(enc::no_case[qi::lit("y") | qi::lit("py")] >> ':')
00389 >> scalar[op(qi::_val,qi::_1,'y')] >>
00390 ',' >> -(enc::no_case[qi::lit("z") | qi::lit("pz")] >> ':')
00391 >> scalar[op(qi::_val,qi::_1,'z')];
00392 }
00393
00394 qi::rule<Iterator, ResultT(), Skipper> point, list;
00395 typename Grammar_<Iterator, Scalar, Skipper>::Grammar scalar;
00396 ph::function<Operations> op;
00397
00398 };
00399
00400
00401
00402 template <typename Iterator, typename T1, typename T2, typename Skipper>
00403 struct Grammar_<Iterator, ROOT::Math::PositionVector3D<T1,T2>, Skipper>{
00404 typedef
00405 Pnt3DGrammar<Iterator, ROOT::Math::PositionVector3D<T1,T2>, Skipper>
00406 Grammar;
00407 };
00408
00409
00410
00411 template <typename Iterator, typename T1, typename T2, typename Skipper>
00412 struct Grammar_<Iterator, ROOT::Math::DisplacementVector3D<T1,T2>, Skipper>{
00413 typedef
00414 Pnt3DGrammar<Iterator,
00415 ROOT::Math::DisplacementVector3D<T1,T2>, Skipper> Grammar;
00416 };
00417
00418 template< typename Iterator, typename PointT, typename Skipper>
00419 struct Pnt4DGrammar : qi::grammar<Iterator, PointT(), Skipper>
00420 {
00421 typedef PointT ResultT;
00422 typedef typename PointT::Scalar ScalarT;
00423
00424 struct Operations {
00425 template <typename A, typename B = boost::fusion::unused_type,
00426 typename C = boost::fusion::unused_type,
00427 typename D = boost::fusion::unused_type>
00428 struct result { typedef void type; };
00429
00430 void operator()(ResultT& res, const ScalarT& scalar,
00431 const char xyz) const{
00432 switch(xyz){
00433 case 'x': res.SetPx(scalar); break;
00434 case 'y': res.SetPy(scalar); break;
00435 case 'z': res.SetPz(scalar); break;
00436 case 'e': res.SetE(scalar); break;
00437 default: break;
00438 }
00439 }
00440 void operator()(ResultT& res, const ResultT& xyz) const{
00441 res.SetPx(xyz.Px());
00442 res.SetPy(xyz.Py());
00443 res.SetPz(xyz.Pz());
00444 }
00445 };
00446
00447 Pnt4DGrammar() : Pnt4DGrammar::base_type(point4d) {
00448 point4d = list4d | ('(' >> list4d >> ')') | ('[' >> list4d >> ']');
00449 list4d = (point3d[op(qi::_val,qi::_1)] >> enc::char_(";,")
00450 >> e[op(qi::_val, qi::_1, 'e')])
00451 |
00452 (e[op(qi::_val,qi::_1, 'e')] >> enc::char_(";,")
00453 >> point3d[op(qi::_val, qi::_1)]);
00454 e = -(enc::no_case[enc::char_("te")] >> ':')
00455 >> scalar[qi::_val = qi::_1];
00456
00457 point3d = list3d | ('(' >> list3d >> ')') | ('[' >> list3d >> ']');
00458 list3d = -(enc::no_case[qi::lit("x") | qi::lit("px")] >> ':')
00459 >> scalar[op(qi::_val, qi::_1,'x')] >>
00460 ',' >> -(enc::no_case[qi::lit("y") | qi::lit("py")] >> ':')
00461 >> scalar[op(qi::_val, qi::_1,'y')] >>
00462 ',' >> -(enc::no_case[qi::lit("z") | qi::lit("pz")] >> ':')
00463 >> scalar[op(qi::_val, qi::_1,'z')];
00464 }
00465
00466 qi::rule<Iterator, ResultT(), Skipper> point3d, point4d, list3d,
00467 list4d;
00468 qi::rule<Iterator, ScalarT(), Skipper> e;
00469 typename Grammar_<Iterator, ScalarT, Skipper>::Grammar scalar;
00470 ph::function<Operations> op;
00471
00472 };
00473
00474
00475
00476 template <typename Iterator, typename T1, typename Skipper>
00477 struct Grammar_<Iterator, ROOT::Math::LorentzVector<T1>, Skipper >
00478 {
00479 typedef Pnt4DGrammar<Iterator, ROOT::Math::LorentzVector<T1>, Skipper>
00480 Grammar;
00481 };
00482
00483 template< typename Iterator, typename Skipper>
00484 struct Histo1DGrammar : qi::grammar<Iterator, Gaudi::Histo1DDef(),
00485 qi::locals<char>, Skipper>
00486 {
00487 typedef Gaudi::Histo1DDef ResultT;
00488
00489 struct Operations {
00490 template <typename A, typename B = boost::fusion::unused_type,
00491 typename C = boost::fusion::unused_type,
00492 typename D = boost::fusion::unused_type>
00493 struct result { typedef void type; };
00494 void operator()(ResultT& res, const std::string& title) const{
00495 res.setTitle(title);
00496 }
00497 void operator()(ResultT& res, const double& val, const char lh) const{
00498 switch (lh) {
00499 case 'l': res.setLowEdge(val); break;
00500 case 'h': res.setHighEdge(val); break;
00501 default: break;
00502 }
00503 }
00504 void operator()(ResultT& res, int val) const{
00505 res.setBins(val);
00506 }
00507 void operator()(ResultT& res) const{}
00508 };
00509
00510 Histo1DGrammar() : Histo1DGrammar::base_type(hist) {
00511 val1 = title[op(qi::_val, qi::_1)] >> ','
00512 >> qi::double_[op(qi::_val, qi::_1, 'l')] >> ','
00513 >> qi::double_[op(qi::_val, qi::_1, 'h')]
00514 >> -(',' >> qi::int_[op(qi::_val, qi::_1)]);
00515 val2 = qi::double_[op(qi::_val, qi::_1, 'l')] >> ','
00516 >> qi::double_[op(qi::_val, qi::_1, 'h')] >> ','
00517 >> title[op(qi::_val, qi::_1)] >> -(','
00518 >> qi::int_[op(qi::_val, qi::_1)]);
00519 val3 = qi::double_[op(qi::_val, qi::_1, 'l')] >> ','
00520 >> qi::double_[op(qi::_val, qi::_1, 'h')]
00521 >> -(',' >> title[op(qi::_val, qi::_1)])
00522 >> -(',' >> qi::int_[op(qi::_val, qi::_1)]);
00523 begin = enc::char_('[')[qi::_val=']'] | enc::char_('(')[qi::_val=')'];
00524 end = enc::char_(qi::_r1);
00525 hist = begin[qi::_a = qi::_1] >> (val1 | val2 | val3)[qi::_val=qi::_1]
00526 >> end(qi::_a);
00527 }
00528
00529 qi::rule<Iterator, ResultT(), qi::locals<char>, Skipper> hist;
00530 qi::rule<Iterator, ResultT(), Skipper> val1, val2, val3;
00531 qi::rule<Iterator, char()> begin;
00532 qi::rule<Iterator, void(char)> end;
00533 StringGrammar<Iterator, Skipper> title;
00534 ph::function<Operations> op;
00535
00536 };
00537
00538 REGISTER_GRAMMAR(Gaudi::Histo1DDef, Histo1DGrammar);
00539
00540 template< typename Iterator, typename Skipper>
00541 struct KeyValueGrammar :
00542 qi::grammar<Iterator, std::pair<std::string, std::string>(), Skipper> {
00543
00544 typedef std::pair<std::string, std::string> ResultT;
00545
00546 struct first {};
00547 struct second {};
00548
00549 KeyValueGrammar() : KeyValueGrammar::base_type(pair) {
00550
00551 pair = gstring >> ":" >> +enc::char_;
00552 }
00553
00554 StringGrammar<Iterator, Skipper> gstring;
00555 qi::rule<Iterator, ResultT(), Skipper> pair;
00556
00557 };
00558
00559
00560 }}
00561
00562 #endif