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