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