ROOT logo
//
// AliRsnExpresion class is used to
// handle operators &|!
// in AliRsnCut
//
// authors: Martin Vala (martin.vala@cern.ch)
//          Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
//

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

#include "AliLog.h"

#include "AliRsnVariableExpression.h"
#include "AliRsnExpression.h"

ClassImp(AliRsnExpression)

AliRsnCutSet *AliRsnExpression::fgCutSet = 0;

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

   Int_t i = -1;
   AliRsnExpression *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;
}

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

AliRsnExpression::AliRsnExpression(const AliRsnExpression &exp) : TObject(exp),
   fVname(exp.fVname),
   fArg1(exp.fArg1),
   fArg2(exp.fArg2),
   fOperator(exp.fOperator)
{}

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

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

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

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

//______________________________________________________________________________
Bool_t AliRsnExpression::Value(TObjArray &vars)
{
   //  Evaluate the expression
   if (fArg2 == 0 && fVname.IsNull()) {
      AliError("Expression undefined.");
      return kFALSE;
   }
   //if (fArg2 == 0) {
   //   AliError("Needed second parameter");
   //   return kFALSE;
   //}

//   AliDebug(AliLog::kDebug,Form("fOperator %d",fOperator));

   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 : {
//       Int_t indexx = fgCutSet->GetIndexByCutName ( fVname.Data() );
         AliDebug(AliLog::kDebug, Form("Vname %s", fVname.Data()));
//       return fgCutSet->GetBoolValue ( indexx );
         return fgCutSet->GetBoolValue(fVname.Atoi());
      }

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

   }
   return kFALSE;
}


//______________________________________________________________________________
TString AliRsnExpression::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 *AliRsnExpression::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 );
//     AliInfo ( Form ( "%d %s",i,val3->String().Data() ) );
//   }
//
//
   delete valtok;
   delete optok;

   return tokens;
}


//______________________________________________________________________________
AliRsnExpression *AliRsnExpression::Element(TObjArray &st, Int_t &i)
{
   // create an element

   AliRsnExpression *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 AliRsnVariableExpression(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("AliRsnExpression::Element", "Mismatched parenthesis.");
            delete result;
            result = new AliRsnExpression;
         }
         break;
      default:
         i--; // push back
         AliErrorGeneral("AliRsnExpression::Element", Form("Unexpected symbol on input. %s", token.Data()));
         //if (result) delete result;
         result = new AliRsnExpression;
   }
   return result;
}

//______________________________________________________________________________
AliRsnExpression *AliRsnExpression::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 AliRsnExpression(kOpNOT, Primary(st, i));
      default:
         i--; // push back
         return Element(st, i);
   }
}

//______________________________________________________________________________
AliRsnExpression *AliRsnExpression::Expression(TObjArray &st, Int_t &i)
{
   // create an expression

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