CMS 3D CMS Logo

TriggerExpressionParser.h
Go to the documentation of this file.
1 #ifndef HLTrigger_HLTcore_TriggerExpressionParser_h
2 #define HLTrigger_HLTcore_TriggerExpressionParser_h
3 
4 // Note: this requires Boost 1.41 or higher, for Spirit 2.1 or higher
5 #include <boost/phoenix.hpp>
6 #include <boost/spirit/include/qi.hpp>
7 
13 
14 namespace triggerExpression {
15 
16  namespace qi = boost::spirit::qi;
17  namespace ascii = boost::spirit::ascii;
18 
19  using boost::phoenix::new_;
20  using boost::spirit::unused_type;
21 
22  template <typename Iterator>
23  class Parser : public qi::grammar<Iterator, Evaluator *(), ascii::space_type> {
24  public:
25  Parser() : Parser::base_type(expression) {
26  auto delimiter = qi::copy(qi::eoi | !qi::char_("a-zA-Z0-9_*?"));
27 
28  operand_not = qi::lexeme[qi::lit("NOT") >> delimiter];
29  operand_and = qi::lexeme[qi::lit("AND") >> delimiter];
30  operand_or = qi::lexeme[qi::lit("OR") >> delimiter];
31  operand_xor = qi::lexeme[qi::lit("XOR") >> delimiter];
32  operand_masking = qi::lexeme[qi::lit("MASKING") >> delimiter];
33 
34  // "TRUE": keyword to accept all events
35  token_true = qi::lexeme[qi::lit("TRUE") >> delimiter];
36 
37  // "FALSE": keyword to reject all events
38  token_false = qi::lexeme[qi::lit("FALSE") >> delimiter];
39 
40  // Level-1 Global Trigger decisions: must begin with characters "L1_"
41  token_l1algo %= qi::raw[qi::lexeme["L1_" >> +(qi::char_("a-zA-Z0-9_*?"))]];
42 
43  // Decisions of Paths in the CMSSW configuration (e.g. high-level triggers):
44  // any alphanumeric pattern except for "TRUE", "FALSE", "NOT", "AND", "OR", "XOR" and "MASKING"
45  token_path %= qi::raw[qi::lexeme[+(qi::char_("a-zA-Z0-9_*?"))] - token_true - token_false - operand_not -
47 
48  token = (token_true[qi::_val = new_<Constant>(true)] | token_false[qi::_val = new_<Constant>(false)] |
49  token_l1algo[qi::_val = new_<L1uGTReader>(qi::_1)] | token_path[qi::_val = new_<PathReader>(qi::_1)]);
50 
51  parenthesis %= ('(' >> expression >> ')');
52 
53  element %= (token | parenthesis);
54 
55  prescale = (element >> '/' >> qi::uint_)[qi::_val = new_<Prescaler>(qi::_1, qi::_2)];
56 
57  operand %= (prescale | element);
58 
59  unary = ((operand_not >> unary)[qi::_val = new_<OperatorNot>(qi::_1)] | operand[qi::_val = qi::_1]);
60 
61  // token_masking is used to restrict the argument (rhs) of the "MASKING"
62  // operation to Constant[FALSE], L1uGTReader and PathReader evaluators
64  (token_false[qi::_val = new_<Constant>(false)] | token_l1algo[qi::_val = new_<L1uGTReader>(qi::_1)] |
65  token_path[qi::_val = new_<PathReader>(qi::_1)]);
66 
67  argument_masking %= (token_masking | ('(' >> argument_masking >> ')'));
68 
69  expression = unary[qi::_val = qi::_1] >>
70  *((operand_and >> unary)[qi::_val = new_<OperatorAnd>(qi::_val, qi::_1)] |
71  (operand_or >> unary)[qi::_val = new_<OperatorOr>(qi::_val, qi::_1)] |
72  (operand_xor >> unary)[qi::_val = new_<OperatorXor>(qi::_val, qi::_1)] |
73  (operand_masking >> argument_masking)[qi::_val = new_<OperatorMasking>(qi::_val, qi::_1)]);
74  }
75 
76  private:
77  typedef qi::rule<Iterator, std::string(), ascii::space_type> name_rule;
78  typedef qi::rule<Iterator, Evaluator *(), ascii::space_type> rule;
79  typedef qi::rule<Iterator> terminal_rule;
80 
83 
89 
92 
102  };
103 
104  // generic interface for string-like objects
105  template <class T>
106  Evaluator *parse(const T &text) {
107  typedef typename T::const_iterator Iterator;
109  Evaluator *evaluator = nullptr;
110 
111  Iterator begin = text.begin();
112  Iterator end = text.end();
113 
114  // the interface of qi::phrase_parse has changed between Boost 1.40 (Spirit 2.0) and Boost 1.41 (Spirit 2.1)
115  bool result = qi::phrase_parse(begin, end, parser, ascii::space, evaluator);
116 
117  if (not result or begin != end) {
118  delete evaluator;
119  return nullptr;
120  }
121 
122  return evaluator;
123  }
124 
125  // overloaded interface for null-terminated strings
126  inline Evaluator *parse(const char *text) {
128  Evaluator *evaluator = nullptr;
129 
130  const char *begin = text;
131  const char *end = text + strlen(text);
132 
133  // the interface of qi::phrase_parse has changed between Boost 1.40 (Spirit 2.0) and Boost 1.41 (Spirit 2.1)
134  bool result = qi::phrase_parse(begin, end, parser, ascii::space, evaluator);
135 
136  if (not result or begin != end) {
137  delete evaluator;
138  return nullptr;
139  }
140 
141  return evaluator;
142  }
143 
144 } // namespace triggerExpression
145 
146 #endif // HLTrigger_HLTcore_TriggerExpressionParser_h
Evaluator * parse(const T &text)
TGeoIterator Iterator
qi::rule< Iterator, Evaluator *(), ascii::space_type > rule
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
qi::rule< Iterator > terminal_rule
qi::rule< Iterator, std::string(), ascii::space_type > name_rule
long double T
dd4hep::tools::Evaluator & evaluator()