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