CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DDPartSelection.cc
Go to the documentation of this file.
5 
6 #include "boost/spirit/include/classic.hpp"
7 
8 // Message logger.
10 
11 #include <map>
12 
13 namespace boost { namespace spirit { namespace classic { } } } using namespace boost::spirit::classic;
14 
16 {
17  std::string namespace_;
18  std::string name_;
19  int copyNo_;
21  bool isChild_;
22  std::vector<DDPartSelRegExpLevel>* p_;
23 
24  std::vector<DDPartSelRegExpLevel>* path(std::vector<DDPartSelRegExpLevel>* p=0) {
25  if (p) {
26  p_=p;
27  namespace_="";
28  name_="";
29  copyNo_=0;
30  isCopyNoValid_=false;
31  isChild_=false;
32  }
33  return p_;
34  }
35 };
36 
37 
38 void noNameSpace(char const * /*first*/, char const* /*last*/) {
40 }
41 /* Functor for the parser; it does not consume memory -
42  pointers are only used to store references to memory
43  managed elsewhere
44 */
46 {
48  : c_(DDI::Singleton<DDSelLevelCollector>::instance())
49  { }
50 
51  // parser calls this whenever a selection has been parsed ( //ns:nm[cn], /nm, //ns:nm, .... )
52  void operator() (char const* /*first*/, char const* /*last*/) const {
53  if(c_.path()){
54  if (c_.isCopyNoValid_ && c_.isChild_) {
55  c_.path()->push_back(DDPartSelRegExpLevel(c_.namespace_,c_.name_,c_.copyNo_,ddchildposp));
56  //edm::LogInfo("DDPartSelection") << namespace_ << name_ << copyNo_ << ' ' << ddchildposp << std::endl;
57  } else
58  if (c_.isCopyNoValid_ && !c_.isChild_) {
59  c_.path()->push_back(DDPartSelRegExpLevel(c_.namespace_,c_.name_,c_.copyNo_,ddanyposp));
60  // edm::LogInfo("DDPartSelection") << namespace_ << name_ << copyNo_ << ' ' << ddanyposp << std::endl;
61  } else
62  if (!c_.isCopyNoValid_ && c_.isChild_) {
63  c_.path()->push_back(DDPartSelRegExpLevel(c_.namespace_,c_.name_,c_.copyNo_,ddchildlogp));
64  // edm::LogInfo("DDPartSelection") << namespace_ << name_ << copyNo_ << ' ' << ddchildlogp << std::endl;
65  } else
66  if (!c_.isCopyNoValid_ && !c_.isChild_) {
67  c_.path()->push_back(DDPartSelRegExpLevel(c_.namespace_,c_.name_,c_.copyNo_,ddanylogp));
68  // edm::LogInfo("DDPartSelection") << namespace_ << name_ << copyNo_ << ' ' << ddanylogp << std::endl;
69  }
70  c_.namespace_="";
71  c_.name_="";
72  c_.isCopyNoValid_=false;
73  }
74  }
75 
77 };
78 
80 {
81 
82  void operator()(char const* first, char const* last) const {
84  if ( (last-first) > 1)
85  sl.isChild_=false;
86  if ( (last-first) ==1 )
87  sl.isChild_=true;
88  //edm::LogInfo("DDPartSelection") << "DDIsChildFtor isChild=" << (last-first) << std::endl;
89  }
90 
91 };
92 
93 
95 {
96 
97  void operator()(char const* first, char const* last) const {
99  sl.namespace_.assign(first,last);
100  // edm::LogInfo("DDPartSelection") << "DDNameSpaceFtor singletonname=" << DDI::Singleton<DDSelLevelCollector>::instance().namespace_ << std::endl;
101  }
102 
104 };
105 
106 
108 {
109 
110  void operator()(char const* first, char const* last) const {
112  sl.name_.assign(first,last);
113  // edm::LogInfo("DDPartSelection") << "DDNameFtor singletonname=" << Singleton<DDSelLevelCollector>::instance().name_ << std::endl;
114  }
115 
116 };
117 
118 
120 {
121 
122  void operator()(int i) const {
124  sl.copyNo_ = i;
125  sl.isCopyNoValid_ = true;
126  // edm::LogInfo("DDPartSelection") << "DDCopyNoFtor ns=" << i;
127  }
128 
129 };
130 
131 
132 
134 struct SpecParParser : public grammar<SpecParParser>
135 {
136  template <typename ScannerT>
137  struct definition
138  {
139  definition(SpecParParser const& /*self*/) {
140 
141  Selection //= FirstStep[selLevelFtor()]
142  //>> *SelectionStep[selLevelFtor()]
143  = +SelectionStep[selLevelFtor()]
144  ;
145 
146  FirstStep = Descendant
147  >> Part
148  ;
149 
150  Part = PartNameCopyNumber
151  | PartName
152  ;
153 
154  PartNameCopyNumber = PartName
155  >> CopyNumber
156  ;
157 
158  SelectionStep = NavigationalElement[isChildFtor()]
159  >> Part
160  ;
161 
162  NavigationalElement = Descendant
163  | Child
164  ;
165 
166  CopyNumber = ch_p('[')
167  >> int_p[copyNoFtor()]
168  >> ch_p(']')
169  ;
170 
171  PartName = NameSpaceName
172  | SimpleName[nameFtor()][&noNameSpace]
173  ;
174 
175  SimpleName = +( alnum_p | ch_p('_') | ch_p('.') | ch_p('*') )
176  ;
177 
178  NameSpaceName = SimpleName[nameSpaceFtor()]
179  >> ':'
180  >> SimpleName[nameFtor()]
181  ;
182 
183  Descendant = ch_p('/')
184  >> ch_p('/')
185  ;
186 
187  Child = ch_p('/')
188  ;
189 
190  }
191 
192  rule<ScannerT> Selection, FirstStep, Part, SelectionStep, NavigationalElement,
193  CopyNumber, PartName, PartNameCopyNumber, NameSpaceName, SimpleName,
194  Descendant, Child;
195 
196  rule<ScannerT> const& start() const { return Selection; }
197 
200  }
201 
203  static DDNameFtor f_;
204  return f_;
205  }
206 
208  static DDNameSpaceFtor f_;
209  return f_;
210  }
211 
213  static DDIsChildFtor f_;
214  return f_;
215  }
216 
218  static DDCopyNoFtor f_;
219  return f_;
220  }
221  };
222 
223 };
224 
225 
226 /*
227 std::ostream & operator<<(std::ostream & os, const DDPartSelection & ps)
228 {
229  DDPartSelection::const_iterator it = ps.begin();
230  for (; it != ps.end(); ++it) {
231  std::string s;
232  switch (it->selectionType_) {
233  case ddunknown: case ddanynode: case ddanychild:
234  os << "*ERROR*";
235  break;
236  case ddanylogp:
237  os << "//" << it->lp_.ddname();
238  break;
239  case ddanyposp:
240  os << "//" << it->lp_.ddname() << '[' << it->copyno_ << ']';
241  break;
242  case ddchildlogp:
243  os << "/" << it->lp_.ddname();
244  break;
245  case ddchildposp:
246  os << "/" << it->lp_.ddname() << '[' << it->copyno_ << ']';
247  break;
248  }
249 
250  }
251  return os;
252 }
253 */
254 
256  : lp_(lp), copyno_(c), selectionType_(t)
257 {
258 
259 }
260 
261 
262 
263 void DDTokenize2(const std::string & sel, std::vector<DDPartSelRegExpLevel> & path)
264 {
265  static SpecParParser parser;
267  bool result = parse(sel.c_str(), parser).full;
268  if (!result) {
269  edm::LogError("DDPartSelection") << "DDTokenize2() error in parsing of " << sel << std::endl;
270  }
271 }
272 
273 // uhhhhhhhhhhhhhhhh! Spaghetti code!!!!!!!!! (or worse?)
274 // FIXME: DDTokenize: if a LogicalPart is not yet defined during parsing of a SpecPar
275 // FIXME: (ddunknown is then the corresponding ddselection_type of the PartSelection)
276 // FIXME: then set a state-variable to 'undefined' .
277 // FIXME: After parsing, reprocess all undefined SpecPars ...
278 void DDTokenize(const std::string & sel, std::vector<DDPartSelRegExpLevel> & path)
279 {
280 
281 
282  static bool isInit(false);
283  static std::vector<std::string> tokens;
284  if(!isInit) {
285  // initialize with valid tokens
286  tokens.push_back("/");
287  tokens.push_back("//");
288  tokens.push_back("[");
289  tokens.push_back("]");
290  }
291  std::string s = sel;
292  std::string::size_type st = std::string::npos;
293  std::string::size_type cu = 0;
294  std::vector<std::string> toksVec;
295  std::vector<std::string> textVec;
296  std::string tkn, txt;
297  bool braceOpen(false);
298  /*
299  the following code should decompose a selection std::string into 2 std::vectors,
300  a token-std::vector and a text-std::vector. Tokens are /,//,[,]
301  example: "//Abc[3]/Def" ->
302  tokens text
303  // ""
304  [ Abc
305  ] 3
306  / ""
307  "Def"
308  */
309 
310  while (s.size()) {
311  std::vector<std::string>::iterator tkit = tokens.begin();
312  std::vector<std::string>::iterator mint = tokens.end();
313  st=s.size();
315  for(;tkit!=tokens.end();++tkit) { // find the first match of one of the token std::strings
316  ts = s.find(*tkit);
317  if (ts<=st) {
318  st=ts;
319  mint = tkit;
320  }
321  }
322 
323  if (mint!=tokens.end())
324  tkn = s.substr(st,mint->size());
325  else
326  tkn="";
327  txt = s.substr(cu,st);
328  toksVec.push_back(tkn);
329  textVec.push_back(txt);
330  if (braceOpen) {
331  if (tkn!="]")
332  throw cms::Exception("DDException") << "PartSelector: syntaxerror in " << sel
333  << "\ncheck the braces!";
334  else
335  braceOpen=false;
336  }
337  if (tkn=="[")
338  braceOpen=true;
339  DCOUT_V('C',"tkn=" << tkn << " txt=" << txt);
340  if (mint!=tokens.end())
341  s.erase(cu,st+mint->size());
342  else
343  s.erase();
344  DCOUT_V('C', std::endl << "s=" << s);
345  //break;
346  }
347  DCOUT_V('C', "The original std::string was:" << std::endl);
348  unsigned int i=0;
349  DCOUT_V('C', "toks\ttext");
350  for (i=0; i<toksVec.size();++i) {
351  DCOUT_V('C', toksVec[i] << "\t" << textVec[i]);
352  }
353  DCOUT_V('C', std::endl);
354 
355  // now some spaghetti code
356  std::string nm = "blabla" ; // std::string("PartSelector=") + ns() + std::string(":") + name();
357  if (textVec[0] != "")
358  throw cms::Exception("DDException") << nm << " selection must not start with a LogicalPart-name";
359 
360  if ((toksVec[0] != "//"))
361  throw cms::Exception("DDException") << nm << " selection must start with '//' !";
362 
363  if (textVec.size() < 2)
364  throw cms::Exception("DDException") << nm << " internal error [textVec.size()<2]!";
365 
366  std::vector<std::string>::iterator tk_it = toksVec.begin();
367  std::vector<std::string>::iterator tx_it = textVec.begin(); ++tx_it;
368  // the BIG switch - yes, this is OO!!!
369  while(tk_it != toksVec.end() && tx_it != textVec.end()) {
370 
371  // anynode ... token //* makes no sense (except as last entry which is forbidden ...)
372  DCOUT_V('C', ">- anynode tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
373  if ( *tk_it == "//" && *tx_it=="*" ) {
374  path.push_back(DDPartSelRegExpLevel("","",0,ddanynode));
375  DCOUT_V('C', "--anynode: //*" << std::endl);
376  ++tk_it;
377  ++tx_it;
378  continue;
379  }
380 
381  // anychild
382  DCOUT_V('C', ">- anychild tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
383  if ( *tk_it == "/" && *tx_it=="*" ) {
384  path.push_back(DDPartSelRegExpLevel("","",0,ddanychild));
385  DCOUT_V('C', "--anychild: /*" << std::endl);
386  ++tk_it;
387  ++tx_it;
388  continue;
389  }
390 
391  // anylogp
392  DCOUT_V('C', ">- anylogp tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
393  if ( *tk_it == "//" && tx_it->size()) {
394  ++tk_it;
395  if ( tk_it != toksVec.end() && *tk_it != "[" && *tk_it != "]") {
396  std::pair<std::string,std::string> p(DDSplit(*tx_it));
397  path.push_back(DDPartSelRegExpLevel(p.second,p.first,0,ddanylogp));
398  DCOUT_V('C', "--anylogp: " << *tx_it << std::endl);
399  ++tx_it;
400  continue;
401  }
402  --tk_it;
403  }
404 
405  // childlogp
406  DCOUT_V('C', ">- childlogp tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
407  if ( *tk_it == "/" && tx_it->size()) {
408  ++tk_it;
409  if ( tk_it == toksVec.end() - 1 ) {
410  DCOUT_V('C', "--childlogp: " << *tx_it << std::endl);
411  std::pair<std::string,std::string> p(DDSplit(*tx_it));
412  path.push_back(DDPartSelRegExpLevel(p.second,p.first,0,ddchildlogp));
413  ++tx_it;
414  continue;
415  }
416  if ( *tk_it == "/" || *tk_it=="//") {
417  DCOUT_V('C', "--childlogp: " << *tx_it << std::endl);
418  std::pair<std::string,std::string> p(DDSplit(*tx_it));
419  path.push_back(DDPartSelRegExpLevel(p.second,p.first,0,ddchildlogp));
420  ++tx_it;
421  continue;
422  }
423  --tk_it;
424  }
425 
426 
427  // anyposp
428  DCOUT_V('C', ">- anyposp tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
429  if ( *tk_it == "//" && tx_it->size()) {
430  ++tk_it;
431  if ( tk_it != toksVec.end() && *tk_it == "[" ) {
432  ++tk_it;
433  if ( tk_it == toksVec.end() || (tk_it != toksVec.end() && *tk_it != "]")) {
434  DCOUT_V('C', *tk_it << " " << *tx_it );
435  break;
436  }
437  ++tx_it;
438  ++tk_it;
439  std::pair<std::string,std::string> p(DDSplit(*(tx_it-1)));
440  path.push_back(DDPartSelRegExpLevel(p.second,p.first,atoi(tx_it->c_str()),ddanyposp));
441  DCOUT_V('C', "--anyposp: " << *tx_it << " " << atoi(tx_it->c_str()) << std::endl);
442  ++tx_it;
443  ++tx_it;
444  continue;
445  }
446  }
447 
448 
449  // childposp
450  DCOUT_V('C', ">- childposp tkn=" << *tk_it << " d=" << tk_it-toksVec.begin() << " txt=" << *tx_it << std::endl);
451  if ( *tk_it == "/" && tx_it->size()) {
452  ++tk_it;
453  if ( tk_it != toksVec.end() && *tk_it=="[" ) {
454  DCOUT_V('C', "--childposp: " << *tx_it << " " << *tk_it << *(tx_it+1) << std::endl);
455  std::pair<std::string,std::string> p(DDSplit(*tx_it));
456  path.push_back(DDPartSelRegExpLevel(p.second,p.first,atoi((tx_it+1)->c_str()),ddchildposp));
457 
458  ++tx_it;
459 
460  ++tx_it;
461  ++tk_it;
462  if (tk_it != toksVec.end() && *tk_it != "]")
463  break;
464  ++tk_it;
465  ++tx_it;
466  continue;
467  }
468  }
469 
470  // any
471  throw cms::Exception("DDException") << nm << " syntax error in:\n" << sel
472  << "\n tkn=" << *tk_it << " txt=" << *tx_it;
473  }
474  //FIXME: DDPartSelectorImpl::tokenize : prototype has restricted support for selection std::string (code below restricts)
475  ddselection_type tmp = path.back().selectionType_;
476  if (tmp==ddunknown || tmp==ddanynode || tmp==ddanychild )
477  throw cms::Exception("DDException") << "PartSelector: last element in selection std::string in " << sel
478  << "\nmust address a distinct LogicalPart or PosPart!";
479 }
480 
481 
482 std::ostream & operator<<(std::ostream & o, const DDPartSelection & p)
483 {
484  DDPartSelection::const_iterator it(p.begin()), ed(p.end());
485  for (; it != ed; ++it) {
486  const DDPartSelectionLevel lv =*it;
487  switch (lv.selectionType_) {
488  case ddanylogp:
489  o << "//" << lv.lp_.ddname();
490  break;
491  case ddanyposp:
492  o << "//" << lv.lp_.ddname() << '[' << lv.copyno_ << ']';
493  break;
494  case ddchildlogp:
495  o << "/" << lv.lp_.ddname();
496  break;
497  case ddchildposp:
498  o << "/" << lv.lp_.ddname() << '[' << lv.copyno_ << ']';
499  break;
500  default:
501  o << "{Syntax ERROR}";
502  }
503  }
504  return o;
505 }
506 
507 std::ostream & operator<<(std::ostream & os, const std::vector<DDPartSelection> & v)
508 {
509  std::vector<DDPartSelection>::const_iterator it(v.begin()), ed(v.end());
510  for (; it != (ed-1); ++it) {
511  os << *it << std::endl;
512  }
513  if ( it != ed ) {
514  ++it;
515  os << *it;
516  }
517  return os;
518 }
519 
520 // explicit template instantiation.
521 
522 template class DDI::Singleton<DDSelLevelFtor>;
523 //template class DDI::Singleton<DDI::Store<DDName, DDSelLevelCollector> >;
525 #include <DetectorDescription/Base/interface/Singleton.icc>
DDSelLevelFtor * selLevelFtor_
int i
Definition: DBlmapReader.cc:9
DDPartSelectionLevel(const DDLogicalPart &, int, ddselection_type)
void operator()(char const *first, char const *last) const
Evaluator * parse(const T &text)
static PFTauRenderPlugin instance
int mint[400]
void DDTokenize(const std::string &selectionString, std::vector< DDPartSelRegExpLevel > &result)
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:187
uint16_t size_type
void operator()(int i) const
DDIsChildFtor & isChildFtor()
static value_type & instance()
list path
Definition: scaleCards.py:51
void noNameSpace(char const *, char const *)
std::vector< DDPartSelRegExpLevel > * path(std::vector< DDPartSelRegExpLevel > *p=0)
ddselection_type
tuple result
Definition: query.py:137
definition(SpecParParser const &)
Definition: GenABIO.cc:193
void operator()(char const *first, char const *last) const
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
Definition: DDLogicalPart.h:88
ddselection_type selectionType_
bool first
Definition: L1TdeRCT.cc:94
DDSelLevelCollector & c_
rule< ScannerT > const & start() const
#define DCOUT_V(M_v_Y, M_v_S)
Definition: DDdebug.h:54
void DDTokenize2(const std::string &selectionString, std::vector< DDPartSelRegExpLevel > &result)
Templated helper class to allow a selection on a certain object collection.
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
void operator()(char const *first, char const *last) const
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:4
DDNameSpaceFtor & nameSpaceFtor()
mathSSE::Vec4< T > v
std::vector< DDPartSelRegExpLevel > * p_
DDSelLevelFtor & selLevelFtor()
const N & ddname() const
Definition: DDBase.h:84