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