ATLAS Offline Software
SelectionExprParser.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
10 
11 #include <iostream>
12 #include <regex>
13 #include <string>
14 
16 
17 namespace CP {
18 using namespace msgSelectionHelpers;
19 
20 namespace DetailSelectionExprParser {
21 bool Separator::operator()(std::string::const_iterator& next,
22  const std::string::const_iterator& end,
23  std::string& tok) const {
24  if (next == end) {
25  return false;
26  }
27 
28  static const std::regex base_regex(
29  "^( ?((?:[^|&()! ]+)|(?:&&)|(?:!)|(?:\\()|(?:\\))|(?:\\|\\|))).*");
30  std::smatch m;
31 
32  if (std::regex_match(next, end, m, base_regex)) {
33  tok = m[2].str();
34  next += m[1].length();
35  } else {
36  std::smatch m2;
37  static const std::regex space_re{"^ +$"};
38  if (std::regex_match(next, end, m, space_re)) {
39  // only spaces left, we're done
40  return false;
41  }
42  throw std::runtime_error("Cannot tokenize: '" + std::string(next, end) +
43  "'");
44  }
45  return true;
46 }
47 
48 Lexer::Lexer(const std::string& s) : m_string(s), m_tokenizer(m_string, {}) {
49  m_iterator = m_tokenizer.begin();
50 }
51 
53  if (m_iterator == m_tokenizer.end()) {
54  return Symbol{END, ""};
55  }
56  std::string t = *m_iterator;
57  Type type;
58  if (t == "&&")
59  type = AND;
60  else if (t == "||")
61  type = OR;
62  else if (t == "(")
63  type = LEFT;
64  else if (t == ")")
65  type = RIGHT;
66  else if (t == "!")
67  type = NOT;
68  else if (t == "true")
69  type = TRUE_LITERAL;
70  else if (t == "false")
71  type = FALSE_LITERAL;
72  else {
73  // check if variable is valid
74  const std::regex base_regex("^([^|()&! ]*)$");
75  std::smatch base_match;
76 
77  if (!std::regex_match(t, base_match, base_regex)) {
78  throw std::runtime_error("illegal variable encountered");
79  } else {
80  type = VAR;
81  }
82  }
83 
84  ++m_iterator;
85  return Symbol{type, t};
86 }
87 
88 } // namespace DetailSelectionExprParser
89 
91  : m_lexer(std::move(lexer)), m_defaultToChar(defaultToChar) {}
92 
94  std::unique_ptr<ISelectionReadAccessor>& accessor) {
95  std::unique_ptr<ISelectionReadAccessor> root{nullptr};
97 
98  if (m_symbol.type != Lexer::END) {
99  throw std::runtime_error(
100  "Not all symbols in expression were consumed. Check your expression.");
101  }
102 
103  accessor = std::move(root);
104  return StatusCode::SUCCESS;
105 }
106 
108  std::unique_ptr<ISelectionReadAccessor>& root) {
109  ANA_CHECK(term(root));
110  while (m_symbol.type == Lexer::OR) {
111  std::unique_ptr<ISelectionReadAccessor> left = std::move(root);
112  ANA_CHECK(term(root));
113  std::unique_ptr<ISelectionReadAccessor> right = std::move(root);
114  root = std::make_unique<SelectionAccessorExprOr>(std::move(left),
115  std::move(right));
116  }
117  return StatusCode::SUCCESS;
118 }
119 
121  std::unique_ptr<ISelectionReadAccessor>& root) {
123  std::vector<std::unique_ptr<ISelectionReadAccessor>> factors;
124  factors.push_back(std::move(root));
125 
126  while (m_symbol.type == Lexer::AND) {
128  factors.push_back(std::move(root));
129  }
130 
131  if (factors.size() == 1) {
132  root = std::move(factors[0]);
133  } else {
134  root = std::make_unique<SelectionAccessorList>(std::move(factors));
135  }
136  return StatusCode::SUCCESS;
137 }
138 
140  std::unique_ptr<ISelectionReadAccessor>& root) {
142  if (m_symbol.type == Lexer::TRUE_LITERAL) {
143  root = std::make_unique<SelectionReadAccessorNull>(true);
145  } else if (m_symbol.type == Lexer::FALSE_LITERAL) {
146  root = std::make_unique<SelectionReadAccessorNull>(false);
148  } else if (m_symbol.type == Lexer::NOT) {
150  std::unique_ptr<ISelectionReadAccessor> notEx =
151  std::make_unique<SelectionAccessorExprNot>(std::move(root));
152  root = std::move(notEx);
153  } else if (m_symbol.type == Lexer::LEFT) {
155  if (m_symbol.type != Lexer::RIGHT) {
156  throw std::runtime_error(
157  "Missing closing bracket, check your expression.");
158  }
160 
161  } else if (m_symbol.type == Lexer::VAR) {
164  } else {
165  throw std::runtime_error("Malformed expression.");
166  }
167 
168  return StatusCode::SUCCESS;
169 }
170 
171 } // namespace CP
SelectionExprParser.h
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
python.SystemOfUnits.m2
int m2
Definition: SystemOfUnits.py:92
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
SelectionAccessorExprOr.h
Root::AND
@ AND
Definition: TGRLCollection.h:32
CP::SelectionExprParser::SelectionExprParser
SelectionExprParser(DetailSelectionExprParser::Lexer lexer, bool defaultToChar=false)
Constructor for the parser which accepts a Lecer.
Definition: SelectionExprParser.cxx:90
ANA_CHECK
#define ANA_CHECK(EXP)
check whether the given expression was successful
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:324
CP::DetailSelectionExprParser::Lexer
Lexer which turns a token stream into a stream of unambigous symbols to be used by a parser.
Definition: SelectionExprParser.h:38
sendEI_SPB.root
root
Definition: sendEI_SPB.py:34
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
CP
Select isolated Photons, Electrons and Muons.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:48
SelectionAccessorList.h
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
CP::SelectionExprParser::term
StatusCode term(std::unique_ptr< ISelectionReadAccessor > &root)
Definition: SelectionExprParser.cxx:120
CP::DetailSelectionExprParser::Lexer::Symbol
Struct grouping together the type and original string representation of a symbol.
Definition: SelectionExprParser.h:64
CP::SelectionExprParser::expression
StatusCode expression(std::unique_ptr< ISelectionReadAccessor > &root)
Definition: SelectionExprParser.cxx:107
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Trk::RIGHT
@ RIGHT
the drift radius is positive (see Trk::AtaStraightLine)
Definition: DriftCircleSide.h:22
internal_poltrig::END
@ END
Definition: PolygonTriangulator.cxx:112
xAODType
Definition: ObjectType.h:13
SelectionAccessorExprNot.h
CP::DetailSelectionExprParser::Lexer::nextSymbol
Symbol nextSymbol()
Generate a new symbol from the token sequence.
Definition: SelectionExprParser.cxx:52
CP::DetailSelectionExprParser::Lexer::Symbol::value
std::string value
Definition: SelectionExprParser.h:66
xAOD::JetAttributeAccessor::accessor
const AccessorWrapper< T > * accessor(xAOD::JetAttribute::AttributeID id)
Returns an attribute accessor corresponding to an AttributeID.
Definition: JetAccessorMap.h:26
CP::SelectionExprParser::m_lexer
DetailSelectionExprParser::Lexer m_lexer
Definition: SelectionExprParser.h:103
CP::makeSelectionReadAccessorVar
StatusCode makeSelectionReadAccessorVar(const std::string &name, std::unique_ptr< ISelectionReadAccessor > &accessor, bool defaultToChar)
Produces a simple ISelectionReadAccessor accessing the given decoration.
Definition: ISelectionAccessor.cxx:139
CP::DetailSelectionExprParser::Lexer::Symbol::type
Type type
Definition: SelectionExprParser.h:65
CP::SelectionExprParser::build
StatusCode build(std::unique_ptr< ISelectionReadAccessor > &accessor)
Triggers the actual parsing of the expression.
Definition: SelectionExprParser.cxx:93
CP::SelectionExprParser::factor
StatusCode factor(std::unique_ptr< ISelectionReadAccessor > &root)
Definition: SelectionExprParser.cxx:139
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
Root::OR
@ OR
Definition: TGRLCollection.h:32
CP::SelectionExprParser::m_symbol
DetailSelectionExprParser::Lexer::Symbol m_symbol
Definition: SelectionExprParser.h:105
Trk::LEFT
@ LEFT
the drift radius is negative (see Trk::AtaStraightLine)
Definition: DriftCircleSide.h:20
CP::SelectionExprParser::m_defaultToChar
bool m_defaultToChar
Definition: SelectionExprParser.h:107
SelectionReadAccessorNull.h