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