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