DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
GrammarParsed.h
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 //
14 // NOTE:
15 //
16 // This is an internal include file. It should only be included to
17 // instantiate code. Otherwise the BasicGrammar include file should be
18 // sufficient for all practical purposes.
19 //
20 //==========================================================================
21 #ifndef DD4HEP_GRAMMARPARSED_H
22 #define DD4HEP_GRAMMARPARSED_H
23 
24 #if defined(DD4HEP_GRAMMARUNPARSED_H)
25 #error "The header files GrammarParsed.h and GrammarUnparsed.h may not be included in the same compilation unit!"
26 #endif
27 
29 #include <DD4hep/Grammar.h>
30 #include <DD4hep/Printout.h>
31 #include <Parsers/Parsers.h>
32 #include <Evaluator/Evaluator.h>
33 
35 #include <string>
36 #include <sstream>
37 #include <vector>
38 #include <list>
39 #include <set>
40 #include <map>
41 #include <deque>
42 
43 // Forward declarations
44 
46 namespace dd4hep {
47 
49  namespace detail {
50 
51  std::string grammar_pre_parse_map(const std::string& in);
52  std::string grammar_pre_parse_cont(const std::string& in);
53  std::string grammar_pre_parse_obj(const std::string& in);
54  std::pair<int,double> grammar_evaluate_item(std::string val);
55 
57  template <typename TYPE> bool grammar_fromString(const BasicGrammar& gr, void* ptr, const std::string& val) {
58  int sc = 0;
59  TYPE temp;
60  try {
61 #ifdef DD4HEP_DEBUG_PROPERTIES
62  std::cout << "Parsing " << val << std::endl;
63 #endif
64  sc = ::dd4hep::Parsers::parse(temp, val);
65  if ( sc ) {
66  *(TYPE*)ptr = std::move(temp);
67  return true;
68  }
69  }
70  catch (...) {
71  }
72 #ifdef DD4HEP_DEBUG_PROPERTIES
73  std::cout << "Parsing " << val << "FAILED" << std::endl;
74 #endif
75  if ( !sc ) sc = gr.evaluate(&temp,val);
76 #ifdef DD4HEP_DEBUG_PROPERTIES
77  std::cout << "Sc=" << sc << " Converting value: " << val
78  << " to type " << typeid(TYPE).name()
79  << std::endl;
80 #endif
81  if ( sc ) {
82  *(TYPE*)ptr = std::move(temp);
83  return true;
84  }
85  BasicGrammar::invalidConversion(val, typeid(TYPE));
86  return false;
87  }
88 
90  template <typename TYPE> std::string grammar_str(const BasicGrammar&, const void* ptr) {
91  std::stringstream string_rep;
92  Parsers::toStream(*(TYPE*)ptr,string_rep);
93  return string_rep.str();
94  }
95 
97  template <typename T> inline int eval_item(T* ptr, const std::string& val) {
99  try {
100  T temp;
101  int sc = ::dd4hep::Parsers::parse(temp,val);
102  if ( sc ) {
103  *ptr = temp;
104  return 1;
105  }
106  }
107  catch (...) {
108  }
110  auto result = grammar_evaluate_item(val);
111  if (result.first == tools::Evaluator::OK) {
112  *ptr = (T)result.second;
113  return 1;
114  }
116  return 0;
117  }
118 
120  template <> inline int eval_item<std::string>(std::string* ptr, const std::string& val) {
121  *ptr = val;
122  return 1;
123  }
124 
126  template <typename TYPE> static int fill_data(std::vector<TYPE>* p,const std::vector<std::string>& temp) {
127  TYPE val;
128  const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
129  for(auto i=std::begin(temp); i != std::end(temp); ++i) {
130  if ( !grammar.fromString(&val,*i) )
131  return 0;
132  p->emplace_back(val);
133  }
134  return 1;
135  }
136 
138  template <typename TYPE> static int fill_data(std::list<TYPE>* p,const std::vector<std::string>& temp) {
139  TYPE val;
140  const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
141  for(auto i=std::begin(temp); i != std::end(temp); ++i) {
142  if ( !grammar.fromString(&val,*i) )
143  return 0;
144  p->emplace_back(val);
145  }
146  return 1;
147  }
148 
150  template <typename TYPE> static int fill_data(std::set<TYPE>* p,const std::vector<std::string>& temp) {
151  TYPE val;
152  const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
153  for(auto i=std::begin(temp); i != std::end(temp); ++i) {
154  if ( !grammar.fromString(&val,*i) )
155  return 0;
156  p->emplace(val);
157  }
158  return 1;
159  }
160 
162  template <typename TYPE> static int fill_data(std::deque<TYPE>* p,const std::vector<std::string>& temp) {
163  TYPE val;
164  const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
165  for(auto i=std::begin(temp); i != std::end(temp); ++i) {
166  if ( !grammar.fromString(&val,*i) )
167  return 0;
168  p->emplace_back(val);
169  }
170  return 1;
171  }
172 
174  template <typename KEY, typename TYPE> static int fill_data(std::map<KEY,TYPE>* p,const std::vector<std::string>& temp) {
175  std::pair<KEY,TYPE> val;
176  const BasicGrammar& grammar = BasicGrammar::instance<std::pair<KEY,TYPE> >();
177  for(auto i=std::begin(temp); i != std::end(temp); ++i) {
178  if ( !grammar.fromString(&val,*i) )
179  return 0;
180  p->emplace(val);
181  }
182  return 1;
183  }
184 
186  template <typename TYPE> static int eval_map(TYPE* p, const std::string& str) {
187  std::vector<std::string> buff;
188  p->clear();
189  int sc = Parsers::parse(buff,str);
190  if ( sc ) {
191  return fill_data(p,buff);
192  }
193  else {
194  TYPE temp;
195  std::map<std::string,std::string> map_buff;
196  // If we get called from python, the values and keys are already in string form
197  sc = 0;
198  try {
199  sc = ::dd4hep::Parsers::parse(map_buff,str);
200  }
201  catch(...) {
202  }
203  if ( !sc ) {
204  // Otherwise stringyfy the values
205  std::string temp_str = grammar_pre_parse_map(str);
206  try {
207  sc = ::dd4hep::Parsers::parse(map_buff,temp_str);
208  }
209  catch(...) {
210  }
211  }
212  if ( sc ) {
213  for(const auto& _o : map_buff ) {
214  typename TYPE::key_type _k {};
215  typename TYPE::mapped_type _v {};
216  eval_item(&_k, _o.first);
217  eval_item(&_v, _o.second);
218  p->emplace(_k,_v);
219  }
220  return 1;
221  }
222  }
223  return 0;
224  }
225 
227  template <typename TYPE> static int eval_container(TYPE* p, const std::string& str) {
228  std::vector<std::string> buff;
229  int sc = Parsers::parse(buff,str);
230  if ( sc ) {
231  return fill_data(p,buff);
232  }
233  else {
234  TYPE temp;
236  std::string temp_str = grammar_pre_parse_obj(str);
237  sc = ::dd4hep::Parsers::parse(temp,temp_str);
238  if ( sc ) {
239  *p = std::move(temp);
240  return 1;
241  }
243  temp_str = grammar_pre_parse_cont(str);
244  sc = ::dd4hep::Parsers::parse(temp,temp_str);
245  if ( sc ) {
246  *p = std::move(temp);
247  return 1;
248  }
249  buff.clear();
250  sc = Parsers::parse(buff,temp_str);
251  if ( sc ) {
252  return fill_data(p,buff);
253  }
254  }
255  return 0;
256  }
257 
259  template <typename T,typename Q> inline int eval_pair(std::pair<T,Q>* ptr, std::string str) {
260  const BasicGrammar& grammar = BasicGrammar::instance<std::pair<T,Q> >();
261  if ( !grammar.fromString(ptr,str) ) return 0;
262  return 1;
263  }
264 
266  template<typename T> inline int eval_obj(T* ptr, const std::string& str) {
267  return BasicGrammar::instance<T>().fromString(ptr,grammar_pre_parse_obj(str));
268  }
269 
270  template<typename T> inline int grammar_eval(const BasicGrammar&, void*, const std::string&) { return 0; }
271  }
272 
274  template <typename TYPE> const BasicGrammar& BasicGrammar::instance() {
275  static Grammar<TYPE> *s_gr = 0;
276  if ( 0 != s_gr ) {
277  return *s_gr;
278  }
279  static Grammar<TYPE> gr;
280  if ( 0 == gr.specialization.bind ) gr.specialization.bind = detail::constructObject<TYPE>;
281  if ( 0 == gr.specialization.copy ) gr.specialization.copy = detail::copyObject<TYPE>;
282  if ( 0 == gr.specialization.fromString ) {
283  gr.specialization.fromString = detail::grammar_fromString<TYPE>;
284  gr.specialization.eval = detail::grammar_eval<TYPE>;
285  gr.specialization.str = detail::grammar_str<TYPE>;
286  }
287  s_gr = &gr;
288  return *s_gr;
289  }
290 } // End namespace dd4hep
291 
292 #define DD4HEP_PARSER_GRAMMAR_CNAME(serial,name) namespace_dd4hep__grammar_##serial##_##name
293 
294 #define DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(xx,func) \
295  namespace dd4hep { namespace detail { \
296  template<> int grammar_eval<xx>(const BasicGrammar&, void* _p, const std::string& _v) { \
297  return func ((xx*)_p,_v); \
298  }}}
299 
300 
301 #define DD4HEP_DEFINE_PARSER_GRAMMAR_INSTANCE(serial,xx) \
302  namespace dd4hep { \
303  template class Grammar< xx >; \
304  template BasicGrammar const& BasicGrammar::instance< xx >(); \
305  template const GrammarRegistry& GrammarRegistry::pre_note<xx>(int); \
306  } \
307  namespace DD4HEP_PARSER_GRAMMAR_CNAME(serial,0) { \
308  static auto s_reg = ::dd4hep::GrammarRegistry::pre_note< xx >(1); \
309  }
310 
311 #define DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,ctxt,xx,func) \
312  DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(xx,func) \
313  DD4HEP_DEFINE_PARSER_GRAMMAR_INSTANCE(DD4HEP_PARSER_GRAMMAR_CNAME(serial,ctxt),xx)
314 
315 #if defined(DD4HEP_HAVE_ALL_PARSERS)
316 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_func) \
317  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,x,eval_func) \
318  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<xx>, eval_container) \
319  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<xx>, eval_container) \
320  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<xx>, eval_container) \
321  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,std::deque<xx>, eval_container) \
322  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<xx>::int_map_t, eval_container) \
323  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<xx>::ulong_map_t, eval_container) \
324  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<xx>::string_map_t, eval_container) \
325  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,9,dd4hep::detail::Primitive<xx>::int_pair_t, eval_pair) \
326  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,10,dd4hep::detail::Primitive<xx>::ulong_pair_t, eval_pair) \
327  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,11,dd4hep::detail::Primitive<xx>::string_pair_t, eval_pair)
328 
329 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(serial,xx,eval_func) \
330  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,12,xx,eval_func) \
331  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,13,std::vector<xx>,eval_container) \
332  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,14,std::list<xx>,eval_container)
333 
334 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(serial,xx) \
335  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_item) \
336  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,unsigned xx,eval_item)
337 
338 #else
339 
340 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_func) \
341  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,xx,eval_func) \
342  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<xx>, eval_container) \
343  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<xx>, eval_container) \
344  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<xx>, eval_container) \
345  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,dd4hep::detail::Primitive<xx>::int_map_t, eval_map) \
346  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<xx>::string_map_t, eval_map) \
347  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<xx>::int_pair_t, eval_pair) \
348  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<xx>::string_pair_t, eval_pair)
349 
350 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_ROOTMATH(serial,xx,eval_func) \
351  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,xx,eval_func) \
352  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<xx>, eval_container) \
353  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<xx>, eval_container) \
354  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<xx>, eval_container) \
355  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,dd4hep::detail::Primitive<xx>::int_map_t, eval_container) \
356  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<xx>::string_map_t, eval_container) \
357  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<xx>::int_pair_t, eval_pair) \
358  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<xx>::string_pair_t, eval_pair)
359 
360 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(serial,xx,eval_func) \
361  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,9,xx,eval_func) \
362  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,10,std::vector<xx>,eval_container) \
363  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,11,std::list<xx>,eval_container)
364 
365 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(serial,xx) \
366  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_item)
367 
368 #endif
369 
370 #define DD4HEP_DEFINE_PARSER_GRAMMAR(xx,func) DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(__LINE__,__LINE__,xx,func)
371 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(xx,eval_func) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(__LINE__,xx,eval_func)
372 #define DD4HEP_DEFINE_PARSER_GRAMMAR_ROOTMATH(xx,eval_func) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_ROOTMATH(__LINE__,xx,eval_func)
373 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(xx) DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(__LINE__,xx)
374 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(xx,eval_func) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(__LINE__,xx,eval_func)
375 #define DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY(xx,func) DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY_SERIAL(__LINE__,xx,func)
376 
377 #endif // DD4HEP_GRAMMARPARSED_H
dd4hep::BasicGrammar::evaluate
virtual int evaluate(void *ptr, const std::string &value) const
Evaluate string value if possible before calling boost::spirit.
Definition: Grammar.cpp:278
dd4hep::detail::grammar_pre_parse_cont
std::string grammar_pre_parse_cont(const std::string &in)
Helper function to parse data type.
Definition: Grammar.cpp:367
dd4hep::BasicGrammar::specialization_t::copy
void(* copy)(void *to, const void *from)=0
Opaque copy constructor.
Definition: Grammar.h:78
dd4hep::Grammar
Concrete type dependent grammar definition.
Definition: Grammar.h:167
dd4hep::BasicGrammar::fromString
virtual bool fromString(void *ptr, const std::string &value) const
Set value from serialized string. On successful data conversion TRUE is returned.
Definition: Grammar.cpp:269
dd4hep::detail::eval_pair
int eval_pair(std::pair< T, Q > *ptr, std::string str)
Item evaluator.
Definition: GrammarParsed.h:259
dd4hep::detail::grammar_fromString
bool grammar_fromString(const BasicGrammar &gr, void *ptr, const std::string &val)
PropertyGrammar overload: Retrieve value from string.
Definition: GrammarParsed.h:57
dd4hep::detail::grammar_pre_parse_map
std::string grammar_pre_parse_map(const std::string &in)
Helper function to parse data type.
Definition: Grammar.cpp:297
dd4hep::xml::parse
void parse(Handle_t e, RotationZYX &rot)
Convert rotation XML objects to dd4hep::RotationZYX.
Definition: XMLParsers.cpp:48
dd4hep::BasicGrammar::instance
static const BasicGrammar & instance()
Instance factory.
Definition: GrammarParsed.h:274
dd4hep::BasicGrammar::specialization_t::fromString
bool(* fromString)(const BasicGrammar &gr, void *ptr, const std::string &value)=0
PropertyGrammar overload: Retrieve value from string.
Definition: Grammar.h:82
dd4hep::detail::grammar_evaluate_item
std::pair< int, double > grammar_evaluate_item(std::string val)
Helper to parse single item.
Definition: Grammar.cpp:286
dd4hep::BasicGrammar
Base class describing string evaluation to C++ objects using boost::spirit.
Definition: Grammar.h:56
dd4hep::Parsers::toStream
std::ostream & toStream(const Property &result, std::ostream &os)
Definition: ComponentProperties.cpp:191
dd4hep::Parsers::parse
int parse(Property &result, const std::string &input)
Definition: ComponentProperties.cpp:187
dd4hep::BasicGrammar::specialization_t::eval
int(* eval)(const BasicGrammar &gr, void *ptr, const std::string &val)=0
Evaluate string value if possible before calling boost::spirit.
Definition: Grammar.h:84
dd4hep::detail::grammar_eval
int grammar_eval(const BasicGrammar &, void *, const std::string &)
Definition: GrammarParsed.h:270
dd4hep::BasicGrammar::specialization_t::bind
void(* bind)(void *pointer)=0
Bind opaque address to object.
Definition: Grammar.h:76
dd4hep::BasicGrammar::specialization_t::str
std::string(* str)(const BasicGrammar &gr, const void *ptr)=0
PropertyGrammar overload: Serialize a property to a string.
Definition: Grammar.h:80
dd4hep::BasicGrammar::specialization
struct dd4hep::BasicGrammar::specialization_t specialization
dd4hep::detail::grammar_str
std::string grammar_str(const BasicGrammar &, const void *ptr)
Serialize a property to a string.
Definition: GrammarParsed.h:90
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::detail::grammar_pre_parse_obj
std::string grammar_pre_parse_obj(const std::string &in)
Helper function to parse data type.
Definition: Grammar.cpp:427
dd4hep::detail::eval_obj
int eval_obj(T *ptr, const std::string &str)
Object evaluator.
Definition: GrammarParsed.h:266
dd4hep::BasicGrammar::invalidConversion
static void invalidConversion(const std::type_info &from, const std::type_info &to)
Error callback on invalid conversion.
Definition: Grammar.cpp:238
dd4hep::detail::eval_item
int eval_item(T *ptr, const std::string &val)
Item evaluator.
Definition: GrammarParsed.h:97
Printout.h
Grammar.h