File indexing completed on 2025-02-21 09:58:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #ifndef DD4HEP_GRAMMARPARSED_H
0022 #define DD4HEP_GRAMMARPARSED_H
0023
0024 #if defined(DD4HEP_GRAMMARUNPARSED_H)
0025 #error "The header files GrammarParsed.h and GrammarUnparsed.h may not be included in the same compilation unit!"
0026 #endif
0027
0028
0029 #include <DD4hep/Grammar.h>
0030 #include <DD4hep/Printout.h>
0031 #include <Parsers/Parsers.h>
0032 #include <Evaluator/Evaluator.h>
0033
0034
0035 #include <string>
0036 #include <sstream>
0037 #include <vector>
0038 #include <list>
0039 #include <set>
0040 #include <map>
0041 #include <deque>
0042
0043
0044
0045
0046 namespace dd4hep {
0047
0048
0049 namespace detail {
0050
0051 std::string grammar_pre_parse_map(const std::string& in);
0052 std::string grammar_pre_parse_cont(const std::string& in);
0053 std::string grammar_pre_parse_obj(const std::string& in);
0054 std::pair<int,double> grammar_evaluate_item(std::string val);
0055
0056
0057 template <typename TYPE> bool grammar_fromString(const BasicGrammar& gr, void* ptr, const std::string& val) {
0058 int sc = 0;
0059 TYPE temp;
0060 try {
0061 #ifdef DD4HEP_DEBUG_PROPERTIES
0062 std::cout << "Parsing " << val << std::endl;
0063 #endif
0064 sc = ::dd4hep::Parsers::parse(temp, val);
0065 if ( sc ) {
0066 *(TYPE*)ptr = std::move(temp);
0067 return true;
0068 }
0069 }
0070 catch (...) {
0071 }
0072 #ifdef DD4HEP_DEBUG_PROPERTIES
0073 std::cout << "Parsing " << val << "FAILED" << std::endl;
0074 #endif
0075 if ( !sc ) sc = gr.evaluate(&temp,val);
0076 #ifdef DD4HEP_DEBUG_PROPERTIES
0077 std::cout << "Sc=" << sc << " Converting value: " << val
0078 << " to type " << typeid(TYPE).name()
0079 << std::endl;
0080 #endif
0081 if ( sc ) {
0082 *(TYPE*)ptr = std::move(temp);
0083 return true;
0084 }
0085 BasicGrammar::invalidConversion(val, typeid(TYPE));
0086 return false;
0087 }
0088
0089
0090 template <typename TYPE> std::string grammar_str(const BasicGrammar&, const void* ptr) {
0091 std::stringstream string_rep;
0092 Parsers::toStream(*(TYPE*)ptr,string_rep);
0093 return string_rep.str();
0094 }
0095
0096
0097 template <typename T> inline int eval_item(T* ptr, const std::string& val) {
0098
0099 try {
0100 T temp;
0101 int sc = ::dd4hep::Parsers::parse(temp,val);
0102 if ( sc ) {
0103 *ptr = temp;
0104 return 1;
0105 }
0106 }
0107 catch (...) {
0108 }
0109
0110 auto result = grammar_evaluate_item(val);
0111 if (result.first == tools::Evaluator::OK) {
0112 *ptr = (T)result.second;
0113 return 1;
0114 }
0115
0116 return 0;
0117 }
0118
0119
0120 template <> inline int eval_item<std::string>(std::string* ptr, const std::string& val) {
0121 *ptr = val;
0122 return 1;
0123 }
0124
0125
0126 template <typename TYPE> static int fill_data(std::vector<TYPE>* p,const std::vector<std::string>& temp) {
0127 TYPE val;
0128 const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
0129 for(auto i=std::begin(temp); i != std::end(temp); ++i) {
0130 if ( !grammar.fromString(&val,*i) )
0131 return 0;
0132 p->emplace_back(val);
0133 }
0134 return 1;
0135 }
0136
0137
0138 template <typename TYPE> static int fill_data(std::list<TYPE>* p,const std::vector<std::string>& temp) {
0139 TYPE val;
0140 const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
0141 for(auto i=std::begin(temp); i != std::end(temp); ++i) {
0142 if ( !grammar.fromString(&val,*i) )
0143 return 0;
0144 p->emplace_back(val);
0145 }
0146 return 1;
0147 }
0148
0149
0150 template <typename TYPE> static int fill_data(std::set<TYPE>* p,const std::vector<std::string>& temp) {
0151 TYPE val;
0152 const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
0153 for(auto i=std::begin(temp); i != std::end(temp); ++i) {
0154 if ( !grammar.fromString(&val,*i) )
0155 return 0;
0156 p->emplace(val);
0157 }
0158 return 1;
0159 }
0160
0161
0162 template <typename TYPE> static int fill_data(std::deque<TYPE>* p,const std::vector<std::string>& temp) {
0163 TYPE val;
0164 const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
0165 for(auto i=std::begin(temp); i != std::end(temp); ++i) {
0166 if ( !grammar.fromString(&val,*i) )
0167 return 0;
0168 p->emplace_back(val);
0169 }
0170 return 1;
0171 }
0172
0173
0174 template <typename KEY, typename TYPE> static int fill_data(std::map<KEY,TYPE>* p,const std::vector<std::string>& temp) {
0175 std::pair<KEY,TYPE> val;
0176 const BasicGrammar& grammar = BasicGrammar::instance<std::pair<KEY,TYPE> >();
0177 for(auto i=std::begin(temp); i != std::end(temp); ++i) {
0178 if ( !grammar.fromString(&val,*i) )
0179 return 0;
0180 p->emplace(val);
0181 }
0182 return 1;
0183 }
0184
0185
0186 template <typename TYPE> static int eval_map(TYPE* p, const std::string& str) {
0187 std::vector<std::string> buff;
0188 p->clear();
0189 int sc = Parsers::parse(buff,str);
0190 if ( sc ) {
0191 return fill_data(p,buff);
0192 }
0193 else {
0194 TYPE temp;
0195 std::map<std::string,std::string> map_buff;
0196
0197 sc = 0;
0198 try {
0199 sc = ::dd4hep::Parsers::parse(map_buff,str);
0200 }
0201 catch(...) {
0202 }
0203 if ( !sc ) {
0204
0205 std::string temp_str = grammar_pre_parse_map(str);
0206 try {
0207 sc = ::dd4hep::Parsers::parse(map_buff,temp_str);
0208 }
0209 catch(...) {
0210 }
0211 }
0212 if ( sc ) {
0213 for(const auto& _o : map_buff ) {
0214 typename TYPE::key_type _k {};
0215 typename TYPE::mapped_type _v {};
0216 eval_item(&_k, _o.first);
0217 eval_item(&_v, _o.second);
0218 p->emplace(_k,_v);
0219 }
0220 return 1;
0221 }
0222 }
0223 return 0;
0224 }
0225
0226
0227 template <typename TYPE> static int eval_container(TYPE* p, const std::string& str) {
0228 std::vector<std::string> buff;
0229 int sc = Parsers::parse(buff,str);
0230 if ( sc ) {
0231 return fill_data(p,buff);
0232 }
0233 else {
0234 TYPE temp;
0235
0236 std::string temp_str = grammar_pre_parse_obj(str);
0237 sc = ::dd4hep::Parsers::parse(temp,temp_str);
0238 if ( sc ) {
0239 *p = std::move(temp);
0240 return 1;
0241 }
0242
0243 temp_str = grammar_pre_parse_cont(str);
0244 sc = ::dd4hep::Parsers::parse(temp,temp_str);
0245 if ( sc ) {
0246 *p = std::move(temp);
0247 return 1;
0248 }
0249 buff.clear();
0250 sc = Parsers::parse(buff,temp_str);
0251 if ( sc ) {
0252 return fill_data(p,buff);
0253 }
0254 }
0255 return 0;
0256 }
0257
0258
0259 template <typename T,typename Q> inline int eval_pair(std::pair<T,Q>* ptr, std::string str) {
0260 const BasicGrammar& grammar = BasicGrammar::instance<std::pair<T,Q> >();
0261 if ( !grammar.fromString(ptr,str) ) return 0;
0262 return 1;
0263 }
0264
0265
0266 template<typename T> inline int eval_obj(T* ptr, const std::string& str) {
0267 return BasicGrammar::instance<T>().fromString(ptr,grammar_pre_parse_obj(str));
0268 }
0269
0270 template<typename T> inline int grammar_eval(const BasicGrammar&, void*, const std::string&) { return 0; }
0271 }
0272
0273
0274 template <typename TYPE> const BasicGrammar& BasicGrammar::instance() {
0275 static Grammar<TYPE> *s_gr = 0;
0276 if ( 0 != s_gr ) {
0277 return *s_gr;
0278 }
0279 static Grammar<TYPE> gr;
0280 if ( 0 == gr.specialization.bind ) gr.specialization.bind = detail::constructObject<TYPE>;
0281 if ( 0 == gr.specialization.copy ) gr.specialization.copy = detail::copyObject<TYPE>;
0282 if ( 0 == gr.specialization.fromString ) {
0283 gr.specialization.fromString = detail::grammar_fromString<TYPE>;
0284 gr.specialization.eval = detail::grammar_eval<TYPE>;
0285 gr.specialization.str = detail::grammar_str<TYPE>;
0286 }
0287 s_gr = &gr;
0288 return *s_gr;
0289 }
0290 }
0291
0292 #define DD4HEP_PARSER_GRAMMAR_CNAME(serial,name) namespace_dd4hep__grammar_##serial##_##name
0293
0294 #define DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(xx,func) \
0295 namespace dd4hep { namespace detail { \
0296 template<> int grammar_eval<xx>(const BasicGrammar&, void* _p, const std::string& _v) { \
0297 return func ((xx*)_p,_v); \
0298 }}}
0299
0300
0301 #define DD4HEP_DEFINE_PARSER_GRAMMAR_INSTANCE(serial,xx) \
0302 namespace dd4hep { \
0303 template class Grammar< xx >; \
0304 template BasicGrammar const& BasicGrammar::instance< xx >(); \
0305 template const GrammarRegistry& GrammarRegistry::pre_note<xx>(int); \
0306 } \
0307 namespace DD4HEP_PARSER_GRAMMAR_CNAME(serial,0) { \
0308 static auto s_reg = ::dd4hep::GrammarRegistry::pre_note< xx >(1); \
0309 }
0310
0311 #define DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,ctxt,xx,func) \
0312 DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(xx,func) \
0313 DD4HEP_DEFINE_PARSER_GRAMMAR_INSTANCE(DD4HEP_PARSER_GRAMMAR_CNAME(serial,ctxt),xx)
0314
0315 #if defined(DD4HEP_HAVE_ALL_PARSERS)
0316 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_func) \
0317 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,x,eval_func) \
0318 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<xx>, eval_container) \
0319 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<xx>, eval_container) \
0320 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<xx>, eval_container) \
0321 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,std::deque<xx>, eval_container) \
0322 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<xx>::int_map_t, eval_container) \
0323 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<xx>::ulong_map_t, eval_container) \
0324 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<xx>::string_map_t, eval_container) \
0325 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,9,dd4hep::detail::Primitive<xx>::int_pair_t, eval_pair) \
0326 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,10,dd4hep::detail::Primitive<xx>::ulong_pair_t, eval_pair) \
0327 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,11,dd4hep::detail::Primitive<xx>::string_pair_t, eval_pair)
0328
0329 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(serial,xx,eval_func) \
0330 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,12,xx,eval_func) \
0331 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,13,std::vector<xx>,eval_container) \
0332 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,14,std::list<xx>,eval_container)
0333
0334 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(serial,xx) \
0335 DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_item) \
0336 DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,unsigned xx,eval_item)
0337
0338 #else
0339
0340 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_func) \
0341 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,xx,eval_func) \
0342 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<xx>, eval_container) \
0343 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<xx>, eval_container) \
0344 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<xx>, eval_container) \
0345 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,dd4hep::detail::Primitive<xx>::int_map_t, eval_map) \
0346 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<xx>::string_map_t, eval_map) \
0347 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<xx>::int_pair_t, eval_pair) \
0348 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<xx>::string_pair_t, eval_pair)
0349
0350 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_ROOTMATH(serial,xx,eval_func) \
0351 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,xx,eval_func) \
0352 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<xx>, eval_container) \
0353 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<xx>, eval_container) \
0354 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<xx>, eval_container) \
0355 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,dd4hep::detail::Primitive<xx>::int_map_t, eval_container) \
0356 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<xx>::string_map_t, eval_container) \
0357 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<xx>::int_pair_t, eval_pair) \
0358 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<xx>::string_pair_t, eval_pair)
0359
0360 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(serial,xx,eval_func) \
0361 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,9,xx,eval_func) \
0362 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,10,std::vector<xx>,eval_container) \
0363 DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,11,std::list<xx>,eval_container)
0364
0365 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(serial,xx) \
0366 DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_item)
0367
0368 #endif
0369
0370 #define DD4HEP_DEFINE_PARSER_GRAMMAR(xx,func) DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(__LINE__,__LINE__,xx,func)
0371 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(xx,eval_func) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(__LINE__,xx,eval_func)
0372 #define DD4HEP_DEFINE_PARSER_GRAMMAR_ROOTMATH(xx,eval_func) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_ROOTMATH(__LINE__,xx,eval_func)
0373 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(xx) DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(__LINE__,xx)
0374 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(xx,eval_func) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(__LINE__,xx,eval_func)
0375 #define DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY(xx,func) DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY_SERIAL(__LINE__,xx,func)
0376
0377 #endif