The Gaudi Framework  master (e68eea06)
Loading...
Searching...
No Matches
Grammars.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11
12// cppcheck-suppress-file useInitializationList; for consistency
13
14#pragma once
15
16#ifdef __GNUC__
17# pragma GCC system_header
18#endif
19
25#include <list>
26#include <map>
27#include <set>
28#include <string>
29#include <tuple>
30#include <unordered_map>
31#include <unordered_set>
32#include <vector>
33
34#include <boost/fusion/include/std_pair.hpp>
35#if ( BOOST_VERSION >= 187000 ) && ( BOOST_VERSION < 188000 )
36# define BOOST_ALLOW_DEPRECATED_HEADERS
37#endif
38#include <boost/spirit/include/qi.hpp>
39#undef BOOST_ALLOW_DEPRECATED_HEADERS
40
41#include <boost/fusion/adapted/std_tuple.hpp>
42#include <boost/phoenix/bind.hpp>
43#include <boost/phoenix/core.hpp>
44#include <boost/phoenix/operator.hpp>
45#include <boost/spirit/repository/include/qi_confix.hpp>
46
47namespace Gaudi::Parsers {
48 namespace sp = boost::spirit;
49 namespace ph = boost::phoenix;
50 namespace qi = sp::qi;
51 namespace enc = sp::ascii;
52 namespace rep = sp::repository;
53
54 template <typename Iterator, typename T, typename Skipper, class Enable = void>
55 struct Grammar_ {
56 /* READ THIS IF YOUR COMPILE BREAKS ON THE FOLLOWING LINE
57 *
58 * To users: You have to ask developers to implement parser for your type T
59 * To developer: You have to implement and register Grammar for type T
60 *
61 */
62 BOOST_MPL_ASSERT_MSG( false, GRAMMAR_FOR_TYPE_DOES_NOT_EXISTS, ( T ) );
63 };
64
65#define REGISTER_GRAMMAR( ResultType, GrammarName ) \
66 template <typename Iterator, typename Skipper> \
67 struct Grammar_<Iterator, ResultType, Skipper> { \
68 using Grammar = GrammarName<Iterator, Skipper>; \
69 }
70
71 template <typename Iterator>
72 struct SkipperGrammar : qi::grammar<Iterator> {
73 qi::rule<Iterator> comments;
75 comments = enc::space | rep::confix( "/*", "*/" )[*( qi::char_ - "*/" )] |
76 rep::confix( "//", ( sp::eol | sp::eoi ) )[*( qi::char_ - ( sp::eol | sp::eoi ) )];
77 }
78 };
79
80 template <typename It, typename Skipper>
81 struct StringGrammar : qi::grammar<It, std::string(), Skipper> {
82 qi::rule<It, std::string()> dq_body, sq_body;
83 qi::rule<It, std::string(), Skipper> str;
84 StringGrammar() : StringGrammar::base_type( str ) {
85 dq_body = qi::eps[qi::_val = std::string{}] >> *( ( qi::lit( '\\' ) >> qi::char_( '"' ) )[qi::_val += '"'] |
86 ( qi::lit( '\\' ) >> qi::char_( '\\' ) )[qi::_val += '\\'] |
87 ( qi::char_ - qi::char_( '"' ) )[qi::_val += qi::_1] );
88 sq_body = qi::eps[qi::_val = std::string{}] >> *( ( qi::lit( '\\' ) >> qi::char_( '\'' ) )[qi::_val += '\''] |
89 ( qi::lit( '\\' ) >> qi::char_( '\\' ) )[qi::_val += '\\'] |
90 ( qi::char_ - qi::char_( '\'' ) )[qi::_val += qi::_1] );
91 str = qi::lexeme[rep::confix( '"', '"' )[dq_body] | rep::confix( '\'', '\'' )[sq_body]];
92 }
93 };
96
97 template <typename Iterator, typename Skipper>
98 struct CharGrammar : qi::grammar<Iterator, char(), Skipper> {
99 using ResultT = char;
100 qi::rule<Iterator, char(), Skipper> ch;
101 CharGrammar() : CharGrammar::base_type( ch ) { ch = qi::int_parser<char>() | '\'' >> ( qi::char_ - '\'' ) >> '\''; }
102 };
104
105 template <typename Iterator, typename Skipper>
106 struct BoolGrammar : qi::grammar<Iterator, bool(), Skipper> {
107 qi::symbols<char, bool> kw;
108 qi::rule<Iterator, bool(), Skipper> boolean_literal;
109
111 kw.add( "true", true )( "True", true )( "TRUE", true )( "1", true )( "false", false )( "False", false )(
112 "FALSE", false )( "0", false );
114 }
115 };
117
118 template <typename Iterator, typename RT, typename Skipper>
119 struct IntGrammar : qi::grammar<Iterator, RT(), Skipper> {
120 using ResultT = RT;
121 IntGrammar() : IntGrammar::base_type( integer ) {
122 integer = qi::int_parser<RT>()[qi::_val = qi::_1] >> -qi::no_case[qi::char_( 'L' )];
123 }
124 qi::rule<Iterator, RT(), Skipper> integer;
125 };
126
127 template <typename Iterator, std::integral T, typename Skipper>
128 struct Grammar_<Iterator, T, Skipper> {
130 };
131
132 template <typename Iterator, typename RT, typename Skipper>
133 struct RealGrammar : qi::grammar<Iterator, RT(), Skipper> {
134 using ResultT = RT;
135 RealGrammar() : RealGrammar::base_type( real ) { real = qi::real_parser<RT>(); }
136 qi::rule<Iterator, RT(), Skipper> real;
137 };
138
139 template <typename Iterator, std::floating_point T, typename Skipper>
143
144 template <typename It, typename Skipper, typename... Ts>
145 struct TupleGrammar : qi::grammar<It, std::tuple<Ts...>(), Skipper> {
146 static_assert( sizeof...( Ts ) > 0, "Tuple must have at least one element" );
147 std::tuple<typename Grammar_<It, Ts, Skipper>::Grammar...> elems{};
148 qi::rule<It, std::tuple<Ts...>(), Skipper> body;
149 qi::rule<It, std::tuple<Ts...>(), Skipper> tuple;
150 TupleGrammar() : TupleGrammar::base_type( tuple ) { init( std::make_index_sequence<sizeof...( Ts ) - 1>{} ); }
151
152 private:
153 template <std::size_t... Is>
154 void init( std::index_sequence<Is...> ) {
155 if constexpr ( sizeof...( Is ) == 0 ) {
156 body = get<0>( elems ) >> -qi::lit( ',' );
157 } else {
158 body = get<0>( elems ) >> ( ( qi::lit( ',' ) >> get<Is + 1>( elems ) ) >> ... ) >> -qi::lit( ',' );
159 }
160 tuple = rep::confix( '(', ')' )[body] | rep::confix( '[', ']' )[body];
161 }
162 };
163
164 // Expose via the expected alias for backwards compatibility
165 template <typename Iterator, typename Skipper, typename... Ts>
166 struct Grammar_<Iterator, std::tuple<Ts...>, Skipper> {
168 };
169
170 template <typename Iterator, typename VectorT, typename Skipper>
171 struct VectorGrammar : qi::grammar<Iterator, VectorT(), Skipper> {
172 using ResultT = VectorT;
173 using value_type = typename VectorT::value_type;
176 qi::rule<Iterator, Skipper> trailing_commas;
179 VectorGrammar() : VectorGrammar::base_type( vec ) {
180 list = element % ',';
181 trailing_commas = qi::omit[*enc::char_( ',' )];
183 vec = rep::confix( '(', ')' )[body] | rep::confix( '[', ']' )[body] | rep::confix( '{', '}' )[body];
184 }
185 };
186
187 template <typename Iterator, typename InnerT, typename AllocatorT, typename Skipper>
191
192 template <typename Iterator, typename InnerT, typename AllocatorT, typename Skipper>
196
197 template <typename Iterator, typename InnerT, typename CompareT, typename AllocatorT, typename Skipper>
201
202 template <typename Iterator, typename SetT, typename Skipper>
203 struct SetGrammar : qi::grammar<Iterator, SetT(), qi::locals<char>, Skipper> {
204 SetGrammar() : SetGrammar::base_type( set ) {
205 // special handling of empty set as "{}" is always a dict
206 set = qi::lit( "set()" ) | grVector;
207 }
209 qi::rule<Iterator, SetT(), qi::locals<char>, Skipper> set;
210 };
211
212 template <typename Iterator, typename InnerT, typename HashT, typename CompareT, typename AllocatorT,
213 typename Skipper>
214 struct Grammar_<Iterator, std::unordered_set<InnerT, HashT, CompareT, AllocatorT>, Skipper> {
216 };
217
218 template <typename Iterator, typename PairT, typename Skipper, char Delim = ','>
219 struct PairGrammar : qi::grammar<Iterator, PairT(), Skipper> {
222 qi::rule<Iterator, PairT(), Skipper> kv;
223 qi::rule<Iterator, PairT(), Skipper> pair;
224 PairGrammar() : PairGrammar::base_type( pair ) {
225 kv = key >> qi::lit( Delim ) >> val;
226 pair = rep::confix( '(', ')' )[kv] | rep::confix( '[', ']' )[kv];
227 }
228 };
229
230 template <typename Iterator, typename KeyT, typename ValueT, typename Skipper>
234
235 template <typename It, typename MapT, typename Skipper>
236 struct MapGrammar : qi::grammar<It, MapT(), Skipper> {
237 using KeyT = typename MapT::key_type;
238 using MappedT = typename MapT::mapped_type;
239 using PairT = std::pair<KeyT, MappedT>;
240
243
244 qi::rule<It, PairT(), Skipper> kv;
245 qi::rule<It, std::vector<PairT>(), Skipper> body;
246 qi::rule<It, std::vector<PairT>(), Skipper> bracketed;
247 qi::rule<It, MapT(), Skipper> map;
248
249 MapGrammar() : MapGrammar::base_type( map ) {
250 kv = key >> ( qi::lit( ':' ) | qi::lit( '=' ) ) >> val;
251 body = -( kv % ',' ) >> qi::omit[*enc::char_( ',' )];
252 bracketed = rep::confix( '[', ']' )[body] | rep::confix( '{', '}' )[body];
253 map = bracketed;
254 }
255 };
256
257 template <typename Iterator, typename KeyT, typename ValueT, typename KeyCompareT, typename AllocatorT,
258 typename Skipper>
259 struct Grammar_<Iterator, std::map<KeyT, ValueT, KeyCompareT, AllocatorT>, Skipper> {
261 };
262 template <typename Iterator, typename KeyT, typename ValueT, typename HashT, typename KeyEqT, typename AllocatorT,
263 typename Skipper>
264 struct Grammar_<Iterator, std::unordered_map<KeyT, ValueT, HashT, KeyEqT, AllocatorT>, Skipper> {
266 };
267 template <typename Iterator, typename KeyT, typename ValueT, typename KeyCompareT, typename AllocatorT,
268 typename Skipper>
272
273 template <typename Iterator, typename PointT, typename Skipper>
274 struct Pnt3DGrammar : qi::grammar<Iterator, PointT(), Skipper> {
275 using ResultT = PointT;
276 using Scalar = typename PointT::Scalar;
277
280
281 Pnt3DGrammar() : Pnt3DGrammar::base_type( point ) {
282 auto const setX = ph::bind( &ResultT::SetX, qi::_val, qi::_1 );
283 auto const setY = ph::bind( &ResultT::SetY, qi::_val, qi::_1 );
284 auto const setZ = ph::bind( &ResultT::SetZ, qi::_val, qi::_1 );
285 list = -( enc::no_case[qi::lit( "x" ) | qi::lit( "px" )] >> ':' ) >> scalar[setX] >> ',' >>
286 -( enc::no_case[qi::lit( "y" ) | qi::lit( "py" )] >> ':' ) >> scalar[setY] >> ',' >>
287 -( enc::no_case[qi::lit( "z" ) | qi::lit( "pz" )] >> ':' ) >> scalar[setZ];
288 point = list | rep::confix( '(', ')' )[list] | rep::confix( '[', ']' )[list];
289 }
290 };
291
292 template <typename Iterator, typename T1, typename T2, typename Skipper>
296
297 template <typename Iterator, typename T1, typename T2, typename Skipper>
301
302 template <typename Iterator, typename PointT, typename Skipper>
303 struct Pnt4DGrammar : qi::grammar<Iterator, PointT(), Skipper> {
304 using ResultT = PointT;
305 using ScalarT = typename PointT::Scalar;
306
308 qi::rule<Iterator, ScalarT(), Skipper> e;
310
312 auto const setPx = ph::bind( &ResultT::SetPx, qi::_val, qi::_1 );
313 auto const setPy = ph::bind( &ResultT::SetPy, qi::_val, qi::_1 );
314 auto const setPz = ph::bind( &ResultT::SetPz, qi::_val, qi::_1 );
315 auto const setE = ph::bind( &ResultT::SetE, qi::_val, qi::_1 );
316 auto const setXYZ = ph::bind(
317 +[]( ResultT& out, ResultT const& in ) {
318 out.SetPx( in.Px() );
319 out.SetPy( in.Py() );
320 out.SetPz( in.Pz() );
321 },
322 qi::_val, qi::_1 );
323
324 // energy: optional 't' or 'e' label + scalar, with explicit assignment
325 e = -( enc::no_case[enc::char_( "te" )] >> ':' ) >> scalar[qi::_val = qi::_1];
326
327 // 3D list: x,y,z with optional labels and aliases
328 list3d = -( enc::no_case[qi::lit( "x" ) | qi::lit( "px" )] >> ':' ) >> scalar[setPx] >> ',' >>
329 -( enc::no_case[qi::lit( "y" ) | qi::lit( "py" )] >> ':' ) >> scalar[setPy] >> ',' >>
330 -( enc::no_case[qi::lit( "z" ) | qi::lit( "pz" )] >> ':' ) >> scalar[setPz];
331
332 // 3D point: bare, or wrapped in () or []
333 point3d = list3d | rep::confix( '(', ')' )[list3d] | rep::confix( '[', ']' )[list3d];
334
335 // 4D list: either (3D ; E) or (E ; 3D), ; or , as separator
336 list4d =
337 ( point3d[setXYZ] >> enc::char_( ";," ) >> e[setE] ) | ( e[setE] >> enc::char_( ";," ) >> point3d[setXYZ] );
338
339 // 4D point: bare, or wrapped in () or []
340 point4d = list4d | rep::confix( '(', ')' )[list4d] | rep::confix( '[', ']' )[list4d];
341 }
342 };
343
344 template <typename Iterator, typename T1, typename Skipper>
348
349 template <typename Iterator, typename Skipper>
350 struct Histo1DGrammar : qi::grammar<Iterator, Gaudi::Histo1DDef(), Skipper> {
352
353 // sub-grammars
355
356 // rules
359
361 // convenience setters (Phoenix binds)
362 auto setTitle = ph::bind( &ResultT::setTitle, qi::_val, qi::_1 );
363 auto setLo = ph::bind( &ResultT::setLowEdge, qi::_val, qi::_1 );
364 auto setHi = ph::bind( &ResultT::setHighEdge, qi::_val, qi::_1 );
365 auto setBins = ph::bind( &ResultT::setBins, qi::_val, qi::_1 );
366
367 // title, lo, hi [, bins]
368 val1 = title[setTitle] >> ',' >> qi::double_[setLo] >> ',' >> qi::double_[setHi] >> -( ',' >> qi::int_[setBins] );
369
370 // lo, hi, title [, bins]
371 val2 = qi::double_[setLo] >> ',' >> qi::double_[setHi] >> ',' >> title[setTitle] >> -( ',' >> qi::int_[setBins] );
372
373 // lo, hi [, title] [, bins]
374 val3 = qi::double_[setLo] >> ',' >> qi::double_[setHi] >> -( ',' >> title[setTitle] ) >>
375 -( ',' >> qi::int_[setBins] );
376
377 // accept either '(...)' or '[...]' around the payload;
378 hist = rep::confix( '(', ')' )[val1 | val2 | val3] | rep::confix( '[', ']' )[val1 | val2 | val3];
379 }
380 };
382
383 template <typename Iterator, typename Skipper>
384 struct KeyValueGrammar : qi::grammar<Iterator, std::pair<std::string, std::string>(), Skipper> {
385 typedef std::pair<std::string, std::string> ResultT;
386
387 struct first {};
388 struct second {};
389
390 KeyValueGrammar() : KeyValueGrammar::base_type( pair ) { pair = gstring >> ":" >> +enc::char_; }
391
394 };
395 // We don't register KeyalueGrammar because it's a special parser
396} // namespace Gaudi::Parsers
#define REGISTER_GRAMMAR(ResultType, GrammarName)
Definition Grammars.h:65
boost::spirit::classic::position_iterator2< ForwardIterator > Iterator
Definition Iterator.h:18
3D point typedefs
4D point typedefs
Simple helper class for description of 1D-histogram The class is targeted to act as the primary "hist...
Definition HistoDef.h:30
void setTitle(std::string value)
set the title
Definition HistoDef.h:61
void setBins(int value)
set number of bis
Definition HistoDef.h:59
void setLowEdge(double value)
set low edge
Definition HistoDef.h:55
void setHighEdge(double value)
set high edge
Definition HistoDef.h:57
Helper class for efficient "key" access for strings.
Definition StringKey.h:66
STL class.
SkipperGrammar< IteratorT > Skipper
Definition Factory.h:20
STL namespace.
qi::rule< Iterator, bool(), Skipper > boolean_literal
Definition Grammars.h:108
qi::symbols< char, bool > kw
Definition Grammars.h:107
qi::rule< Iterator, char(), Skipper > ch
Definition Grammars.h:100
IntGrammar< Iterator, T, Skipper > Grammar
Definition Grammars.h:129
MapGrammar< Iterator, std::unordered_map< KeyT, ValueT, HashT, KeyEqT, AllocatorT >, Skipper > Grammar
Definition Grammars.h:265
VectorGrammar< Iterator, std::list< InnerT, AllocatorT >, Skipper > Grammar
Definition Grammars.h:194
MapGrammar< Iterator, GaudiUtils::VectorMap< KeyT, ValueT, KeyCompareT, AllocatorT >, Skipper > Grammar
Definition Grammars.h:270
PairGrammar< Iterator, std::pair< KeyT, ValueT >, Skipper > Grammar
Definition Grammars.h:232
MapGrammar< Iterator, std::map< KeyT, ValueT, KeyCompareT, AllocatorT >, Skipper > Grammar
Definition Grammars.h:260
VectorGrammar< Iterator, std::set< InnerT, CompareT, AllocatorT >, Skipper > Grammar
Definition Grammars.h:199
Pnt3DGrammar< Iterator, ROOT::Math::DisplacementVector3D< T1, T2 >, Skipper > Grammar
Definition Grammars.h:299
Pnt3DGrammar< Iterator, ROOT::Math::PositionVector3D< T1, T2 >, Skipper > Grammar
Definition Grammars.h:294
VectorGrammar< Iterator, std::vector< InnerT, AllocatorT >, Skipper > Grammar
Definition Grammars.h:189
Pnt4DGrammar< Iterator, ROOT::Math::LorentzVector< T1 >, Skipper > Grammar
Definition Grammars.h:346
BOOST_MPL_ASSERT_MSG(false, GRAMMAR_FOR_TYPE_DOES_NOT_EXISTS,(T))
SetGrammar< Iterator, std::unordered_set< InnerT, HashT, CompareT, AllocatorT >, Skipper > Grammar
Definition Grammars.h:215
qi::rule< Iterator, ResultT(), Skipper > hist
Definition Grammars.h:357
qi::rule< Iterator, ResultT(), Skipper > val3
Definition Grammars.h:358
qi::rule< Iterator, ResultT(), Skipper > val2
Definition Grammars.h:358
Gaudi::Histo1DDef ResultT
Definition Grammars.h:351
StringGrammar< Iterator, Skipper > title
Definition Grammars.h:354
qi::rule< Iterator, ResultT(), Skipper > val1
Definition Grammars.h:358
qi::rule< Iterator, T(), Skipper > integer
Definition Grammars.h:124
std::pair< std::string, std::string > ResultT
Definition Grammars.h:385
qi::rule< Iterator, ResultT(), Skipper > pair
Definition Grammars.h:393
StringGrammar< Iterator, Skipper > gstring
Definition Grammars.h:392
typename MapT::mapped_type MappedT
Definition Grammars.h:238
std::pair< KeyT, MappedT > PairT
Definition Grammars.h:239
typename MapT::key_type KeyT
Definition Grammars.h:237
qi::rule< Iterator, std::map< KeyT, ValueT, KeyCompareT, AllocatorT >(), Skipper > map
Definition Grammars.h:247
Grammar_< Iterator, typenamePairT::first_type, Skipper >::Grammar key
Definition Grammars.h:220
qi::rule< Iterator, std::pair< KeyT, ValueT >(), Skipper > kv
Definition Grammars.h:222
Grammar_< Iterator, typenamePairT::second_type, Skipper >::Grammar val
Definition Grammars.h:221
qi::rule< Iterator, std::pair< KeyT, ValueT >(), Skipper > pair
Definition Grammars.h:223
typename PointT::Scalar Scalar
Definition Grammars.h:276
typename PointT::Scalar ScalarT
Definition Grammars.h:305
qi::rule< Iterator, Node(), Skipper > real
Definition Grammar.h:90
VectorGrammar< Iterator, std::unordered_set< InnerT, HashT, CompareT, AllocatorT >, Skipper > grVector
Definition Grammars.h:208
qi::rule< Iterator, std::unordered_set< InnerT, HashT, CompareT, AllocatorT >(), qi::locals< char >, Skipper > set
Definition Grammars.h:209
qi::rule< Iterator > comments
Definition Grammar.h:41
qi::rule< Iterator, std::string(), qi::locals< char >, Skipper > str
Definition Grammar.h:56
qi::rule< It, std::string()> dq_body
Definition Grammars.h:82
qi::rule< It, std::string()> sq_body
Definition Grammars.h:82
qi::rule< Iterator, std::tuple< Ts... >(), Skipper > body
Definition Grammars.h:148
std::tuple< typename Grammar_< Iterator, Ts, Skipper >::Grammar... > elems
Definition Grammars.h:147
void init(std::index_sequence< Is... >)
Definition Grammars.h:154
qi::rule< Iterator, std::tuple< Ts... >(), Skipper > tuple
Definition Grammars.h:149
typename VectorT::value_type value_type
Definition Grammars.h:173