ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//  AliExpression Class                                                      //                                                                           //
//                                                                           //
//  Helper class to evaluate the condition expressions in                    //
//  AliTrigger* classes                                                      //
//  Implements a simple recursive-descent parser                             //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

//#include <Riostream.h>
#include <TString.h>
#include <TObjString.h>
#include <TObjArray.h>

#include "AliLog.h"
#include "AliExpression.h"
#include "AliTriggerInput.h"

ClassImp( AliExpression )

//______________________________________________________________________________
AliExpression::AliExpression( TString exp ) :
  TObject(),
  fVname(""),
  fArg1(0x0),
  fArg2(0x0),
  fOperator(0)
{
   // Default constructor
   TObjArray* tokens = Tokenize( exp );

   Int_t i = -1;
   AliExpression* e = Expression( *tokens, i );
   // Copy !!!
   fArg1 = e->fArg1; e->fArg1 = 0;
   fArg2 = e->fArg2; e->fArg2 = 0;
   fOperator = e->fOperator;
   fVname = e->fVname;
   delete e;
   delete tokens;
}

//______________________________________________________________________________
AliExpression::~AliExpression()
{
   if( fArg1 ) delete fArg1;
   if( fArg2 ) delete fArg2;
}

//______________________________________________________________________________
AliExpression& AliExpression::operator=(const AliExpression& e)
{
   // AliExpression assignment operator.

   if( this != &e ) {
      TObject::operator=(e);
      fArg1 = e.fArg1;
      fArg2 = e.fArg2;
      fOperator = e.fOperator;
      fVname = e.fVname;
   }
   return *this;
}

//______________________________________________________________________________
AliExpression::AliExpression( int op, AliExpression* a, AliExpression* b ) :
  TObject(),
  fVname(""),
  fArg1(a),
  fArg2(b),
  fOperator(op)
{
   // Create a new expression
}

//______________________________________________________________________________
AliExpression::AliExpression( int op, AliExpression* a ) :
  TObject(),
  fVname(""),
  fArg1(0),
  fArg2(a),
  fOperator(op)
{
   // Create a unary expression.
}

//______________________________________________________________________________
Bool_t AliExpression::Value( const TObjArray &vars )
{
   //  Evaluate the expression
  if ( ( fArg2 == 0 && fVname.IsNull() ) ||
       ( fArg2 == 0 && ( fOperator == kOpOR || fOperator == kOpAND || fOperator == kOpNOT ) ) ) {
       AliError( "Expression undefined." );
       return kFALSE;
   }

   switch (fOperator) {

      case kOpOR :
          return fArg1->Value(vars) || fArg2->Value(vars);

      case kOpAND :
          return fArg1->Value(vars) && fArg2->Value(vars);

      case kOpNOT :
          return !(fArg2->Value(vars));

      case 0 :
	{
          TObject* dd = vars.FindObject( fVname.Data() );
          if( dd == NULL ) {
             AliError( fVname + " is undefined" );
             return 0;
          }
          return ((AliTriggerInput*)dd)->GetValue();
	}

      default:
          AliError( "Illegal operator in expression!");

   }
   return kFALSE;
}


//______________________________________________________________________________
TString AliExpression::Unparse() const
{
   // Unparse the expression

   TString opVals[4] = { "", "&", "|","!" };
   if ( fArg2 == 0 && fVname.IsNull() ) {
      AliError( "Expression undefined." );
      return "Error";
   }

   if( fArg2 == 0 && !fVname.IsNull() ) return fVname;

   if (fArg1 == 0 && fArg2) {
      return opVals[fOperator]+fArg2->Unparse();
   }
   return "("+fArg1->Unparse()+" "+opVals[fOperator]+" "+fArg2->Unparse()+")";
}

