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