00001 #include "DetectorDescription/Base/interface/Singleton.h"
00002 #include "DetectorDescription/Core/interface/DDPartSelection.h"
00003 #include "DetectorDescription/Base/interface/DDdebug.h"
00004 #include "DetectorDescription/Core/interface/DDSplit.h"
00005
00006 #include "boost/spirit/include/classic.hpp"
00007
00008
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010
00011 #include <map>
00012
00013 namespace boost { namespace spirit { namespace classic { } } } using namespace boost::spirit::classic;
00014
00015 struct DDSelLevelCollector
00016 {
00017 std::string namespace_;
00018 std::string name_;
00019 int copyNo_;
00020 bool isCopyNoValid_;
00021 bool isChild_;
00022 std::vector<DDPartSelRegExpLevel>* p_;
00023
00024 std::vector<DDPartSelRegExpLevel>* path(std::vector<DDPartSelRegExpLevel>* p=0) {
00025 if (p) {
00026 p_=p;
00027 namespace_="";
00028 name_="";
00029 copyNo_=0;
00030 isCopyNoValid_=false;
00031 isChild_=false;
00032 }
00033 return p_;
00034 }
00035 };
00036
00037
00038 void noNameSpace(char const * , char const* ) {
00039 DDI::Singleton<DDSelLevelCollector>::instance().namespace_="";
00040 }
00041
00042
00043
00044
00045 struct DDSelLevelFtor
00046 {
00047 DDSelLevelFtor()
00048 : c_(DDI::Singleton<DDSelLevelCollector>::instance())
00049 { }
00050
00051
00052 void operator() (char const* , char const* ) const {
00053 if(c_.path()){
00054 if (c_.isCopyNoValid_ && c_.isChild_) {
00055 c_.path()->push_back(DDPartSelRegExpLevel(c_.namespace_,c_.name_,c_.copyNo_,ddchildposp));
00056
00057 } else
00058 if (c_.isCopyNoValid_ && !c_.isChild_) {
00059 c_.path()->push_back(DDPartSelRegExpLevel(c_.namespace_,c_.name_,c_.copyNo_,ddanyposp));
00060
00061 } else
00062 if (!c_.isCopyNoValid_ && c_.isChild_) {
00063 c_.path()->push_back(DDPartSelRegExpLevel(c_.namespace_,c_.name_,c_.copyNo_,ddchildlogp));
00064
00065 } else
00066 if (!c_.isCopyNoValid_ && !c_.isChild_) {
00067 c_.path()->push_back(DDPartSelRegExpLevel(c_.namespace_,c_.name_,c_.copyNo_,ddanylogp));
00068
00069 }
00070 c_.namespace_="";
00071 c_.name_="";
00072 c_.isCopyNoValid_=false;
00073 }
00074 }
00075
00076 DDSelLevelCollector & c_;
00077 };
00078
00079 struct DDIsChildFtor
00080 {
00081
00082 void operator()(char const* first, char const* last) const {
00083 DDSelLevelCollector & sl = DDI::Singleton<DDSelLevelCollector>::instance();
00084 if ( (last-first) > 1)
00085 sl.isChild_=false;
00086 if ( (last-first) ==1 )
00087 sl.isChild_=true;
00088
00089 }
00090
00091 };
00092
00093
00094 struct DDNameSpaceFtor
00095 {
00096
00097 void operator()(char const* first, char const* last) const {
00098 DDSelLevelCollector & sl = DDI::Singleton<DDSelLevelCollector>::instance();
00099 sl.namespace_.assign(first,last);
00100
00101 }
00102
00103 DDSelLevelFtor* selLevelFtor_;
00104 };
00105
00106
00107 struct DDNameFtor
00108 {
00109
00110 void operator()(char const* first, char const* last) const {
00111 DDSelLevelCollector & sl = DDI::Singleton<DDSelLevelCollector>::instance();
00112 sl.name_.assign(first,last);
00113
00114 }
00115
00116 };
00117
00118
00119 struct DDCopyNoFtor
00120 {
00121
00122 void operator()(int i) const {
00123 DDSelLevelCollector & sl = DDI::Singleton<DDSelLevelCollector>::instance();
00124 sl.copyNo_ = i;
00125 sl.isCopyNoValid_ = true;
00126
00127 }
00128
00129 };
00130
00131
00132
00134 struct SpecParParser : public grammar<SpecParParser>
00135 {
00136 template <typename ScannerT>
00137 struct definition
00138 {
00139 definition(SpecParParser const& ) {
00140
00141 Selection
00142
00143 = +SelectionStep[selLevelFtor()]
00144 ;
00145
00146 FirstStep = Descendant
00147 >> Part
00148 ;
00149
00150 Part = PartNameCopyNumber
00151 | PartName
00152 ;
00153
00154 PartNameCopyNumber = PartName
00155 >> CopyNumber
00156 ;
00157
00158 SelectionStep = NavigationalElement[isChildFtor()]
00159 >> Part
00160 ;
00161
00162 NavigationalElement = Descendant
00163 | Child
00164 ;
00165
00166 CopyNumber = ch_p('[')
00167 >> int_p[copyNoFtor()]
00168 >> ch_p(']')
00169 ;
00170
00171 PartName = NameSpaceName
00172 | SimpleName[nameFtor()][&noNameSpace]
00173 ;
00174
00175 SimpleName = +( alnum_p | ch_p('_') | ch_p('.') | ch_p('*') )
00176 ;
00177
00178 NameSpaceName = SimpleName[nameSpaceFtor()]
00179 >> ':'
00180 >> SimpleName[nameFtor()]
00181 ;
00182
00183 Descendant = ch_p('/')
00184 >> ch_p('/')
00185 ;
00186
00187 Child = ch_p('/')
00188 ;
00189
00190 }
00191
00192 rule<ScannerT> Selection, FirstStep, Part, SelectionStep, NavigationalElement,
00193 CopyNumber, PartName, PartNameCopyNumber, NameSpaceName, SimpleName,
00194 Descendant, Child;
00195
00196 rule<ScannerT> const& start() const { return Selection; }
00197
00198 DDSelLevelFtor & selLevelFtor() {
00199 return DDI::Singleton<DDSelLevelFtor>::instance();
00200 }
00201
00202 DDNameFtor & nameFtor() {
00203 static DDNameFtor f_;
00204 return f_;
00205 }
00206
00207 DDNameSpaceFtor & nameSpaceFtor() {
00208 static DDNameSpaceFtor f_;
00209 return f_;
00210 }
00211
00212 DDIsChildFtor & isChildFtor() {
00213 static DDIsChildFtor f_;
00214 return f_;
00215 }
00216
00217 DDCopyNoFtor & copyNoFtor() {
00218 static DDCopyNoFtor f_;
00219 return f_;
00220 }
00221 };
00222
00223 };
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 DDPartSelectionLevel::DDPartSelectionLevel(const DDLogicalPart & lp, int c, ddselection_type t)
00256 : lp_(lp), copyno_(c), selectionType_(t)
00257 {
00258
00259 }
00260
00261
00262
00263 void DDTokenize2(const std::string & sel, std::vector<DDPartSelRegExpLevel> & path)
00264 {
00265 static SpecParParser parser;
00266 DDI::Singleton<DDSelLevelCollector>::instance().path(&path);
00267 bool result = parse(sel.c_str(), parser).full;
00268 if (!result) {
00269 edm::LogError("DDPartSelection") << "DDTokenize2() error in parsing of " << sel << std::endl;
00270 }
00271 }
00272
00273
00274
00275
00276
00277
00278 void DDTokenize(const std::string & sel, std::vector<DDPartSelRegExpLevel> & path)
00279 {
00280
00281
00282 static bool isInit(false);
00283 static std::vector<std::string> tokens;
00284 if(!isInit) {
00285
00286 tokens.push_back("/");
00287 tokens.push_back("//");
00288 tokens.push_back("[");
00289 tokens.push_back("]");
00290 }
00291 std::string s = sel;
00292 std::string::size_type st = std::string::npos;
00293 std::string::size_type cu = 0;
00294 std::vector<std::string> toksVec;
00295 std::vector<std::string> textVec;
00296 std::string tkn, txt;
00297 bool braceOpen(false);
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 while (s.size()) {
00311 std::vector<std::string>::iterator tkit = tokens.begin();
00312 std::vector<std::string>::iterator mint = tokens.end();
00313 st=s.size();
00314 std::string::size_type ts;
00315 for(;tkit!=tokens.end();++tkit) {
00316 ts = s.find(*tkit);
00317 if (ts<=st) {
00318 st=ts;
00319 mint = tkit;
00320 }
00321 }
00322
00323 if (mint!=tokens.end())
00324 tkn = s.substr(st,mint->size());
00325 else
00326 tkn="";
00327 txt = s.substr(cu,st);
00328 toksVec.push_back(tkn);
00329 textVec.push_back(txt);
00330 if (braceOpen) {
00331 if (tkn!="]")
00332 throw cms::Exception("DDException") << "PartSelector: syntaxerror in " << sel
00333 << "\ncheck the braces!";
00334 else
00335 braceOpen=false;
00336 }
00337 if (tkn=="[")
00338 braceOpen=true;
00339 DCOUT_V('C',"tkn=" << tkn << " txt=" << txt);
00340 if (mint!=tokens.end())
00341 s.erase(cu,st+mint->size());
00342 else
00343 s.erase();
00344 DCOUT_V('C', std::endl << "s=" << s);
00345
00346 }
00347 DCOUT_V('C', "The original std::string was:" << std::endl);
00348 unsigned int i=0;
00349 DCOUT_V('C', "toks\ttext");
00350 for (i=0; i<toksVec.size();++i) {
00351 DCOUT_V('C', toksVec[i] << "\t" << textVec[i]);
00352 }
00353 DCOUT_V('C', std::endl);
00354
00355
00356 std::string nm = "blabla" ;
00357 if (textVec[0] != "")
00358 throw cms::Exception("DDException") << nm << " selection must not start with a LogicalPart-name";
00359
00360 if ((toksVec[0] != "//"))
00361 throw cms::Exception("DDException") << nm << " selection must start with '//' !";
00362
00363 if (textVec.size() < 2)
00364 throw cms::Exception("DDException") << nm << " internal error [textVec.size()<2]!";
00365
00366 std::vector<std::string>::iterator tk_it = toksVec.begin();
00367 std::vector<std::string>::iterator tx_it = textVec.begin(); ++tx_it;
00368
00369 while(tk_it != toksVec.end() && tx_it != textVec.end()) {
00370
00371
00372 DCOUT_V('C', ">- anynode tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
00373 if ( *tk_it == "//" && *tx_it=="*" ) {
00374 path.push_back(DDPartSelRegExpLevel("","",0,ddanynode));
00375 DCOUT_V('C', "--anynode: //*" << std::endl);
00376 ++tk_it;
00377 ++tx_it;
00378 continue;
00379 }
00380
00381
00382 DCOUT_V('C', ">- anychild tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
00383 if ( *tk_it == "/" && *tx_it=="*" ) {
00384 path.push_back(DDPartSelRegExpLevel("","",0,ddanychild));
00385 DCOUT_V('C', "--anychild: /*" << std::endl);
00386 ++tk_it;
00387 ++tx_it;
00388 continue;
00389 }
00390
00391
00392 DCOUT_V('C', ">- anylogp tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
00393 if ( *tk_it == "//" && tx_it->size()) {
00394 ++tk_it;
00395 if ( tk_it != toksVec.end() && *tk_it != "[" && *tk_it != "]") {
00396 std::pair<std::string,std::string> p(DDSplit(*tx_it));
00397 path.push_back(DDPartSelRegExpLevel(p.second,p.first,0,ddanylogp));
00398 DCOUT_V('C', "--anylogp: " << *tx_it << std::endl);
00399 ++tx_it;
00400 continue;
00401 }
00402 --tk_it;
00403 }
00404
00405
00406 DCOUT_V('C', ">- childlogp tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
00407 if ( *tk_it == "/" && tx_it->size()) {
00408 ++tk_it;
00409 if ( tk_it == toksVec.end() - 1 ) {
00410 DCOUT_V('C', "--childlogp: " << *tx_it << std::endl);
00411 std::pair<std::string,std::string> p(DDSplit(*tx_it));
00412 path.push_back(DDPartSelRegExpLevel(p.second,p.first,0,ddchildlogp));
00413 ++tx_it;
00414 continue;
00415 }
00416 if ( *tk_it == "/" || *tk_it=="//") {
00417 DCOUT_V('C', "--childlogp: " << *tx_it << std::endl);
00418 std::pair<std::string,std::string> p(DDSplit(*tx_it));
00419 path.push_back(DDPartSelRegExpLevel(p.second,p.first,0,ddchildlogp));
00420 ++tx_it;
00421 continue;
00422 }
00423 --tk_it;
00424 }
00425
00426
00427
00428 DCOUT_V('C', ">- anyposp tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
00429 if ( *tk_it == "//" && tx_it->size()) {
00430 ++tk_it;
00431 if ( tk_it != toksVec.end() && *tk_it == "[" ) {
00432 ++tk_it;
00433 if ( tk_it == toksVec.end() || (tk_it != toksVec.end() && *tk_it != "]")) {
00434 DCOUT_V('C', *tk_it << " " << *tx_it );
00435 break;
00436 }
00437 ++tx_it;
00438 ++tk_it;
00439 std::pair<std::string,std::string> p(DDSplit(*(tx_it-1)));
00440 path.push_back(DDPartSelRegExpLevel(p.second,p.first,atoi(tx_it->c_str()),ddanyposp));
00441 DCOUT_V('C', "--anyposp: " << *tx_it << " " << atoi(tx_it->c_str()) << std::endl);
00442 ++tx_it;
00443 ++tx_it;
00444 continue;
00445 }
00446 }
00447
00448
00449
00450 DCOUT_V('C', ">- childposp tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
00451 if ( *tk_it == "/" && tx_it->size()) {
00452 ++tk_it;
00453 if ( tk_it != toksVec.end() && *tk_it=="[" ) {
00454 DCOUT_V('C', "--childposp: " << *tx_it << " " << *tk_it << *(tx_it+1) << std::endl);
00455 std::pair<std::string,std::string> p(DDSplit(*tx_it));
00456 path.push_back(DDPartSelRegExpLevel(p.second,p.first,atoi((tx_it+1)->c_str()),ddchildposp));
00457
00458 ++tx_it;
00459
00460 ++tx_it;
00461 ++tk_it;
00462 if (tk_it != toksVec.end() && *tk_it != "]")
00463 break;
00464 ++tk_it;
00465 ++tx_it;
00466 continue;
00467 }
00468 }
00469
00470
00471 throw cms::Exception("DDException") << nm << " syntax error in:\n" << sel
00472 << "\n tkn=" << *tk_it << " txt=" << *tx_it;
00473 }
00474
00475 ddselection_type tmp = path.back().selectionType_;
00476 if (tmp==ddunknown || tmp==ddanynode || tmp==ddanychild )
00477 throw cms::Exception("DDException") << "PartSelector: last element in selection std::string in " << sel
00478 << "\nmust address a distinct LogicalPart or PosPart!";
00479 }
00480
00481
00482 std::ostream & operator<<(std::ostream & o, const DDPartSelection & p)
00483 {
00484 DDPartSelection::const_iterator it(p.begin()), ed(p.end());
00485 for (; it != ed; ++it) {
00486 const DDPartSelectionLevel lv =*it;
00487 switch (lv.selectionType_) {
00488 case ddanylogp:
00489 o << "//" << lv.lp_.ddname();
00490 break;
00491 case ddanyposp:
00492 o << "//" << lv.lp_.ddname() << '[' << lv.copyno_ << ']';
00493 break;
00494 case ddchildlogp:
00495 o << "/" << lv.lp_.ddname();
00496 break;
00497 case ddchildposp:
00498 o << "/" << lv.lp_.ddname() << '[' << lv.copyno_ << ']';
00499 break;
00500 default:
00501 o << "{Syntax ERROR}";
00502 }
00503 }
00504 return o;
00505 }
00506
00507 std::ostream & operator<<(std::ostream & os, const std::vector<DDPartSelection> & v)
00508 {
00509 std::vector<DDPartSelection>::const_iterator it(v.begin()), ed(v.end());
00510 for (; it != (ed-1); ++it) {
00511 os << *it << std::endl;
00512 }
00513 if ( it != ed ) {
00514 ++it;
00515 os << *it;
00516 }
00517 return os;
00518 }
00519
00520
00521
00522 template class DDI::Singleton<DDSelLevelFtor>;
00523
00524 template class DDI::Singleton<DDSelLevelCollector>;
00525 #include <DetectorDescription/Base/interface/Singleton.icc>