//______________________________________________________________________________
TObjArray* AliExpression::Tokenize( TString str ) const
{
   // tokenize the expression

   // Remove spaces
   TString str1;
   for( Int_t i=0; i<str.Length(); i++ ) {
      if( str[i] == ' ' ) continue;
      str1.Append( str[i] );
   }
   // get variable tokens
   TObjArray* valtok = str1.Tokenize( "!&|()" );
   // put all variables together
   Int_t nvt = valtok->GetEntriesFast();
   TString sumval;
   for( Int_t i=0; i<nvt; i++ ) {
      TObjString* val = (TObjString*)valtok->At( i );
      sumval.Append( val->String() );
   }
   // get the operator tokens
   TObjArray* optok = str1.Tokenize( sumval.Data() );
   // put all operator in one string
   TString operators;
   Int_t nopt = optok->GetEntriesFast();
   for( Int_t i=0; i<nopt; i++ ) {
      TObjString* val1 = (TObjString*)optok->At( i );
      operators.Append( val1->String() );
   }
   // add more room to be safe
   TObjString* blank = new TObjString(" ");
   operators.Append( " " );
   valtok->AddLast( blank );
   // Now put var. and oper. together
   TObjArray* tokens = new TObjArray( valtok->GetEntriesFast() + operators.Length() );
   int io = 0,iv = 0;
   int index = 0;
   while( 1 ) {
      TString so = operators[io];
      int indexO = str1.Index( so, index );
      TString val2 = ((TObjString*)valtok->At( iv ))->String();
      int indexV = str1.Index( val2, index );
      if( (indexO < indexV || indexV < 0) && indexO >=0 ) {
         tokens->AddLast( new TObjString( so ) );
         index += so.Length();
         io++;
      }
      if( (indexV < indexO || indexO < 0) && indexV >=0 ) {
         tokens->AddLast( new TObjString( val2 ) );
         index += val2.Length();
         iv++;
      }
      if( index >= str1.Length() ) break;
   }

//  Debug -> Print the tokens
//   Int_t nt = tokens->GetEntriesFast();
//   for( Int_t i=0; i<nt; i++ ) {
//      TObjString* val3 = (TObjString*)tokens->At( i );
//      cout << i << " " << val3->String() << endl;
//   }
   delete valtok;
   delete optok;

   return tokens;
}


//______________________________________________________________________________
AliExpression* AliExpression::Element( TObjArray &st, Int_t &i )
{
   // create an element
   
   AliExpression* result = 0;

   Int_t nt = st.GetEntriesFast();
   TString token = "@";
   TObjString* valt;
   // next token
   if( i < nt-1 ) {
      i++;
      valt = (TObjString*)st.At( i );
      token = valt->String();
   }
   // token type
   char ttok = ( token[0]!='|' && token[0]!='&' &&
                 token[0]!='!' && token[0]!='('&& token[0]!=')') ? 'w' : token[0];
   switch( ttok ) {
      case 'w' :
          result = new AliVariableExpression( token );
          break;
      case '(' :
          result = Expression(st, i);
            // next token
          if( i < nt-1 ) {
             i++;
             valt = (TObjString*)st.At( i );
             token = valt->String();
          }
          if( token[0] != ')' ) {
       //       i--; // push back
              AliErrorGeneral( "AliExpression::Element", "Mismatched parenthesis." );
              delete result;
              result = new AliExpression;
          }
          break;
      default:
          i--; // push back
          AliErrorGeneral( "AliExpression::Element", Form("Unexpected symbol on input. %s", token.Data()) );
          result = new AliExpression;
   }
   return result;
}

//______________________________________________________________________________
AliExpression* AliExpression::Primary( TObjArray &st, Int_t &i )
{
   // create a primary
   
   Int_t nt = st.GetEntriesFast();
   TString token = "@";
   TObjString* valt;
   // next token
   if( i < nt-1 ) {
      i++;
      valt = (TObjString*)st.At( i );
      token = valt->String();
   }

   switch (token[0]) {
       case '!' :
           return new AliExpression( kOpNOT, Primary( st, i ) );
       default:
           i--; // push back
           return Element( st, i );
   }
}

//______________________________________________________________________________
AliExpression* AliExpression::Expression( TObjArray &st,Int_t &i )
{
   // create an expression
   
   AliExpression* result = 0;
   Bool_t done = kFALSE;
   TString token;
   TObjString* valt;

   static int stack = 0;
   stack++;
   Int_t nt = st.GetEntriesFast();

   result = Primary( st, i );
//   cout <<"i "<<i<< "Primary " << result->Unparse() << endl;
   while (! done) {
      // next token
      if( i < nt-1 ) i++;
      else break;
      valt = (TObjString*)st.At( i );
      token = valt->String();
      switch (token[0]) {
         case '&' :
             result = new AliExpression( kOpAND, result, Primary( st, i ) );
//   cout <<"i "<<i<< " Expression AND " << result->Unparse() << endl;
             break;
         case '|' :
             result = new AliExpression( kOpOR, result, Primary( st, i ) );
//   cout <<"i "<<i<< " Expression OR " << result->Unparse() << endl;
             break;
         default:
             done = kTRUE;
             i--; // push back
             break;
      }
   }
   stack--;
   if( stack == 0 && !token.IsNull() && token[0] == ')' ) {
      AliErrorGeneral( "AliExpression::Expression", "To many closing parenthesis." );
      delete result;
      result = new AliExpression;
   } else 
   if( stack == 0 && i< nt-1 ) {
      AliErrorGeneral( "AliExpression::Expression", Form( "Unexpected symbol on input. %s", token.Data() ) );
      delete result;
      result = new AliExpression;
   }
   return result;
}

