ATLAS Offline Software
LogicExpression.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "./LogicExpression.h"
6 #include <cstdlib>
7 #include <string>
8 #include <iostream>
9 #include <sstream>
10 #include <stdio.h>
11 
12 using namespace TrigConf;
13 
15  m_State(kELEMENT),
16  m_Element(""),
17  m_ostream(o)
18 {}
19 
20 
21 LogicExpression::LogicExpression(const std::string& name, std::ostream & o)
22  : m_State(kELEMENT),
23  m_Element(name),
24  m_ostream(o)
25 {}
26 
27 
28 bool
30  std::string valid_sym = "_";
31  if (isalpha(c) || isdigit(c) || valid_sym.find(c)!=std::string::npos) {
32  return true;
33  } else {
34  return false;
35  }
36 }
37 
38 
39 std::string
40 LogicExpression::extractElementName(const std::string& expr) {
41  std::string name="";
42  for (unsigned int i=0; i<expr.size(); ++i) {
43  if (isValidElementChar(expr[i])) name += expr[i];
44  else break;
45  }
46  return name;
47 }
48 
49 
50 int
51 LogicExpression::parse(const std::string& expr, bool enclosed) {
52  unsigned int i=0;
53  char c;
54  bool no_problem=true;
55  char prev = ' ';
56  int n;
57 
58  m_LogicRep = expr;
59  while (no_problem && i < expr.size()) {
60  c = expr[i];
61 
62  switch (c) {
63  case kOPEN:
64  {
66  if ( (n = sub.parse(expr.substr(i+1), true)) > 0) {
67  addSubLogic(sub);
68  prev = kELEMENT;
69  i += n;
70  } else {
71  no_problem = false;
72  }
73  }
74  break;
75  case kCLOSE:
76  if ( ( (m_State == kAND || m_State == kOR) && subLogics().size()>=2) ||
77  (m_State == kNOT && subLogics().size()==1) ||
78  (m_State == kELEMENT && subLogics().size()<=1 && m_Element=="")) {
79  prev = kELEMENT;
81  return i + 1;
82  } else {
83  std::ostringstream formatedoutput;
84  formatedoutput << "Invalid logic: State=" << m_State << " Nsublogics=" << subLogics().size() << " Element=" << m_Element;
85  printError(formatedoutput.str(), i);
86  no_problem = false;
87  }
88  break;
89  case kAND: case kOR:
90  if (prev == kELEMENT &&
91  ( (subLogics().size() >= 2 && m_State==c) ||
92  (subLogics().size()==1 && m_State==kELEMENT))
93  ) {
94  m_State = c;
95  prev = c;
96  } else {
97  std::ostringstream formatedoutput;
98  formatedoutput << kAND << " or " << kOR << " must come after a logic element";
99  printError(formatedoutput.str(), i);
100  no_problem = false;
101  }
102  break;
103  case kNOT:
104  if (kELEMENT != prev) {
106  sub.setState(kNOT);
107  if ( (i+1)<expr.size() && isValidElementChar(expr[i+1])) {
108  std::string name = extractElementName(expr.substr(i+1));
110  i += name.size();
111  addSubLogic(sub);
112  } else if ( (i+1)<expr.size() && expr[i+1]==kOPEN) {
114  if ( (n = sub2.parse(expr.substr(i+2), true)) > 0) {
115  sub.addSubLogic(sub2);
116  i += (n+1);
117  addSubLogic(sub);
118  } else {
119  no_problem = false;
120  }
121  } else {
122  printError("Was expecting a sub-logic after !", i);
123  no_problem = false;
124  }
125  } else {
126  printError("! must not come directly after a logic element", i);
127  no_problem = false;
128  }
129  prev = kELEMENT;
130  break;
131  default:
132  // Start of a candidate of an element string.
133  if (subLogics().size()==0 ||
134  (subLogics().size()>0 && m_State != kELEMENT)) {
135  std::string name = extractElementName(expr.substr(i));
136  if (name.size() > 0) {
138  i += name.size()-1;
139  } else {
140  printError("Unrecognized string", i);
141  no_problem = false;
142  }
143  prev = kELEMENT;
144  } else {
145  printError("A logic element may not come immediately after another logic element", i);
146  no_problem = false;
147  }
148  break;
149  }
150  i ++;
151 
152  }
153  if (!no_problem) {
154  return -1;
155  }
156 
157  if (enclosed) {
158  // The logic expression started with a '(' but didn't find ')' and
159  // reached the end of the string.
160  printError("The expression started with a '(' but ')' not found.", i);
161  return 0;
162  }
163  markPlaceHolder();
164 
165  return i;
166 }
167 
168 void
170  if (m_State == kELEMENT && subLogics().size() == 1 && m_Element=="") {
171  m_State = kOPEN;
172  }
173 }
174 
175 std::string
177  std::string s="";
178  if (m_State == kELEMENT) {
179  s = m_Element;
180  } else if (m_State == kAND || m_State == kOR) {
181  LogicV_t::const_iterator p;
182  s = kOPEN;
183  for (p=subLogics().begin(); p!=subLogics().end(); ++p) {
184  s += (*p)->logicRep();
185  s += m_State;
186  }
187  if (s.size() > 1) s[s.size()-1] = kCLOSE;
188  else s += kCLOSE;
189  } else if (m_State == kNOT) {
190  s = kNOT;
191  s += kOPEN;
192  if (subLogics().size() == 1) s += subLogics()[0]->logicRep();
193  s += kCLOSE;
194  } else if (m_State == kOPEN) {
195  s += kOPEN;
196  if (subLogics().size() == 1) s += subLogics()[0]->logicRep();
197  s += kCLOSE;
198  }
199  return s;
200 }
201 
202 
203 void
205  LogicV_t::const_iterator p;
206  for (p=subLogics().begin(); p!=subLogics().end(); ++p) {
207  (*p)->normalize();
208  }
209  if (isPlaceHolder()) {
210  char s = subLogics()[0]->state();
211  std::string e = subLogics()[0]->element();
212  LogicV_t sublogics = subLogics()[0]->subLogics();
213  clear();
214  setState(s);
215  setElement(e);
216  for (p=sublogics.begin(); p!=sublogics.end(); ++p) {
217  addSubLogic(**p);
218  }
219  }
220 }
221 
222 
223 int
225  int n = 0;
226  LogicV_t::const_iterator p;
227 
228  switch (m_State) {
229  case kELEMENT:
230  n = 1;
231  break;
232  case kAND: case kOR: case kNOT: case kOPEN:
233  for (p=subLogics().begin(); p!=subLogics().end(); ++p) {
234  n += (*p)->totalNumberOfElements();
235  }
236  break;
237  default:
238  n = 0;
239  break;
240  }
241  return n;
242 }
243 
244 
245 void
246 LogicExpression::printError(const std::string& message, int i) {
247  std::string m="Error while parsing : ";
248  std::string s="";
249  int n = m.size();
250  for (int j=0; j<(n+i); ++j) s += " ";
251  s += "^";
252  m_ostream << m << m_LogicRep << " at " << i << "-th character" << std::endl;
253  m_ostream << s << std::endl;
254  m_ostream << message << std::endl;
255 }
256 
257 
258 void
260  char aaa[100];
261  sprintf(aaa, "Current state: State=%c Nsublogics=%d Element=%s",
262  m_State, (int)subLogics().size(), m_Element.c_str());
263  m_ostream << aaa << std::endl;
264 }
265 
266 
267 void
268 LogicExpression::print(const std::string& indent) {
269  std::string s=indent;
270  if (m_State == kELEMENT) {
271  m_ostream << indent << m_Element << std::endl;
272  } else if (m_State == kAND || m_State == kOR) {
273  if (m_State==kAND) m_ostream << indent << "AND" << std::endl;
274  if (m_State==kOR) m_ostream << indent << "OR" << std::endl;
275  LogicV_t::const_iterator p;
276  for (p=subLogics().begin(); p!=subLogics().end(); ++p) {
277  (*p)->print(indent + " ");
278  }
279  } else if (m_State == kNOT) {
280  m_ostream << indent << "NOT" << std::endl;
281  if (subLogics().size() == 1) {
282  subLogic(0)->print(indent + " ");
283  }
284  } else if (m_State == kOPEN) {
285  if (subLogics().size() == 1) subLogic(0)->print(indent);
286  } else {
287  m_ostream << indent << "ERROR" << std::endl;
288  }
289 }
290 
291 
292 void
294  m_State = kELEMENT;
295  m_SubLogics.clear();
296  m_Element = "";
297 }
298 
TrigConf::LogicExpression::markPlaceHolder
void markPlaceHolder()
Definition: LogicExpression.cxx:169
TrigConf::LogicExpression::setState
void setState(char s)
Definition: LogicExpression.h:54
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
TrigConf::LogicExpression::logicRep
virtual std::string logicRep() const
Definition: LogicExpression.cxx:176
TrigConf::LogicExpression::parse
virtual int parse(const std::string &expr, bool enclosed=false)
Definition: LogicExpression.cxx:51
TrigConf::LogicExpression::m_SubLogics
LogicV_t m_SubLogics
Definition: LogicExpression.h:84
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
TrigConf::LogicExpression::subLogics
const LogicV_t & subLogics() const
Definition: LogicExpression.h:62
TrigConf::LogicV_t
std::vector< std::shared_ptr< LogicExpression > > LogicV_t
Definition: LogicExpression.h:24
LogicExpression.h
TrigConf::LogicExpression::setElement
void setElement(const std::string &e)
Definition: LogicExpression.h:55
ReweightUtils.message
message
Definition: ReweightUtils.py:15
TrigConf::LogicExpression
Definition: LogicExpression.h:27
TrigConf::LogicExpression::m_State
char m_State
Definition: LogicExpression.h:82
TrigConf
Forward iterator to traverse the main components of the trigger configuration.
Definition: Config.h:22
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
geometry_dat_to_json.indent
indent
Definition: geometry_dat_to_json.py:18
lumiFormat.i
int i
Definition: lumiFormat.py:92
TrigConf::LogicExpression::isPlaceHolder
bool isPlaceHolder() const
Definition: LogicExpression.h:64
TrigConf::LogicExpression::addSubLogic
void addSubLogic(const LogicExpression &sub)
Definition: LogicExpression.h:56
beamspotman.n
n
Definition: beamspotman.py:731
TrigConf::LogicExpression::normalize
void normalize()
Definition: LogicExpression.cxx:204
TrigConf::LogicExpression::clear
void clear()
Definition: LogicExpression.cxx:293
TrigConf::LogicExpression::m_Element
std::string m_Element
Definition: LogicExpression.h:85
TrigConf::LogicExpression::LogicExpression
LogicExpression(std::ostream &o=std::cout)
constructor
Definition: LogicExpression.cxx:14
TrigConf::LogicExpression::kNOT
static const char kNOT
NOT of a sub-logic. (only one sub-logic)
Definition: LogicExpression.h:34
TrigConf::LogicExpression::kELEMENT
static const char kELEMENT
simple element.
Definition: LogicExpression.h:35
TrigConf::LogicExpression::extractElementName
static std::string extractElementName(const std::string &expr)
Definition: LogicExpression.cxx:40
TrigConf::LogicExpression::kOR
static const char kOR
OR of sub-logics.
Definition: LogicExpression.h:33
TrigConf::name
Definition: HLTChainList.h:35
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
TrigConf::LogicExpression::kCLOSE
static const char kCLOSE
')' is a valid symbol, but not allowed as a state.
Definition: LogicExpression.h:37
TrigConf::LogicExpression::subLogic
const std::shared_ptr< LogicExpression > subLogic(int i) const
Definition: LogicExpression.h:63
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
TrigConf::LogicExpression::printCurrentState
void printCurrentState()
Definition: LogicExpression.cxx:259
TrigConf::LogicExpression::kAND
static const char kAND
AND of sub-logics.
Definition: LogicExpression.h:32
TrigConf::LogicExpression::totalNumberOfElements
int totalNumberOfElements() const
Definition: LogicExpression.cxx:224
TrigConf::LogicExpression::printError
void printError(const std::string &message, int i)
Definition: LogicExpression.cxx:246
python.compressB64.c
def c
Definition: compressB64.py:93
TrigConf::LogicExpression::m_ostream
std::ostream & m_ostream
output stream for all messages
Definition: LogicExpression.h:87
TrigConf::LogicExpression::isValidElementChar
static bool isValidElementChar(char c)
Definition: LogicExpression.cxx:29
TrigConf::LogicExpression::kOPEN
static const char kOPEN
empty logic but may have sub-logics.
Definition: LogicExpression.h:36
TrigConf::LogicExpression::print
void print(const std::string &indent="")
Definition: LogicExpression.cxx:268
TrigConf::LogicExpression::m_LogicRep
std::string m_LogicRep
Definition: LogicExpression.h:80