1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // AliExpression Class // //
22 // Helper class to evaluate the condition expressions in //
23 // AliTrigger* classes //
24 // Implements a simple recursive-descent parser //
26 ///////////////////////////////////////////////////////////////////////////////
28 //#include <Riostream.h>
30 #include <TObjString.h>
31 #include <TObjArray.h>
34 #include "AliExpression.h"
35 #include "AliTriggerInput.h"
37 ClassImp( AliExpression )
39 //______________________________________________________________________________
40 AliExpression::AliExpression( TString exp ) :
47 // Default constructor
48 TObjArray* tokens = Tokenize( exp );
51 AliExpression* e = Expression( *tokens, i );
53 fArg1 = e->fArg1; e->fArg1 = 0;
54 fArg2 = e->fArg2; e->fArg2 = 0;
55 fOperator = e->fOperator;
61 //______________________________________________________________________________
62 AliExpression::~AliExpression()
64 if( fArg1 ) delete fArg1;
65 if( fArg2 ) delete fArg2;
68 //______________________________________________________________________________
69 AliExpression& AliExpression::operator=(const AliExpression& e)
71 // AliExpression assignment operator.
74 TObject::operator=(e);
77 fOperator = e.fOperator;
83 //______________________________________________________________________________
84 AliExpression::AliExpression( int op, AliExpression* a, AliExpression* b ) :
91 // Create a new expression
94 //______________________________________________________________________________
95 AliExpression::AliExpression( int op, AliExpression* a ) :
102 // Create a unary expression.
105 //______________________________________________________________________________
106 Bool_t AliExpression::Value( const TObjArray &vars )
108 // Evaluate the expression
109 if ( ( fArg2 == 0 && fVname.IsNull() ) ||
110 ( fArg2 == 0 && ( fOperator == kOpOR || fOperator == kOpAND || fOperator == kOpNOT ) ) ) {
111 AliError( "Expression undefined." );
118 return fArg1->Value(vars) || fArg2->Value(vars);
121 return fArg1->Value(vars) && fArg2->Value(vars);
124 return !(fArg2->Value(vars));
128 TObject* dd = vars.FindObject( fVname.Data() );
130 AliError( fVname + " is undefined" );
133 return ((AliTriggerInput*)dd)->GetValue();
137 AliError( "Illegal operator in expression!");
144 //______________________________________________________________________________
145 TString AliExpression::Unparse() const
147 // Unparse the expression
149 TString opVals[4] = { "", "&", "|","!" };
150 if ( fArg2 == 0 && fVname.IsNull() ) {
151 AliError( "Expression undefined." );
155 if( fArg2 == 0 && !fVname.IsNull() ) return fVname;
157 if (fArg1 == 0 && fArg2) {
158 return opVals[fOperator]+fArg2->Unparse();
160 return "("+fArg1->Unparse()+" "+opVals[fOperator]+" "+fArg2->Unparse()+")";
163 //______________________________________________________________________________
164 TObjArray* AliExpression::Tokenize( TString str ) const
166 // tokenize the expression
170 for( Int_t i=0; i<str.Length(); i++ ) {
171 if( str[i] == ' ' ) continue;
172 str1.Append( str[i] );
174 // get variable tokens
175 TObjArray* valtok = str1.Tokenize( "!&|()" );
176 // put all variables together
177 Int_t nvt = valtok->GetEntriesFast();
179 for( Int_t i=0; i<nvt; i++ ) {
180 TObjString* val = (TObjString*)valtok->At( i );
181 sumval.Append( val->String() );
183 // get the operator tokens
184 TObjArray* optok = str1.Tokenize( sumval.Data() );
185 // put all operator in one string
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() );
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() );
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();
210 if( (indexV < indexO || indexO < 0) && indexV >=0 ) {
211 tokens->AddLast( new TObjString( val2 ) );
212 index += val2.Length();
215 if( index >= str1.Length() ) break;
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;
231 //______________________________________________________________________________
232 AliExpression* AliExpression::Element( TObjArray &st, Int_t &i )
236 AliExpression* result = 0;
238 Int_t nt = st.GetEntriesFast();
244 valt = (TObjString*)st.At( i );
245 token = valt->String();
248 char ttok = ( token[0]!='|' && token[0]!='&' &&
249 token[0]!='!' && token[0]!='('&& token[0]!=')') ? 'w' : token[0];
252 result = new AliVariableExpression( token );
255 result = Expression(st, i);
259 valt = (TObjString*)st.At( i );
260 token = valt->String();
262 if( token[0] != ')' ) {
264 AliErrorGeneral( "AliExpression::Element", "Mismatched parenthesis." );
266 result = new AliExpression;
271 AliErrorGeneral( "AliExpression::Element", Form("Unexpected symbol on input. %s", token.Data()) );
272 result = new AliExpression;
277 //______________________________________________________________________________
278 AliExpression* AliExpression::Primary( TObjArray &st, Int_t &i )
282 Int_t nt = st.GetEntriesFast();
288 valt = (TObjString*)st.At( i );
289 token = valt->String();
294 return new AliExpression( kOpNOT, Primary( st, i ) );
297 return Element( st, i );
301 //______________________________________________________________________________
302 AliExpression* AliExpression::Expression( TObjArray &st,Int_t &i )
304 // create an expression
306 AliExpression* result = 0;
307 Bool_t done = kFALSE;
311 static int stack = 0;
313 Int_t nt = st.GetEntriesFast();
315 result = Primary( st, i );
316 // cout <<"i "<<i<< "Primary " << result->Unparse() << endl;
321 valt = (TObjString*)st.At( i );
322 token = valt->String();
325 result = new AliExpression( kOpAND, result, Primary( st, i ) );
326 // cout <<"i "<<i<< " Expression AND " << result->Unparse() << endl;
329 result = new AliExpression( kOpOR, result, Primary( st, i ) );
330 // cout <<"i "<<i<< " Expression OR " << result->Unparse() << endl;
339 if( stack == 0 && !token.IsNull() && token[0] == ')' ) {
340 AliErrorGeneral( "AliExpression::Expression", "To many closing parenthesis." );
342 result = new AliExpression;
344 if( stack == 0 && i< nt-1 ) {
345 AliErrorGeneral( "AliExpression::Expression", Form( "Unexpected symbol on input. %s", token.Data() ) );
347 result = new AliExpression;
352 ////////////////////////////////////////////////////////////////////////////////
354 ClassImp( AliVariableExpression )
356 //______________________________________________________________________________
357 Bool_t AliVariableExpression::Value( const TObjArray& pgm )
360 TObject* dd = pgm.FindObject( fVname.Data() );
362 AliError( fVname + " is undefined" );
365 return ((AliTriggerInput*)dd)->GetValue();