////////////////////////////////////////////////////////////////////////////////

ClassImp( AliVariableExpression )

//______________________________________________________________________________
Bool_t AliVariableExpression::Value( const TObjArray& pgm )
{
   // return the value
   TObject* dd = pgm.FindObject( fVname.Data() );
   if( dd == NULL ) {
      AliError( fVname + " is undefined" );
      return 0;
   }
   return ((AliTriggerInput*)dd)->GetValue();
}

 AliExpression.cxx:1
 AliExpression.cxx:2
 AliExpression.cxx:3
 AliExpression.cxx:4
 AliExpression.cxx:5
 AliExpression.cxx:6
 AliExpression.cxx:7
 AliExpression.cxx:8
 AliExpression.cxx:9
 AliExpression.cxx:10
 AliExpression.cxx:11
 AliExpression.cxx:12
 AliExpression.cxx:13
 AliExpression.cxx:14
 AliExpression.cxx:15
 AliExpression.cxx:16
 AliExpression.cxx:17
 AliExpression.cxx:18
 AliExpression.cxx:19
 AliExpression.cxx:20
 AliExpression.cxx:21
 AliExpression.cxx:22
 AliExpression.cxx:23
 AliExpression.cxx:24
 AliExpression.cxx:25
 AliExpression.cxx:26
 AliExpression.cxx:27
 AliExpression.cxx:28
 AliExpression.cxx:29
 AliExpression.cxx:30
 AliExpression.cxx:31
 AliExpression.cxx:32
 AliExpression.cxx:33
 AliExpression.cxx:34
 AliExpression.cxx:35
 AliExpression.cxx:36
 AliExpression.cxx:37
 AliExpression.cxx:38
 AliExpression.cxx:39
 AliExpression.cxx:40
 AliExpression.cxx:41
 AliExpression.cxx:42
 AliExpression.cxx:43
 AliExpression.cxx:44
 AliExpression.cxx:45
 AliExpression.cxx:46
 AliExpression.cxx:47
 AliExpression.cxx:48
 AliExpression.cxx:49
 AliExpression.cxx:50
 AliExpression.cxx:51
 AliExpression.cxx:52
 AliExpression.cxx:53
 AliExpression.cxx:54
 AliExpression.cxx:55
 AliExpression.cxx:56
 AliExpression.cxx:57
 AliExpression.cxx:58
 AliExpression.cxx:59
 AliExpression.cxx:60
 AliExpression.cxx:61
 AliExpression.cxx:62
 AliExpression.cxx:63
 AliExpression.cxx:64
 AliExpression.cxx:65
 AliExpression.cxx:66
 AliExpression.cxx:67
 AliExpression.cxx:68
 AliExpression.cxx:69
 AliExpression.cxx:70
 AliExpression.cxx:71
 AliExpression.cxx:72
 AliExpression.cxx:73
 AliExpression.cxx:74
 AliExpression.cxx:75
 AliExpression.cxx:76
 AliExpression.cxx:77
 AliExpression.cxx:78
 AliExpression.cxx:79
 AliExpression.cxx:80
 AliExpression.cxx:81
 AliExpression.cxx:82
 AliExpression.cxx:83
 AliExpression.cxx:84
 AliExpression.cxx:85
 AliExpression.cxx:86
 AliExpression.cxx:87
 AliExpression.cxx:88
 AliExpression.cxx:89
 AliExpression.cxx:90
 AliExpression.cxx:91
 AliExpression.cxx:92
 AliExpression.cxx:93
 AliExpression.cxx:94
 AliExpression.cxx:95
 AliExpression.cxx:96
 AliExpression.cxx:97
 AliExpression.cxx:98
 AliExpression.cxx:99
 AliExpression.cxx:100
 AliExpression.cxx:101
 AliExpression.cxx:102
 AliExpression.cxx:103
 AliExpression.cxx:104
 AliExpression.cxx:105
 AliExpression.cxx:106
 AliExpression.cxx:107
 AliExpression.cxx:108
 AliExpression.cxx:109
 AliExpression.cxx:110
 AliExpression.cxx:111
 AliExpression.cxx:112
 AliExpression.cxx:113
 AliExpression.cxx:114
 AliExpression.cxx:115
 AliExpression.cxx:116
 AliExpression.cxx:117
 AliExpression.cxx:118
 AliExpression.cxx:119
 AliExpression.cxx:120
 AliExpression.cxx:121
 AliExpression.cxx:122
 AliExpression.cxx:123
 AliExpression.cxx:124
 AliExpression.cxx:125
 AliExpression.cxx:126
 AliExpression.cxx:127
 AliExpression.cxx:128
 AliExpression.cxx:129
 AliExpression.cxx:130
 AliExpression.cxx:131
 AliExpression.cxx:132
 AliExpression.cxx:133
 AliExpression.cxx:134
 AliExpression.cxx:135
 AliExpression.cxx:136
 AliExpression.cxx:137
 AliExpression.cxx:138
 AliExpression.cxx:139
 AliExpression.cxx:140
 AliExpression.cxx:141
 AliExpression.cxx:142
 AliExpression.cxx:143
 AliExpression.cxx:144
 AliExpression.cxx:145
 AliExpression.cxx:146
 AliExpression.cxx:147
 AliExpression.cxx:148
 AliExpression.cxx:149
 AliExpression.cxx:150
 AliExpression.cxx:151
 AliExpression.cxx:152
 AliExpression.cxx:153
 AliExpression.cxx:154
 AliExpression.cxx:155
 AliExpression.cxx:156
 AliExpression.cxx:157
 AliExpression.cxx:158
 AliExpression.cxx:159
 AliExpression.cxx:160
 AliExpression.cxx:161
 AliExpression.cxx:162
 AliExpression.cxx:163
 AliExpression.cxx:164
 AliExpression.cxx:165
 AliExpression.cxx:166
 AliExpression.cxx:167
 AliExpression.cxx:168
 AliExpression.cxx:169
 AliExpression.cxx:170
 AliExpression.cxx:171
 AliExpression.cxx:172
 AliExpression.cxx:173
 AliExpression.cxx:174
 AliExpression.cxx:175
 AliExpression.cxx:176
 AliExpression.cxx:177
 AliExpression.cxx:178
 AliExpression.cxx:179
 AliExpression.cxx:180
 AliExpression.cxx:181
 AliExpression.cxx:182
 AliExpression.cxx:183
 AliExpression.cxx:184
 AliExpression.cxx:185
 AliExpression.cxx:186
 AliExpression.cxx:187
 AliExpression.cxx:188
 AliExpression.cxx:189
 AliExpression.cxx:190
 AliExpression.cxx:191
 AliExpression.cxx:192
 AliExpression.cxx:193
 AliExpression.cxx:194
 AliExpression.cxx:195
 AliExpression.cxx:196
 AliExpression.cxx:197
 AliExpression.cxx:198
 AliExpression.cxx:199
 AliExpression.cxx:200
 AliExpression.cxx:201
 AliExpression.cxx:202
 AliExpression.cxx:203
 AliExpression.cxx:204
 AliExpression.cxx:205
 AliExpression.cxx:206
 AliExpression.cxx:207
 AliExpression.cxx:208
 AliExpression.cxx:209
 AliExpression.cxx:210
 AliExpression.cxx:211
 AliExpression.cxx:212
 AliExpression.cxx:213
 AliExpression.cxx:214
 AliExpression.cxx:215
 AliExpression.cxx:216
 AliExpression.cxx:217
 AliExpression.cxx:218
 AliExpression.cxx:219
 AliExpression.cxx:220
 AliExpression.cxx:221
 AliExpression.cxx:222
 AliExpression.cxx:223
 AliExpression.cxx:224
 AliExpression.cxx:225
 AliExpression.cxx:226
 AliExpression.cxx:227
 AliExpression.cxx:228
 AliExpression.cxx:229
 AliExpression.cxx:230
 AliExpression.cxx:231
 AliExpression.cxx:232
 AliExpression.cxx:233
 AliExpression.cxx:234
 AliExpression.cxx:235
 AliExpression.cxx:236
 AliExpression.cxx:237
 AliExpression.cxx:238
 AliExpression.cxx:239
 AliExpression.cxx:240
 AliExpression.cxx:241
 AliExpression.cxx:242
 AliExpression.cxx:243
 AliExpression.cxx:244
 AliExpression.cxx:245
 AliExpression.cxx:246
 AliExpression.cxx:247
 AliExpression.cxx:248
 AliExpression.cxx:249
 AliExpression.cxx:250
 AliExpression.cxx:251
 AliExpression.cxx:252
 AliExpression.cxx:253
 AliExpression.cxx:254
 AliExpression.cxx:255
 AliExpression.cxx:256
 AliExpression.cxx:257
 AliExpression.cxx:258
 AliExpression.cxx:259
 AliExpression.cxx:260
 AliExpression.cxx:261
 AliExpression.cxx:262
 AliExpression.cxx:263
 AliExpression.cxx:264
 AliExpression.cxx:265
 AliExpression.cxx:266
 AliExpression.cxx:267
 AliExpression.cxx:268
 AliExpression.cxx:269
 AliExpression.cxx:270
 AliExpression.cxx:271
 AliExpression.cxx:272
 AliExpression.cxx:273
 AliExpression.cxx:274
 AliExpression.cxx:275
 AliExpression.cxx:276
 AliExpression.cxx:277
 AliExpression.cxx:278
 AliExpression.cxx:279
 AliExpression.cxx:280
 AliExpression.cxx:281
 AliExpression.cxx:282
 AliExpression.cxx:283
 AliExpression.cxx:284
 AliExpression.cxx:285
 AliExpression.cxx:286
 AliExpression.cxx:287
 AliExpression.cxx:288
 AliExpression.cxx:289
 AliExpression.cxx:290
 AliExpression.cxx:291
 AliExpression.cxx:292
 AliExpression.cxx:293
 AliExpression.cxx:294
 AliExpression.cxx:295
 AliExpression.cxx:296
 AliExpression.cxx:297
 AliExpression.cxx:298
 AliExpression.cxx:299
 AliExpression.cxx:300
 AliExpression.cxx:301
 AliExpression.cxx:302
 AliExpression.cxx:303
 AliExpression.cxx:304
 AliExpression.cxx:305
 AliExpression.cxx:306
 AliExpression.cxx:307
 AliExpression.cxx:308
 AliExpression.cxx:309
 AliExpression.cxx:310
 AliExpression.cxx:311
 AliExpression.cxx:312
 AliExpression.cxx:313
 AliExpression.cxx:314
 AliExpression.cxx:315
 AliExpression.cxx:316
 AliExpression.cxx:317
 AliExpression.cxx:318
 AliExpression.cxx:319
 AliExpression.cxx:320
 AliExpression.cxx:321
 AliExpression.cxx:322
 AliExpression.cxx:323
 AliExpression.cxx:324
 AliExpression.cxx:325
 AliExpression.cxx:326
 AliExpression.cxx:327
 AliExpression.cxx:328
 AliExpression.cxx:329
 AliExpression.cxx:330
 AliExpression.cxx:331
 AliExpression.cxx:332
 AliExpression.cxx:333
 AliExpression.cxx:334
 AliExpression.cxx:335
 AliExpression.cxx:336
 AliExpression.cxx:337
 AliExpression.cxx:338
 AliExpression.cxx:339
 AliExpression.cxx:340
 AliExpression.cxx:341
 AliExpression.cxx:342
 AliExpression.cxx:343
 AliExpression.cxx:344
 AliExpression.cxx:345
 AliExpression.cxx:346
 AliExpression.cxx:347
 AliExpression.cxx:348
 AliExpression.cxx:349
 AliExpression.cxx:350
 AliExpression.cxx:351
 AliExpression.cxx:352
 AliExpression.cxx:353
 AliExpression.cxx:354
 AliExpression.cxx:355
 AliExpression.cxx:356
 AliExpression.cxx:357
 AliExpression.cxx:358
 AliExpression.cxx:359
 AliExpression.cxx:360
 AliExpression.cxx:361
 AliExpression.cxx:362
 AliExpression.cxx:363
 AliExpression.cxx:364
 AliExpression.cxx:365
 AliExpression.cxx:366
 AliExpression.cxx:367