The Gaudi Framework  master (82fdf313)
Loading...
Searching...
No Matches
Grammar.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#pragma once
12
13#include "Node.h"
14#include <boost/phoenix/core.hpp>
15#include <boost/phoenix/fusion.hpp>
16#include <boost/phoenix/operator.hpp>
17#include <boost/phoenix/stl.hpp>
18#if ( BOOST_VERSION >= 187000 ) && ( BOOST_VERSION < 188000 )
19# define BOOST_ALLOW_DEPRECATED_HEADERS
20#endif
21#include <boost/spirit/include/qi.hpp>
22#undef BOOST_ALLOW_DEPRECATED_HEADERS
23#include <boost/spirit/repository/include/qi_confix.hpp>
24#include <boost/spirit/repository/include/qi_iter_pos.hpp>
25#include <string>
26
27namespace Gaudi {
28 namespace Parsers {
29 namespace sp = boost::spirit;
30 namespace ph = boost::phoenix;
31 namespace qi = sp::qi;
32 namespace enc = sp::ascii;
33 namespace rep = sp::repository;
34
35 template <typename Iterator>
36 struct SkipperGrammar : qi::grammar<Iterator> {
38 comments = enc::space | rep::confix( "/*", "*/" )[*( qi::char_ - "*/" )] |
39 rep::confix( "//", ( sp::eol | sp::eoi ) )[*( qi::char_ - ( sp::eol | sp::eoi ) )];
40 }
41 qi::rule<Iterator> comments;
42 };
43
44 template <typename Iterator, typename Skipper>
45 struct StringGrammar : qi::grammar<Iterator, std::string(), qi::locals<char>, Skipper> {
46 typedef std::string ResultT;
47 StringGrammar() : StringGrammar::base_type( str ) {
48 begin_quote = enc::char_( "\"'" );
49 quote = enc::char_( qi::_r1 );
50
51 str = qi::lexeme[begin_quote[qi::_a = qi::_1] >>
52 *( ( enc::char_( '\\' ) >> quote( qi::_a ) )[qi::_val += qi::_a] |
53 ( enc::char_[qi::_val += qi::_1] - quote( qi::_a ) ) ) >>
54 quote( qi::_a )];
55 }
56 qi::rule<Iterator, std::string(), qi::locals<char>, Skipper> str;
57 qi::rule<Iterator, char()> begin_quote;
58 qi::rule<Iterator, void( char )> quote;
59 };
60 template <typename Iterator, typename Skipper>
61 struct IdentifierGrammar : qi::grammar<Iterator, Node(), Skipper> {
62 typedef std::string ResultT;
64 ident =
65 rep::qi::iter_pos[op( qi::_val, qi::_1 )] >> str[op( qi::_val, qi::_1 )][op( qi::_val, Node::kIdentifier )];
66 str = -qi::lit( "::" )[qi::_val += "::"] >> inner[qi::_val += qi::_1] >>
67 *( qi::lit( "::" ) >> inner[qi::_val += ( "::" + qi::_1 )] );
68 inner = qi::alpha >> *( qi::alnum | qi::char_( '_' ) );
69 }
70 qi::rule<Iterator, Node(), Skipper> ident;
71 qi::rule<Iterator, std::string(), Skipper> str;
72 qi::rule<Iterator, std::string()> inner;
73 ph::function<NodeOperations> op;
74 };
75 template <typename Iterator, typename Skipper>
76 struct BoolGrammar : qi::grammar<Iterator, bool(), Skipper> {
77 typedef bool ResultT;
78 BoolGrammar() : BoolGrammar::base_type( boolean ) {
79 boolean = enc::no_case[qi::lit( "true" )[qi::_val = true] | qi::lit( "false" )[qi::_val = false]];
80 }
81 qi::rule<Iterator, bool(), Skipper> boolean;
82 };
83 template <typename Iterator, typename Skipper>
84 struct RealGrammar : qi::grammar<Iterator, Node(), Skipper> {
85 typedef bool ResultT;
86 RealGrammar() : RealGrammar::base_type( real ) {
87 real = qi::raw[qi::double_][op( qi::_val, qi::_1 )][op( qi::_val, Node::kReal )] >> -qi::char_( 'L' ) >>
88 -( -qi::char_( '*' ) >> gunit[op( qi::_val, qi::_1 )] );
89 }
90 qi::rule<Iterator, Node(), Skipper> real;
92 ph::function<NodeOperations> op;
93 };
94 template <typename Iterator, typename Skipper>
95 struct UnitsGrammar : qi::grammar<Iterator, Node(), Skipper> {
96 UnitsGrammar() : UnitsGrammar::base_type( units ) {
97 units = *unit[op( qi::_val, qi::_1 )];
98 unit = rep::qi::iter_pos[op( qi::_val, qi::_1 )] >> val[op( qi::_val, qi::_1 )] >> -qi::lit( '*' ) >>
99 gunit[op( qi::_val, qi::_1 )] >> qi::lit( '=' ) >>
100 val[op( qi::_val, qi::_1 )][op( qi::_val, Node::kUnit )];
101 ;
102 val = qi::raw[qi::double_][op( qi::_val, qi::_1 )][op( qi::_val, Node::kReal )];
103 }
106 ph::function<NodeOperations> op;
107 };
108 template <typename Iterator, typename Skipper>
109 struct FileGrammar : qi::grammar<Iterator, Node(), Skipper> {
110 FileGrammar() : FileGrammar::base_type( file ) {
111 file = -shell[op( qi::_val, qi::_1 )] >> *( statement[op( qi::_val, qi::_1 )] )[op( qi::_val, Node::kRoot )];
112 shell = rep::confix(
113 "#!",
114 qi::eol )[*( qi::char_[qi::_a += qi::_1] - qi::eol )][op( qi::_val, Node::kShell )][op( qi::_val, qi::_a )];
115 statement = rep::qi::iter_pos[qi::_a = qi::_1] >> ( include | assign | units | print_options | pragma |
116 condition )[qi::_val = qi::_1][op( qi::_val, qi::_a )];
117 condition =
118 ( qi::lit( "#ifdef" )[op( qi::_a, Node::kIfdef )] | qi::lit( "#ifndef" )[op( qi::_a, Node::kIfndef )] ) >>
119 property[op( qi::_val, qi::_1 )] >> ( *statement[op( qi::_a, qi::_1 )] )[op( qi::_val, qi::_a )] >>
120 -( qi::lit( "#else" )[op( qi::_b, Node::kElse )] >>
121 *statement[op( qi::_b, qi::_1 )] )[op( qi::_val, qi::_b )] >>
122 qi::lit( "#endif" )[op( qi::_val, Node::kCondition )];
123 include = qi::lit( "#include" ) >> gstring[op( qi::_val, qi::_1 )][op( qi::_val, Node::kInclude )];
124 units = qi::lit( "#units" ) >> gstring[op( qi::_val, qi::_1 )][op( qi::_val, Node::kUnits )];
125 print_options = qi::lit( "#printOptions" ) >> qi::lit( "full" )[op( qi::_val, Node::kPrintOptions )];
126 pragma = qi::lit( "#pragma" ) >> ( pragma_print | pragma_tree | pragma_dump_file );
127 pragma_print = qi::lit( "print" ) >> enc::no_case[qi::lit( "on" )[op( qi::_val, Node::kPrintOn )] |
128 qi::lit( "off" )[op( qi::_val, Node::kPrintOff )]];
129 pragma_tree = enc::no_case[qi::lit( "printtree" )[op( qi::_val, Node::kPrintTree )]];
130 pragma_dump_file = qi::lit( "dumpfile" ) >> gstring[op( qi::_val, qi::_1 )][op( qi::_val, Node::kDumpFile )];
131 assign = property[op( qi::_val, qi::_1 )][op( qi::_val, Node::kAssign )] >> oper[op( qi::_val, qi::_1 )] >>
132 value[op( qi::_val, qi::_1 )] >> ';';
133 property = rep::qi::iter_pos[op( qi::_val, qi::_1 )] >>
134 ( gidentifier[op( qi::_val, qi::_1 )] % '.' )[op( qi::_val, Node::kProperty )];
135 property_ref %= -qi::lit( '@' ) >> property[op( qi::_val, Node::kPropertyRef )];
136 oper = rep::qi::iter_pos[op( qi::_val, qi::_1 )] >>
137 ( qi::lit( "=" )[op( qi::_val, Node::kEqual )] | qi::lit( "+=" )[op( qi::_val, Node::kPlusEqual )] |
138 qi::lit( "-=" )[op( qi::_val, Node::kMinusEqual )] );
139 value = rep::qi::iter_pos[qi::_a = qi::_1] >> ( map_value | vector_value | simple_value | property |
140 property_ref )[qi::_val = qi::_1][op( qi::_val, qi::_a )];
142 enc::char_( '(' )[qi::_val = ')'] | enc::char_( '[' )[qi::_val = ']'] | enc::char_( '{' )[qi::_val = '}'];
143 end_vector = qi::char_( qi::_r1 );
144 vector_value = ( begin_vector[qi::_a = qi::_1] >> -( value[op( qi::_val, qi::_1 )] % ',' ) >>
145 end_vector( qi::_a ) )[op( qi::_val, Node::kVector )];
146 map_value = ( enc::char_( '{' ) >> -( pair[op( qi::_val, qi::_1 )] % ',' ) >>
147 enc::char_( '}' ) )[op( qi::_val, Node::kMap )];
148 pair =
149 simple_value[op( qi::_val, qi::_1 )] >> ':' >> value[op( qi::_val, qi::_1 )][op( qi::_val, Node::kPair )];
150 simple_value = ( gstring[op( qi::_val, qi::_1 )][op( qi::_val, Node::kString )] ) |
151 ( gbool[op( qi::_val, qi::_1 )][op( qi::_val, Node::kBool )] ) | ( greal[qi::_val = qi::_1] );
152 }
155 qi::rule<Iterator, Node(), qi::locals<std::string>> shell;
156 qi::rule<Iterator, Node(), qi::locals<Iterator>, Skipper> statement, value;
157 qi::rule<Iterator, Node(), qi::locals<char>, Skipper> vector_value;
158 qi::rule<Iterator, Node(), qi::locals<Node, Node>, Skipper> condition;
159 qi::rule<Iterator, char()> begin_vector;
160 qi::rule<Iterator, void( char )> end_vector;
165 ph::function<NodeOperations> op;
166 };
167 } // namespace Parsers
168} // namespace Gaudi
boost::spirit::classic::position_iterator2< ForwardIterator > Iterator
Definition Iterator.h:18
SkipperGrammar< IteratorT > Skipper
Definition Factory.h:24
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
qi::rule< Iterator, bool(), Skipper > boolean
Definition Grammar.h:81
qi::rule< Iterator, Node(), Skipper > pragma_tree
Definition Grammar.h:154
qi::rule< Iterator, Node(), qi::locals< Node, Node >, Skipper > condition
Definition Grammar.h:158
qi::rule< Iterator, Node(), qi::locals< char >, Skipper > vector_value
Definition Grammar.h:157
qi::rule< Iterator, Node(), Skipper > oper
Definition Grammar.h:153
qi::rule< Iterator, Node(), Skipper > include
Definition Grammar.h:153
qi::rule< Iterator, Node(), qi::locals< Iterator >, Skipper > value
Definition Grammar.h:156
qi::rule< Iterator, Node(), qi::locals< Iterator >, Skipper > statement
Definition Grammar.h:156
qi::rule< Iterator, Node(), Skipper > print_options
Definition Grammar.h:154
qi::rule< Iterator, Node(), Skipper > file
Definition Grammar.h:153
qi::rule< Iterator, Node(), Skipper > pair_value
Definition Grammar.h:153
qi::rule< Iterator, void(char)> end_vector
Definition Grammar.h:160
RealGrammar< Iterator, Skipper > greal
Definition Grammar.h:163
ph::function< NodeOperations > op
Definition Grammar.h:165
qi::rule< Iterator, Node(), Skipper > property_ref
Definition Grammar.h:153
qi::rule< Iterator, char()> begin_vector
Definition Grammar.h:159
qi::rule< Iterator, Node(), qi::locals< std::string > > shell
Definition Grammar.h:155
BoolGrammar< Iterator, Skipper > gbool
Definition Grammar.h:162
qi::rule< Iterator, Node(), Skipper > assign
Definition Grammar.h:153
qi::rule< Iterator, Node(), Skipper > pragma
Definition Grammar.h:154
qi::rule< Iterator, Node(), Skipper > simple_value
Definition Grammar.h:154
qi::rule< Iterator, Node(), Skipper > property
Definition Grammar.h:153
qi::rule< Iterator, Node(), Skipper > map_value
Definition Grammar.h:153
StringGrammar< Iterator, Skipper > gstring
Definition Grammar.h:161
qi::rule< Iterator, Node(), Skipper > pragma_dump_file
Definition Grammar.h:154
qi::rule< Iterator, Node(), Skipper > units
Definition Grammar.h:154
qi::rule< Iterator, Node(), Skipper > pragma_print
Definition Grammar.h:154
qi::rule< Iterator, Node(), Skipper > pair
Definition Grammar.h:154
IdentifierGrammar< Iterator, Skipper > gidentifier
Definition Grammar.h:164
qi::rule< Iterator, std::string()> inner
Definition Grammar.h:72
qi::rule< Iterator, Node(), Skipper > ident
Definition Grammar.h:70
qi::rule< Iterator, std::string(), Skipper > str
Definition Grammar.h:71
ph::function< NodeOperations > op
Definition Grammar.h:73
qi::rule< Iterator, Node(), Skipper > real
Definition Grammar.h:90
IdentifierGrammar< Iterator, Skipper > gunit
Definition Grammar.h:91
ph::function< NodeOperations > op
Definition Grammar.h:92
qi::rule< Iterator, void(char)> quote
Definition Grammar.h:58
qi::rule< Iterator, char()> begin_quote
Definition Grammar.h:57
qi::rule< Iterator, std::string(), qi::locals< char >, Skipper > str
Definition Grammar.h:56
ph::function< NodeOperations > op
Definition Grammar.h:106
qi::rule< Iterator, Node(), Skipper > units
Definition Grammar.h:104
qi::rule< Iterator, Node(), Skipper > val
Definition Grammar.h:104
qi::rule< Iterator, Node(), Skipper > unit
Definition Grammar.h:104
IdentifierGrammar< Iterator, Skipper > gunit
Definition Grammar.h:105