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