]>
Commit | Line | Data |
---|---|---|
4fbb2459 | 1 | // |
9477aa42 | 2 | // AliRsnExpresion class is used to |
3 | // handle operators &|! | |
4 | // in AliRsnCut | |
4fbb2459 | 5 | // |
6 | // authors: Martin Vala (martin.vala@cern.ch) | |
7 | // Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it) | |
8 | // | |
9 | ||
baca856a | 10 | #include <TString.h> |
11 | #include <TObjString.h> | |
12 | #include <TObjArray.h> | |
13 | ||
14 | #include "AliLog.h" | |
15 | ||
4fbb2459 | 16 | #include "AliRsnVariableExpression.h" |
baca856a | 17 | #include "AliRsnExpression.h" |
18 | ||
aec0ec32 | 19 | ClassImp(AliRsnExpression) |
baca856a | 20 | |
4fbb2459 | 21 | AliRsnCutSet *AliRsnExpression::fgCutSet = 0; |
baca856a | 22 | |
23 | //______________________________________________________________________________ | |
aec0ec32 | 24 | AliRsnExpression::AliRsnExpression(TString exp) : |
baca856a | 25 | TObject(), |
aec0ec32 | 26 | fVname(""), |
27 | fArg1(0x0), | |
28 | fArg2(0x0), | |
29 | fOperator(0) | |
baca856a | 30 | { |
31 | // Default constructor | |
aec0ec32 | 32 | TObjArray* tokens = Tokenize(exp); |
baca856a | 33 | |
34 | Int_t i = -1; | |
aec0ec32 | 35 | AliRsnExpression* e = Expression(*tokens, i); |
baca856a | 36 | // Copy !!! |
37 | fArg1 = e->fArg1; e->fArg1 = 0; | |
38 | fArg2 = e->fArg2; e->fArg2 = 0; | |
39 | fOperator = e->fOperator; | |
40 | fVname = e->fVname; | |
41 | delete e; | |
42 | delete tokens; | |
43 | } | |
44 | ||
45 | //______________________________________________________________________________ | |
46 | AliRsnExpression::~AliRsnExpression() | |
47 | { | |
aec0ec32 | 48 | if (fArg1) delete fArg1; |
49 | if (fArg2) delete fArg2; | |
baca856a | 50 | } |
51 | ||
aec0ec32 | 52 | AliRsnExpression::AliRsnExpression(const AliRsnExpression & exp) : TObject(exp), |
53 | fVname(exp.fVname), | |
54 | fArg1(exp.fArg1), | |
55 | fArg2(exp.fArg2), | |
56 | fOperator(exp.fOperator) | |
baca856a | 57 | {} |
58 | ||
59 | //______________________________________________________________________________ | |
aec0ec32 | 60 | AliRsnExpression& AliRsnExpression::operator= (const AliRsnExpression& e) |
baca856a | 61 | { |
62 | // AliRsnExpression assignment operator. | |
63 | ||
4fbb2459 | 64 | if (this != &e) { |
aec0ec32 | 65 | TObject::operator= (e); |
baca856a | 66 | fArg1 = e.fArg1; |
67 | fArg2 = e.fArg2; | |
68 | fOperator = e.fOperator; | |
69 | fVname = e.fVname; | |
70 | } | |
71 | return *this; | |
72 | } | |
73 | ||
74 | //______________________________________________________________________________ | |
aec0ec32 | 75 | AliRsnExpression::AliRsnExpression(int op, AliRsnExpression* a, AliRsnExpression* b) : |
baca856a | 76 | TObject(), |
aec0ec32 | 77 | fVname(""), |
78 | fArg1(a), | |
79 | fArg2(b), | |
80 | fOperator(op) | |
baca856a | 81 | { |
82 | // Create a new expression | |
83 | } | |
84 | ||
85 | //______________________________________________________________________________ | |
aec0ec32 | 86 | AliRsnExpression::AliRsnExpression(int op, AliRsnExpression* a) : |
baca856a | 87 | TObject(), |
aec0ec32 | 88 | fVname(""), |
89 | fArg1(0), | |
90 | fArg2(a), | |
91 | fOperator(op) | |
baca856a | 92 | { |
93 | // Create a unary expression. | |
94 | } | |
95 | ||
96 | //______________________________________________________________________________ | |
aec0ec32 | 97 | Bool_t AliRsnExpression::Value(TObjArray &vars) |
baca856a | 98 | { |
99 | // Evaluate the expression | |
4fbb2459 | 100 | if (fArg2 == 0 && fVname.IsNull()) { |
aec0ec32 | 101 | AliError("Expression undefined."); |
baca856a | 102 | return kFALSE; |
103 | } | |
104 | ||
105 | // AliDebug(AliLog::kDebug,Form("fOperator %d",fOperator)); | |
8ecf98c4 | 106 | |
4fbb2459 | 107 | switch (fOperator) { |
baca856a | 108 | |
4fbb2459 | 109 | case kOpOR : |
110 | return fArg1->Value(vars) || fArg2->Value(vars); | |
baca856a | 111 | |
4fbb2459 | 112 | case kOpAND : |
113 | return fArg1->Value(vars) && fArg2->Value(vars); | |
baca856a | 114 | |
4fbb2459 | 115 | case kOpNOT : |
116 | return !(fArg2->Value(vars)); | |
baca856a | 117 | |
4fbb2459 | 118 | case 0 : { |
119 | // Int_t indexx = fgCutSet->GetIndexByCutName ( fVname.Data() ); | |
baca856a | 120 | AliDebug(AliLog::kDebug,Form("Vname %s",fVname.Data())); |
4fbb2459 | 121 | // return fgCutSet->GetBoolValue ( indexx ); |
122 | return fgCutSet->GetBoolValue(fVname.Atoi()); | |
baca856a | 123 | } |
124 | ||
4fbb2459 | 125 | default: |
126 | AliError("Illegal operator in expression!"); | |
baca856a | 127 | |
128 | } | |
129 | return kFALSE; | |
130 | } | |
131 | ||
132 | ||
133 | //______________________________________________________________________________ | |
134 | TString AliRsnExpression::Unparse() const | |
135 | { | |
136 | // Unparse the expression | |
137 | ||
138 | TString opVals[4] = { "", "&", "|","!" }; | |
4fbb2459 | 139 | if (fArg2 == 0 && fVname.IsNull()) { |
aec0ec32 | 140 | AliError("Expression undefined."); |
baca856a | 141 | return "Error"; |
142 | } | |
143 | ||
aec0ec32 | 144 | if (fArg2 == 0 && !fVname.IsNull()) return fVname; |
baca856a | 145 | |
4fbb2459 | 146 | if (fArg1 == 0 && fArg2) { |
baca856a | 147 | return opVals[fOperator]+fArg2->Unparse(); |
148 | } | |
149 | return "("+fArg1->Unparse() +" "+opVals[fOperator]+" "+fArg2->Unparse() +")"; | |
150 | } | |
151 | ||
152 | //______________________________________________________________________________ | |
aec0ec32 | 153 | TObjArray* AliRsnExpression::Tokenize(TString str) const |
baca856a | 154 | { |
155 | // tokenize the expression | |
156 | ||
157 | // Remove spaces | |
158 | TString str1; | |
4fbb2459 | 159 | for (Int_t i=0; i<str.Length(); i++) { |
aec0ec32 | 160 | if (str[i] == ' ') continue; |
161 | str1.Append(str[i]); | |
baca856a | 162 | } |
163 | // get variable tokens | |
aec0ec32 | 164 | TObjArray* valtok = str1.Tokenize("!&|()"); |
baca856a | 165 | // put all variables together |
166 | Int_t nvt = valtok->GetEntriesFast(); | |
167 | TString sumval; | |
4fbb2459 | 168 | for (Int_t i=0; i<nvt; i++) { |
aec0ec32 | 169 | TObjString* val = (TObjString*) valtok->At(i); |
170 | sumval.Append(val->String()); | |
baca856a | 171 | } |
172 | // get the operator tokens | |
aec0ec32 | 173 | TObjArray* optok = str1.Tokenize(sumval.Data()); |
baca856a | 174 | // put all operator in one string |
175 | TString operators; | |
176 | Int_t nopt = optok->GetEntriesFast(); | |
4fbb2459 | 177 | for (Int_t i=0; i<nopt; i++) { |
aec0ec32 | 178 | TObjString* val1 = (TObjString*) optok->At(i); |
179 | operators.Append(val1->String()); | |
baca856a | 180 | } |
181 | // add more room to be safe | |
aec0ec32 | 182 | TObjString* blank = new TObjString(" "); |
183 | operators.Append(" "); | |
184 | valtok->AddLast(blank); | |
baca856a | 185 | // Now put var. and oper. together |
aec0ec32 | 186 | TObjArray* tokens = new TObjArray(valtok->GetEntriesFast() + operators.Length()); |
baca856a | 187 | int io = 0,iv = 0; |
188 | int index = 0; | |
4fbb2459 | 189 | while (1) { |
baca856a | 190 | TString so = operators[io]; |
aec0ec32 | 191 | int indexO = str1.Index(so, index); |
192 | TString val2 = ((TObjString*) valtok->At(iv))->String(); | |
193 | int indexV = str1.Index(val2, index); | |
4fbb2459 | 194 | if ((indexO < indexV || indexV < 0) && indexO >=0) { |
aec0ec32 | 195 | tokens->AddLast(new TObjString(so)); |
baca856a | 196 | index += so.Length(); |
197 | io++; | |
198 | } | |
4fbb2459 | 199 | if ((indexV < indexO || indexO < 0) && indexV >=0) { |
aec0ec32 | 200 | tokens->AddLast(new TObjString(val2)); |
baca856a | 201 | index += val2.Length(); |
202 | iv++; | |
203 | } | |
aec0ec32 | 204 | if (index >= str1.Length()) break; |
baca856a | 205 | } |
206 | ||
207 | // // Debug -> Print the tokens | |
208 | // Int_t nt = tokens->GetEntriesFast(); | |
209 | // for ( Int_t i=0; i<nt; i++ ) | |
210 | // { | |
211 | // TObjString* val3 = ( TObjString* ) tokens->At ( i ); | |
212 | // AliInfo ( Form ( "%d %s",i,val3->String().Data() ) ); | |
213 | // } | |
8ecf98c4 | 214 | // |
215 | // | |
baca856a | 216 | delete valtok; |
217 | delete optok; | |
218 | ||
219 | return tokens; | |
220 | } | |
221 | ||
222 | ||
223 | //______________________________________________________________________________ | |
aec0ec32 | 224 | AliRsnExpression* AliRsnExpression::Element(TObjArray &st, Int_t &i) |
baca856a | 225 | { |
226 | // create an element | |
227 | ||
228 | AliRsnExpression* result = 0; | |
229 | ||
230 | Int_t nt = st.GetEntriesFast(); | |
231 | TString token = "@"; | |
232 | TObjString* valt; | |
233 | // next token | |
4fbb2459 | 234 | if (i < nt-1) { |
baca856a | 235 | i++; |
aec0ec32 | 236 | valt = (TObjString*) st.At(i); |
baca856a | 237 | token = valt->String(); |
238 | } | |
239 | // token type | |
aec0ec32 | 240 | char ttok = (token[0]!='|' && token[0]!='&' && |
241 | token[0]!='!' && token[0]!='('&& token[0]!=')') ? 'w' : token[0]; | |
4fbb2459 | 242 | switch (ttok) { |
243 | case 'w' : { | |
aec0ec32 | 244 | result = new AliRsnVariableExpression(token); |
baca856a | 245 | break; |
246 | } | |
4fbb2459 | 247 | case '(' : |
248 | result = Expression(st, i); | |
249 | // next token | |
250 | if (i < nt-1) { | |
251 | i++; | |
252 | valt = (TObjString*) st.At(i); | |
253 | token = valt->String(); | |
254 | } | |
255 | if (token[0] != ')') { | |
256 | // i--; // push back | |
257 | AliErrorGeneral("AliRsnExpression::Element", "Mismatched parenthesis."); | |
258 | delete result; | |
baca856a | 259 | result = new AliRsnExpression; |
4fbb2459 | 260 | } |
261 | break; | |
262 | default: | |
263 | i--; // push back | |
264 | AliErrorGeneral("AliRsnExpression::Element", Form("Unexpected symbol on input. %s", token.Data())); | |
265 | if (result) delete result; | |
266 | result = new AliRsnExpression; | |
baca856a | 267 | } |
268 | return result; | |
269 | } | |
270 | ||
271 | //______________________________________________________________________________ | |
aec0ec32 | 272 | AliRsnExpression* AliRsnExpression::Primary(TObjArray &st, Int_t &i) |
baca856a | 273 | { |
274 | // create a primary | |
275 | ||
276 | Int_t nt = st.GetEntriesFast(); | |
277 | TString token = "@"; | |
278 | TObjString* valt; | |
279 | // next token | |
4fbb2459 | 280 | if (i < nt-1) { |
baca856a | 281 | i++; |
aec0ec32 | 282 | valt = (TObjString*) st.At(i); |
baca856a | 283 | token = valt->String(); |
284 | } | |
285 | ||
4fbb2459 | 286 | switch (token[0]) { |
287 | case '!' : | |
288 | return new AliRsnExpression(kOpNOT, Primary(st, i)); | |
289 | default: | |
290 | i--; // push back | |
291 | return Element(st, i); | |
baca856a | 292 | } |
293 | } | |
294 | ||
295 | //______________________________________________________________________________ | |
aec0ec32 | 296 | AliRsnExpression* AliRsnExpression::Expression(TObjArray &st,Int_t &i) |
baca856a | 297 | { |
298 | // create an expression | |
299 | ||
300 | AliRsnExpression* result = 0; | |
301 | Bool_t done = kFALSE; | |
302 | TString token; | |
303 | TObjString* valt; | |
304 | ||
305 | static int stack = 0; | |
306 | stack++; | |
307 | Int_t nt = st.GetEntriesFast(); | |
308 | ||
aec0ec32 | 309 | result = Primary(st, i); |
baca856a | 310 | // cout <<"i "<<i<< "Primary " << result->Unparse() << endl; |
4fbb2459 | 311 | while (! done) { |
baca856a | 312 | // next token |
aec0ec32 | 313 | if (i < nt-1) i++; |
baca856a | 314 | else break; |
aec0ec32 | 315 | valt = (TObjString*) st.At(i); |
baca856a | 316 | token = valt->String(); |
4fbb2459 | 317 | switch (token[0]) { |
318 | case '&' : | |
319 | result = new AliRsnExpression(kOpAND, result, Primary(st, i)); | |
baca856a | 320 | // cout <<"i "<<i<< " Expression AND " << result->Unparse() << endl; |
4fbb2459 | 321 | break; |
322 | case '|' : | |
323 | result = new AliRsnExpression(kOpOR, result, Primary(st, i)); | |
baca856a | 324 | // cout <<"i "<<i<< " Expression OR " << result->Unparse() << endl; |
4fbb2459 | 325 | break; |
326 | default: | |
327 | done = kTRUE; | |
328 | i--; // push back | |
329 | break; | |
baca856a | 330 | } |
331 | } | |
332 | stack--; | |
4fbb2459 | 333 | if (stack == 0 && !token.IsNull() && token[0] == ')') { |
aec0ec32 | 334 | AliErrorGeneral("AliRsnExpression::Expression", "To many closing parenthesis."); |
baca856a | 335 | delete result; |
336 | result = new AliRsnExpression; | |
4fbb2459 | 337 | } else |
338 | if (stack == 0 && i< nt-1) { | |
aec0ec32 | 339 | AliErrorGeneral("AliRsnExpression::Expression", Form("Unexpected symbol on input. %s", token.Data())); |
baca856a | 340 | delete result; |
341 | result = new AliRsnExpression; | |
342 | } | |
343 | return result; | |
344 | } |