CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/DataFormats/L1GlobalTrigger/src/L1GtLogicParser.cc

Go to the documentation of this file.
00001 
00017 // this class header
00018 #include "DataFormats/L1GlobalTrigger/interface/L1GtLogicParser.h"
00019 
00020 // system include files
00021 #include <stack>
00022 
00023 #include <iostream>
00024 #include <sstream>
00025 
00026 #include <boost/algorithm/string.hpp>
00027 
00028 // user include files
00029 
00030 
00031 #include "FWCore/Utilities/interface/EDMException.h"
00032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00033 
00034 // forward declarations
00035 
00036 // constructor(s)
00037 
00038 //   default constructor
00039 L1GtLogicParser::L1GtLogicParser() {
00040 
00041     // empty, default C++ initialization for string and vector are enough
00042 }
00043 
00044 
00045 //   from the RPN vector and the operand token vector
00046 //   no checks for consistency, empty logical and numerical expressions
00047 //   requires special care when used
00048 L1GtLogicParser::L1GtLogicParser(const RpnVector& rpnVec,
00049         const std::vector<OperandToken>& opTokenVector)
00050 {
00051     m_rpnVector = rpnVec;
00052     m_operandTokenVector = opTokenVector;
00053 
00054 }
00055 
00056 
00057 //   from a constant logical expression
00058 //   numerical expression will be empty
00059 L1GtLogicParser::L1GtLogicParser(const std::string& logicalExpressionVal)
00060 {
00061 
00062     // checks also for syntactic correctness of the logical expression
00063 
00064     if ( !setLogicalExpression(logicalExpressionVal) ) {
00065 
00066         // error(s) in logical expression - printed in the relevant place
00067         throw cms::Exception("FailModule")
00068         << "\nError in parsing the logical expression = " << logicalExpressionVal
00069         << std::endl;
00070 
00071     }
00072 
00073 }
00074 
00075 //   from a non-constant logical expression - add/remove spaces if needed
00076 //   numerical expression will be empty
00077 L1GtLogicParser::L1GtLogicParser(std::string& logicalExpressionVal)
00078 {
00079 
00080     // checks also for syntactic correctness of the logical expression
00081 
00082     // add spaces around brackets
00083     std::string logicalExpressionBS;
00084     addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
00085 
00086     // trim leading or trailing spaces
00087     boost::trim(logicalExpressionBS);
00088 
00089     if ( !buildRpnVector(logicalExpressionBS) ) {
00090         // error(s) in logical expression
00091         throw cms::Exception("FailModule")
00092         << "\nError in parsing the logical expression = " << logicalExpressionVal
00093         << std::endl;
00094     }
00095 
00096     //LogDebug("L1GtLogicParser")
00097     //    << "\nInitial logical expression = '" << logicalExpressionVal << "'"
00098     //    << "\nFinal   logical expression = '" << logicalExpressionBS << "'\n"
00099     //    << std::endl;
00100 
00101     logicalExpressionVal = logicalExpressionBS;
00102     m_logicalExpression = logicalExpressionVal;
00103 
00104     // build operand token vector
00105     // dummy tokenNumber; tokenResult false
00106     buildOperandTokenVector();
00107 
00108 }
00109 
00110 //   from a logical and a numerical expression
00111 L1GtLogicParser::L1GtLogicParser(const std::string logicalExpressionVal,
00112     const std::string numericalExpressionVal) {
00113     // checks also for correctness
00114 
00115     if ( !setLogicalExpression(logicalExpressionVal) ) {
00116 
00117         // error(s) in logical expression - printed in the relevant place
00118         throw cms::Exception("FailModule")
00119         << "\nError in parsing the logical expression = " << logicalExpressionVal
00120         << std::endl;
00121 
00122     }
00123 
00124     if ( !setNumericalExpression(numericalExpressionVal) ) {
00125 
00126         // error(s) in numerical expression - printed in the relevant place
00127         throw cms::Exception("FileModule")
00128         << "\nError in parsing the numerical expression = " << numericalExpressionVal
00129         << std::endl;
00130     }
00131 
00132 }
00133 
00134 //   from a logical and a numerical expression
00135 //   no checks for correctness - use it only after the correctness was tested
00136 L1GtLogicParser::L1GtLogicParser(const std::string& logicalExpressionVal,
00137     const std::string& numericalExpressionVal, const bool dummy) {
00138 
00139     clearRpnVector();
00140     if ( !buildRpnVector(logicalExpressionVal) ) {
00141         throw cms::Exception("FileModule")
00142         << "\nError in building RPN vector for the logical expression = "
00143         << logicalExpressionVal
00144         << std::endl;
00145     }
00146 
00147     m_logicalExpression = logicalExpressionVal;
00148     m_numericalExpression = numericalExpressionVal;
00149 
00150 }
00151 
00152 
00153 // destructor
00154 L1GtLogicParser::~L1GtLogicParser()
00155 {
00156     // empty now
00157 }
00158 
00159 // public methods
00160 
00161 // check a logical expression for correctness - add/remove spaces if needed
00162 bool L1GtLogicParser::checkLogicalExpression(std::string& logicalExpressionVal) {
00163 
00164     // add spaces around brackets
00165     std::string logicalExpressionBS;
00166     addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
00167 
00168     // trim leading or trailing spaces
00169     boost::trim(logicalExpressionBS);
00170 
00171     clearRpnVector();
00172 
00173     if ( !buildRpnVector(logicalExpressionBS) ) {
00174         return false;
00175     }
00176 
00177     LogDebug("L1GtLogicParser") << "\nL1GtLogicParser::checkLogicalExpression - "
00178         << "\nInitial logical expression = '" << logicalExpressionVal << "'"
00179         << "\nFinal   logical expression = '" << logicalExpressionBS << "'\n"
00180         << std::endl;
00181 
00182     logicalExpressionVal = logicalExpressionBS;
00183 
00184 
00185     return true;
00186 
00187 }
00188 
00198 bool L1GtLogicParser::buildRpnVector(const std::string& logicalExpressionVal)
00199 {
00200 
00201     //LogDebug("L1GtLogicParser")
00202     //<< "\nL1GtLogicParser::buildRpnVector - "
00203     //<< "\nLogical expression = '" << logicalExpressionVal << "'\n"
00204     //<< std::endl;
00205 
00206     OperationType actualOperation = OP_NULL;
00207     OperationType lastOperation   = OP_NULL;
00208 
00209     // token as string and as TokenRPN, stack to form the postfix notation
00210     std::string tokenString;
00211     TokenRPN rpnToken;
00212     std::stack<TokenRPN> operatorStack;
00213 
00214     static const std::string whitespaces=" \r\v\n\t";
00215 
00216     // clear possible old rpn vector
00217     clearRpnVector();
00218 
00219     // stringstream to separate all tokens
00220     std::istringstream exprStringStream(logicalExpressionVal);
00221 
00222     while ( !exprStringStream.eof() ) {
00223 
00224         exprStringStream >> std::skipws >> std::ws >> tokenString;
00225 
00226         // skip the end
00227         if (tokenString.find_first_not_of(whitespaces) == std::string::npos ||
00228                 tokenString.length() == 0) {
00229 
00230             //LogTrace("L1GtLogicParser")
00231             //<< "  Break for token string = " << tokenString
00232             //<< std::endl;
00233 
00234             break;
00235         }
00236 
00237         actualOperation = getOperation(tokenString, lastOperation, rpnToken);
00238 
00239         //LogTrace("L1GtLogicParser")
00240         //<< "  Token string = '" << tokenString << "'"
00241         //<< "\tActual Operation = " << actualOperation
00242         //<< std::endl;
00243 
00244         // http://en.wikipedia.org/wiki/Postfix_notation#Converting_from_infix_notation
00245 
00246         switch (actualOperation) {
00247             case OP_OPERAND: {
00248                     // operands get pushed to the postfix notation immediately
00249                     m_rpnVector.push_back(rpnToken);
00250                 }
00251 
00252                 break;
00253             case OP_INVALID: {
00254 
00255                     int errorPosition = exprStringStream.tellg();
00256 
00257 
00258                     edm::LogError("L1GtLogicParser")
00259                     << "\nLogical expression = '" << logicalExpressionVal << "'"
00260                     << "\n  Syntax error during parsing: "
00261                     << "\n     " << exprStringStream.str().substr(0,errorPosition)
00262                     << "\n     " << exprStringStream.str().substr(errorPosition)
00263                     << "\n  Returned empty RPN vector and result false."
00264                     << std::endl;
00265 
00266                     // clear the rpn vector before returning
00267                     clearRpnVector();
00268 
00269                     return false;
00270                 }
00271 
00272                 break;
00273             case OP_NOT: {
00274                     operatorStack.push(rpnToken);
00275                     // there are no operators with higher precedence
00276                 }
00277 
00278                 break;
00279             case OP_AND: {
00280                     // first pop operators with higher precedence (NOT)
00281                     while (!operatorStack.empty() && operatorStack.top().operation == OP_NOT) {
00282                         m_rpnVector.push_back(operatorStack.top());
00283                         operatorStack.pop();
00284                     }
00285                     operatorStack.push(rpnToken);
00286                 }
00287 
00288                 break;
00289             case OP_OR: {
00290                     // pop operators with higher precedence (AND, NOT)
00291                     while (!operatorStack.empty() &&
00292                             (operatorStack.top().operation == OP_NOT ||
00293                              operatorStack.top().operation == OP_AND)  ) {
00294 
00295                         m_rpnVector.push_back(operatorStack.top());
00296                         operatorStack.pop();
00297                     }
00298                     // push operator on stack
00299                     operatorStack.push(rpnToken);
00300                 }
00301 
00302                 break;
00303             case OP_OPENBRACKET: {
00304 
00305                     // just push it on stack
00306                     operatorStack.push(rpnToken);
00307                 }
00308 
00309                 break;
00310             case OP_CLOSEBRACKET: {
00311                     // check if the operatorStack is empty
00312                     if (operatorStack.empty()) {
00313 
00314                         int errorPosition = exprStringStream.tellg();
00315 
00316                         edm::LogError("L1GtLogicParser")
00317                         << "\nLogical expression = '" << logicalExpressionVal << "'"
00318                         << "\n  Syntax error during parsing - misplaced ')':"
00319                         << "\n     " << exprStringStream.str().substr(0,errorPosition)
00320                         << "\n     " << exprStringStream.str().substr(errorPosition)
00321                         << "\n  Returned empty RPN vector and result false."
00322                         << std::endl;
00323 
00324                         // clear the rpn vector before returning
00325                         clearRpnVector();
00326 
00327                         return false;
00328                     }
00329 
00330                     // pop stack until a left parenthesis is found
00331                     do {
00332                         if (operatorStack.top().operation != OP_OPENBRACKET) {
00333                             m_rpnVector.push_back(operatorStack.top()); // pop
00334                             operatorStack.pop();
00335                         }
00336                         if (operatorStack.empty()) { // the operatorStack must not be empty
00337 
00338                             int errorPosition = exprStringStream.tellg();
00339 
00340                             edm::LogError("L1GtLogicParser")
00341                             << "\nLogical expression = '" << logicalExpressionVal << "'"
00342                             << "\n  Syntax error during parsing - misplaced ')':"
00343                             << "\n     " << exprStringStream.str().substr(0,errorPosition)
00344                             << "\n     " << exprStringStream.str().substr(errorPosition)
00345                             << "\n  Returned empty RPN vector and result false."
00346                             << std::endl;
00347 
00348                             // clear the rpn vector before returning
00349                             clearRpnVector();
00350                             return false;
00351                         }
00352                     } while (operatorStack.top().operation != OP_OPENBRACKET);
00353 
00354                     operatorStack.pop(); // pop the open bracket.
00355                 }
00356 
00357                 break;
00358             default: {
00359                     // empty
00360                 }
00361                 break;
00362         }
00363 
00364         lastOperation = actualOperation;    // for the next turn
00365 
00366     }
00367 
00368     // pop the rest of the operator stack
00369     while (!operatorStack.empty()) {
00370         if (operatorStack.top().operation == OP_OPENBRACKET) {
00371 
00372             edm::LogError("L1GtLogicParser")
00373             << "\nLogical expression = '" << logicalExpressionVal << "'"
00374             << "\n  Syntax error during parsing - missing ')':"
00375             << "\n  Returned empty RPN vector and result false."
00376             << std::endl;
00377 
00378             // clear the rpn vector before returning
00379             clearRpnVector();
00380             return false;
00381         }
00382 
00383         m_rpnVector.push_back(operatorStack.top());
00384         operatorStack.pop();
00385     }
00386 
00387     // count all operations and check if the result is 1
00388     int counter = 0;
00389     for(RpnVector::iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
00390         if (it->operation == OP_OPERAND)
00391             counter++;
00392         if (it->operation == OP_OR || it->operation == OP_AND)
00393             counter--;
00394         if (counter < 1) {
00395 
00396             edm::LogError("L1GtLogicParser")
00397             << "\nLogical expression = '" << logicalExpressionVal << "'"
00398             << "\n  Syntax error during parsing - too many operators"
00399             << "\n  Returned empty RPN vector and result false."
00400             << std::endl;
00401 
00402             // clear the rpn vector before returning
00403             clearRpnVector();
00404             return false;
00405         }
00406     }
00407 
00408     if (counter > 1) {
00409 
00410         edm::LogError("L1GtLogicParser")
00411         << "\nLogical expression = '" << logicalExpressionVal << "'"
00412         << "\n  Syntax error during parsing - too many operands"
00413         << "\n  Returned empty RPN vector and result false."
00414         << std::endl;
00415 
00416         // clear the rpn vector before returning
00417         clearRpnVector();
00418         return false;
00419     }
00420 
00421     return true;
00422 }
00423 
00424 
00425 // clear rpn vector
00426 void L1GtLogicParser::clearRpnVector()
00427 {
00428 
00429     m_rpnVector.clear();
00430 
00431 }
00432 
00433 
00434 // build from the RPN vector the operand token vector
00435 // dummy tokenNumber and token result
00436 void L1GtLogicParser::buildOperandTokenVector()
00437 {
00438 
00439     //LogTrace("L1GtLogicParser")
00440     //<< "\nL1GtLogicParser::buildOperandTokenVector - "
00441     //<< std::endl;
00442 
00443     // reserve memory
00444     size_t rpnVectorSize = m_rpnVector.size();
00445     m_operandTokenVector.reserve(rpnVectorSize);
00446 
00447     int opNumber = 0;
00448 
00449     for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
00450 
00451         //LogTrace("L1GtLogicParser")
00452         //<< "\nit->operation = " << it->operation
00453         //<< "\nit->operand =   '" << it->operand << "'\n"
00454         //<< std::endl;
00455 
00456         switch (it->operation) {
00457 
00458             case OP_OPERAND: {
00459                     OperandToken opToken;
00460                     opToken.tokenName = it->operand;
00461                     opToken.tokenNumber = opNumber;
00462                     opToken.tokenResult = false;
00463 
00464                     m_operandTokenVector.push_back(opToken);
00465 
00466                 }
00467 
00468                 break;
00469             case OP_NOT: {
00470                     // do nothing
00471             }
00472 
00473                 break;
00474             case OP_OR: {
00475                     // do nothing
00476                 }
00477 
00478                 break;
00479             case OP_AND: {
00480                 // do nothing
00481                 }
00482 
00483                 break;
00484             default: {
00485                     // should not arrive here
00486                 }
00487 
00488                 break;
00489         }
00490 
00491         opNumber++;
00492     }
00493 
00494 }
00495 
00496 
00497 // return the position index of the operand in the logical expression
00498 int L1GtLogicParser::operandIndex(const std::string& operandNameVal) const
00499 {
00500 
00501     int result = -1;
00502 
00503     OperationType actualOperation = OP_NULL;
00504     OperationType lastOperation   = OP_NULL;
00505 
00506     std::string tokenString;
00507     TokenRPN rpnToken;           // token to be used by getOperation
00508 
00509     // stringstream to separate all tokens
00510     std::istringstream exprStringStream(m_logicalExpression);
00511 
00512     // temporary index for usage in the loop
00513     int tmpIndex = -1;
00514 
00515     while (!exprStringStream.eof()) {
00516 
00517         exprStringStream >> tokenString;
00518 
00519         //LogTrace("L1GtLogicParser")
00520         //<< "Token string = " << tokenString
00521         //<< std::endl;
00522 
00523         actualOperation = getOperation(tokenString, lastOperation, rpnToken);
00524         if (actualOperation == OP_INVALID) {
00525 
00526             // it should never be invalid
00527             edm::LogError("L1GtLogicParser")
00528             << "\nLogical expression = '" << m_logicalExpression << "'"
00529             << "\n  Invalid operation/operand " << operandNameVal
00530             << "\n  Returned index is by default out of range (-1)."
00531             << std::endl;
00532 
00533             return result;
00534 
00535         }
00536 
00537         if (actualOperation != OP_OPERAND) {
00538 
00539             // do nothing
00540 
00541         } else {
00542 
00543             tmpIndex++;
00544             if (rpnToken.operand == operandNameVal) {
00545                 result = tmpIndex;
00546 
00547                 //LogDebug("L1GtLogicParser")
00548                 //<< "\nL1GtLogicParser::operandIndex - "
00549                 //<< "\nLogical expression = '" << m_logicalExpression << "'"
00550                 //<< "\nIndex of operand " << operandNameVal << " = " << result
00551                 //<< std::endl;
00552 
00553                 return result;
00554             }
00555         }
00556         lastOperation = actualOperation;
00557     }
00558 
00559     //
00560     edm::LogError("L1GtLogicParser")
00561     << "\nLogical expression = '" << m_logicalExpression << "'"
00562     << "\n  Operand " << operandNameVal << " not found in the logical expression"
00563     << "\n  Returned index is by default out of range (-1)."
00564     << std::endl;
00565 
00566     return result;
00567 }
00568 
00569 // return the name of the (iOperand)th operand in the logical expression
00570 std::string L1GtLogicParser::operandName(const int iOperand) const
00571 {
00572 
00573     std::string result;
00574 
00575     OperationType actualOperation = OP_NULL;
00576     OperationType lastOperation   = OP_NULL;
00577 
00578     std::string tokenString;
00579     TokenRPN rpnToken;           // token to be used by getOperation
00580 
00581     // stringstream to separate all tokens
00582     std::istringstream exprStringStream(m_logicalExpression);
00583 
00584     // temporary index for usage in the loop
00585     int tmpIndex = -1;
00586 
00587     while (!exprStringStream.eof()) {
00588 
00589         exprStringStream >> tokenString;
00590 
00591         //LogTrace("L1GtLogicParser")
00592         //<< "Token string = " << tokenString
00593         //<< std::endl;
00594 
00595         actualOperation = getOperation(tokenString, lastOperation, rpnToken);
00596         if (actualOperation == OP_INVALID) {
00597 
00598             // it should never be invalid
00599             edm::LogError("L1GtLogicParser")
00600             << "\nLogical expression = '" << m_logicalExpression << "'"
00601             << "\n  Invalid operation/operand at position " << iOperand
00602             << "\n  Returned empty name by default."
00603             << std::endl;
00604 
00605             return result;
00606 
00607         }
00608 
00609         if (actualOperation != OP_OPERAND) {
00610 
00611             // do nothing
00612 
00613         } else {
00614 
00615             tmpIndex++;
00616             if (tmpIndex == iOperand) {
00617                 result = rpnToken.operand;
00618 
00619                 //LogDebug("L1GtLogicParser")
00620                 //<< "\nL1GtLogicParser::operandName - "
00621                 //<< "\nLogical expression = '" << m_logicalExpression << "'"
00622                 //<< "\nOperand with index " << iOperand << " = " << result
00623                 //<< std::endl;
00624 
00625                 return result;
00626             }
00627         }
00628         lastOperation = actualOperation;
00629     }
00630 
00631     //
00632     edm::LogError("L1GtLogicParser")
00633     << "\nLogical expression = '" << m_logicalExpression << "'"
00634     << "\n  No operand found at position " << iOperand
00635     << "\n  Returned empty name by default."
00636     << std::endl;
00637 
00638     return result;
00639 
00640 }
00641 
00642 // return the result for an operand with name operandNameVal
00643 // in the logical expression using the operand token vector
00644 bool L1GtLogicParser::operandResult(const std::string& operandNameVal) const {
00645 
00646     for (size_t i = 0; i < m_operandTokenVector.size(); ++i) {
00647 
00648         if ((m_operandTokenVector[i]).tokenName == operandNameVal) {
00649             return (m_operandTokenVector[i]).tokenResult;
00650         }
00651     }
00652 
00653     // return false - should not arrive here
00654     edm::LogError("L1GtLogicParser")
00655         << "\n  Operand " << operandNameVal << " not found in the operand token vector"
00656         << "\n  Returned false by default."
00657         << std::endl;
00658 
00659     return false;
00660 
00661 }
00662 
00663 // return the result for an operand with tokenNumberVal
00664 // using the operand token vector
00665 bool L1GtLogicParser::operandResult(const int tokenNumberVal) const {
00666 
00667     for (size_t i = 0; i < m_operandTokenVector.size(); ++i) {
00668 
00669         if ((m_operandTokenVector[i]).tokenNumber == tokenNumberVal) {
00670             return (m_operandTokenVector[i]).tokenResult;
00671         }
00672     }
00673 
00674     // return false - should not arrive here
00675     edm::LogError("L1GtLogicParser")
00676         << "\n  No operand with token number " << tokenNumberVal
00677         << " found in the operand token vector"
00678         << "\n  Returned false by default."
00679         << std::endl;
00680 
00681     return false;
00682 
00683 }
00684 
00685 // return the result for the logical expression
00686 // require a proper operand token vector
00687 const bool L1GtLogicParser::expressionResult() const
00688 {
00689 
00690     //LogTrace("L1GtLogicParser")
00691     //<< "\nL1GtLogicParser::expressionResult - "
00692     //<< std::endl;
00693 
00694     // return false if there is no RPN vector built
00695     if ( m_rpnVector.empty() ) {
00696         edm::LogError("L1GtLogicParser")
00697             << "\n  No built RPN vector exists."
00698             << "\n  Returned false by default."
00699             << std::endl;
00700         return false;
00701     }
00702 
00703     // stack containing temporary results
00704     std::stack<bool> resultStack;
00705     bool b1, b2;
00706 
00707 
00708     for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
00709 
00710         //LogTrace("L1GtLogicParser")
00711         //<< "\nit->operation = " << it->operation
00712         //<< "\nit->operand =   '" << it->operand << "'\n"
00713         //<< std::endl;
00714 
00715         switch (it->operation) {
00716 
00717             case OP_OPERAND: {
00718                     resultStack.push(operandResult(it->operand));
00719                 }
00720 
00721                 break;
00722             case OP_NOT: {
00723                     b1 = resultStack.top();
00724                     resultStack.pop();                          // pop the top
00725                     resultStack.push(!b1);                      // and push the result
00726                 }
00727 
00728                 break;
00729             case OP_OR: {
00730                     b1 = resultStack.top();
00731                     resultStack.pop();
00732                     b2 = resultStack.top();
00733                     resultStack.pop();
00734                     resultStack.push(b1 || b2);
00735                 }
00736 
00737                 break;
00738             case OP_AND: {
00739                     b1 = resultStack.top();
00740                     resultStack.pop();
00741                     b2 = resultStack.top();
00742                     resultStack.pop();
00743                     resultStack.push(b1 && b2);
00744                 }
00745 
00746                 break;
00747             default: {
00748                     // should not arrive here
00749                 }
00750 
00751                 break;
00752         }
00753 
00754     }
00755 
00756     // get the result in the top of the stack
00757 
00758     //LogTrace("L1GtLogicParser")
00759     //<< "\nL1GtLogicParser::expressionResult - "
00760     //<< "\nResult = " << resultStack.top()
00761     //<< std::endl;
00762 
00763     return resultStack.top();
00764 
00765 
00766 }
00767 
00768 
00769 // return the result for an operand with name operandNameVal
00770 // in the logical expression using a numerical expression
00771 bool L1GtLogicParser::operandResultNumExp(const std::string& operandNameVal) const
00772 {
00773 
00774     bool result = false;
00775 
00776     // get the position index of the operand in the logical string
00777     const int iOperand = operandIndex(operandNameVal);
00778 
00779     result = operandResult(iOperand);
00780 
00781     return result;
00782 
00783 }
00784 
00785 // return the result for an operand with index iOperand
00786 // in the logical expression using a numerical expression
00787 bool L1GtLogicParser::operandResultNumExp(const int iOperand) const
00788 {
00789 
00790     bool result = false;
00791 
00792     // parse the numerical expression
00793 
00794     OperationType actualOperation = OP_NULL;
00795     OperationType lastOperation   = OP_NULL;
00796 
00797     std::string tokenString;
00798     TokenRPN rpnToken;           // token to be used by getOperation
00799 
00800     // stringstream to separate all tokens
00801     std::istringstream exprStringStream(m_numericalExpression);
00802 
00803     // temporary index for usage in the loop
00804     int tmpIndex = -1;
00805 
00806     while (!exprStringStream.eof()) {
00807 
00808         exprStringStream >> tokenString;
00809 
00810         //LogTrace("L1GtLogicParser")
00811         //<< "Token string = " << tokenString
00812         //<< std::endl;
00813 
00814         actualOperation = getOperation(tokenString, lastOperation, rpnToken);
00815         if (actualOperation == OP_INVALID) {
00816 
00817             // it should never be invalid
00818             edm::LogError("L1GtLogicParser")
00819             << "\nNumerical expression = '" << m_numericalExpression << "'"
00820             << "\n  Invalid operation/operand at position " << iOperand
00821             << "\n  Returned false by default."
00822             << std::endl;
00823 
00824             result = false;
00825             return result;
00826         }
00827 
00828         if (actualOperation != OP_OPERAND) {
00829 
00830             // do nothing
00831 
00832         } else {
00833 
00834             tmpIndex++;
00835             if (tmpIndex == iOperand) {
00836 
00837                 if (rpnToken.operand == "1") {
00838                     result = true;
00839                 } else {
00840                     if (rpnToken.operand == "0") {
00841                         result = false;
00842                     } else {
00843                         // something went wrong - break
00844                         //
00845                         edm::LogError("L1GtLogicParser")
00846                         << "\nNumerical expression = '" << m_numericalExpression << "'"
00847                         << "\n  Invalid result for operand at position " << iOperand
00848                         << ": " << rpnToken.operand
00849                         << "\n  It must be 0 or 1"
00850                         << "\n  Returned false by default."
00851                         << std::endl;
00852 
00853                         result = false;
00854                         return result;
00855                     }
00856                 }
00857 
00858                 //LogDebug("L1GtLogicParser")
00859                 //<< "\nL1GtLogicParser::operandResult - "
00860                 //<< "\nNumerical expression = '" << m_numericalExpression << "'"
00861                 //<< "\nResult for operand with index " << iOperand
00862                 //<< " = " << result << "'\n"
00863                 //<< std::endl;
00864 
00865                 return result;
00866             }
00867         }
00868         lastOperation = actualOperation;
00869     }
00870 
00871     //
00872     edm::LogError("L1GtLogicParser")
00873     << "\nNumerical expression = '" << m_numericalExpression << "'"
00874     << "\n  No operand found at position " << iOperand
00875     << "\n  Returned false by default."
00876     << std::endl;
00877 
00878     return result;
00879 
00880 
00881 }
00882 
00883 // build from the RPN vector the operand token vector
00884 // using a numerical expression
00885 void L1GtLogicParser::buildOperandTokenVectorNumExp()
00886 {
00887 
00888     //LogTrace("L1GtLogicParser")
00889     //<< "\nL1GtLogicParser::buildOperandTokenVector - "
00890     //<< std::endl;
00891 
00892     // reserve memory
00893     size_t rpnVectorSize = m_rpnVector.size();
00894     m_operandTokenVector.reserve(rpnVectorSize);
00895 
00896     int opNumber = 0;
00897 
00898     for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
00899 
00900         //LogTrace("L1GtLogicParser")
00901         //<< "\nit->operation = " << it->operation
00902         //<< "\nit->operand =   '" << it->operand << "'\n"
00903         //<< std::endl;
00904 
00905         switch (it->operation) {
00906 
00907             case OP_OPERAND: {
00908                     OperandToken opToken;
00909                     opToken.tokenName = it->operand;
00910                     opToken.tokenNumber = opNumber;
00911                     opToken.tokenResult = operandResultNumExp(it->operand);
00912 
00913                     m_operandTokenVector.push_back(opToken);
00914 
00915                 }
00916 
00917                 break;
00918             case OP_NOT: {
00919                     // do nothing
00920             }
00921 
00922                 break;
00923             case OP_OR: {
00924                     // do nothing
00925                 }
00926 
00927                 break;
00928             case OP_AND: {
00929                 // do nothing
00930                 }
00931 
00932                 break;
00933             default: {
00934                     // should not arrive here
00935                 }
00936 
00937                 break;
00938         }
00939 
00940         opNumber++;
00941     }
00942 
00943 }
00944 
00945 
00946 
00947 // return the result for the logical expression
00948 const bool L1GtLogicParser::expressionResultNumExp() const
00949 {
00950 
00951     //LogTrace("L1GtLogicParser")
00952     //<< "\nL1GtLogicParser::expressionResult - "
00953     //<< std::endl;
00954 
00955     // return false if there is no expression
00956     if ( m_rpnVector.empty() ) {
00957         edm::LogError("L1GtLogicParser")
00958             << "\n  No built RPN vector exists."
00959             << "\n  Returned false by default."
00960             << std::endl;
00961         return false;
00962     }
00963 
00964     // stack containing temporary results
00965     std::stack<bool> resultStack;
00966     bool b1, b2;
00967 
00968 
00969     for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
00970 
00971         //LogTrace("L1GtLogicParser")
00972         //<< "\nit->operation = " << it->operation
00973         //<< "\nit->operand =   '" << it->operand << "'\n"
00974         //<< std::endl;
00975 
00976         switch (it->operation) {
00977 
00978             case OP_OPERAND: {
00979                     resultStack.push(operandResultNumExp(it->operand));
00980                 }
00981 
00982                 break;
00983             case OP_NOT: {
00984                     b1 = resultStack.top();
00985                     resultStack.pop();                          // pop the top
00986                     resultStack.push(!b1);                      // and push the result
00987                 }
00988 
00989                 break;
00990             case OP_OR: {
00991                     b1 = resultStack.top();
00992                     resultStack.pop();
00993                     b2 = resultStack.top();
00994                     resultStack.pop();
00995                     resultStack.push(b1 || b2);
00996                 }
00997 
00998                 break;
00999             case OP_AND: {
01000                     b1 = resultStack.top();
01001                     resultStack.pop();
01002                     b2 = resultStack.top();
01003                     resultStack.pop();
01004                     resultStack.push(b1 && b2);
01005                 }
01006 
01007                 break;
01008             default: {
01009                     // should not arrive here
01010                 }
01011 
01012                 break;
01013         }
01014 
01015     }
01016 
01017     // get the result in the top of the stack
01018 
01019     //LogTrace("L1GtLogicParser")
01020     //<< "\nL1GtLogicParser::expressionResult - "
01021     //<< "\nLogical expression   = '" << m_logicalExpression << "'"
01022     //<< "\nNumerical expression = '" << m_numericalExpression << "'"
01023     //<< "\nResult = " << resultStack.top()
01024     //<< std::endl;
01025 
01026     return resultStack.top();
01027 
01028 
01029 }
01030 
01031 // convert the logical expression composed with names to
01032 // a logical expression composed with int numbers using
01033 // a (string, int)  map
01034 
01035 void L1GtLogicParser::convertNameToIntLogicalExpression(
01036     const std::map<std::string, int>& nameToIntMap)
01037 {
01038 
01039 
01040     if (m_logicalExpression.empty()) {
01041 
01042         return;
01043     }
01044 
01045     // non-empty logical expression
01046 
01047     OperationType actualOperation = OP_NULL;
01048     OperationType lastOperation   = OP_NULL;
01049 
01050     std::string tokenString;
01051     TokenRPN rpnToken;           // token to be used by getOperation
01052 
01053     int intValue = -1;
01054 
01055     // stringstream to separate all tokens
01056     std::istringstream exprStringStream(m_logicalExpression);
01057     std::string convertedLogicalExpression;
01058 
01059     while (!exprStringStream.eof()) {
01060 
01061         exprStringStream >> tokenString;
01062 
01063         actualOperation = getOperation(tokenString, lastOperation, rpnToken);
01064         if (actualOperation == OP_INVALID) {
01065 
01066             // it should never be invalid
01067             edm::LogError("L1GtLogicParser")
01068             << "\nLogical expression = '" << m_logicalExpression << "'"
01069             << "\n  Invalid operation/operand in logical expression."
01070             << "\n  Return empty logical expression."
01071             << std::endl;
01072 
01073             m_logicalExpression.clear();
01074             return;
01075 
01076         }
01077 
01078         if (actualOperation != OP_OPERAND) {
01079 
01080             convertedLogicalExpression.append(getRuleFromType(actualOperation)->opString);
01081 
01082         } else {
01083 
01084             typedef std::map<std::string, int>::const_iterator CIter;
01085 
01086             CIter it = nameToIntMap.find(rpnToken.operand);
01087             if (it != nameToIntMap.end()) {
01088 
01089                 intValue = it->second;
01090                 std::stringstream intStr;
01091                 intStr << intValue;
01092                 convertedLogicalExpression.append(intStr.str());
01093 
01094             } else {
01095 
01096                 // it should never be happen
01097                 edm::LogError("L1GtLogicParser")
01098                 << "\nLogical expression = '" << m_logicalExpression << "'"
01099                 << "\n  Could not convert " << rpnToken.operand << " to integer!"
01100                 << "\n  Return empty logical expression."
01101                 << std::endl;
01102 
01103                 m_logicalExpression.clear();
01104                 return;
01105             }
01106 
01107         }
01108 
01109         convertedLogicalExpression.append(" ");   // one whitespace after each token
01110         lastOperation = actualOperation;
01111     }
01112 
01113     // remove the last space
01114     //convertedLogicalExpression.erase(convertedLogicalExpression.size() - 1);
01115     boost::trim(convertedLogicalExpression);
01116 
01117     LogDebug("L1GtLogicParser")
01118     << "\nL1GtLogicParser::convertNameToIntLogicalExpression - "
01119     << "\nLogical expression (strings) = '" << m_logicalExpression << "'"
01120     << "\nLogical expression (int)     = '" << convertedLogicalExpression << "'\n"
01121     << std::endl;
01122 
01123     // replace now the logical expression with strings with
01124     // the converted logical expression
01125 
01126     m_logicalExpression = convertedLogicalExpression;
01127 
01128     return;
01129 
01130 }
01131 
01132 // convert a logical expression composed with integer numbers to
01133 // a logical expression composed with names using a map (int, string)
01134 
01135 void L1GtLogicParser::convertIntToNameLogicalExpression(
01136         const std::map<int, std::string>& intToNameMap) {
01137 
01138     if (m_logicalExpression.empty()) {
01139 
01140         return;
01141     }
01142 
01143     // non-empty logical expression
01144 
01145     OperationType actualOperation = OP_NULL;
01146     OperationType lastOperation = OP_NULL;
01147 
01148     std::string tokenString;
01149     TokenRPN rpnToken; // token to be used by getOperation
01150 
01151     // stringstream to separate all tokens
01152     std::istringstream exprStringStream(m_logicalExpression);
01153     std::string convertedLogicalExpression;
01154 
01155     while (!exprStringStream.eof()) {
01156 
01157         exprStringStream >> tokenString;
01158 
01159         actualOperation = getOperation(tokenString, lastOperation, rpnToken);
01160         if (actualOperation == OP_INVALID) {
01161 
01162             // it should never be invalid
01163             edm::LogError("L1GtLogicParser") << "\nLogical expression = '" << m_logicalExpression
01164                     << "'" << "\n  Invalid operation/operand in logical expression."
01165                     << "\n  Return empty logical expression." << std::endl;
01166 
01167             m_logicalExpression.clear();
01168             return;
01169 
01170         }
01171 
01172         if (actualOperation != OP_OPERAND) {
01173 
01174             convertedLogicalExpression.append(getRuleFromType(actualOperation)->opString);
01175 
01176         } else {
01177 
01178             typedef std::map<int, std::string>::const_iterator CIter;
01179 
01180             // convert string to int
01181             int indexInt;
01182             std::istringstream iss(rpnToken.operand);
01183             iss >> std::dec >> indexInt;
01184 
01185             CIter it = intToNameMap.find(indexInt);
01186             if (it != intToNameMap.end()) {
01187 
01188                 convertedLogicalExpression.append(it->second);
01189 
01190             } else {
01191 
01192                 // it should never be happen
01193                 edm::LogError("L1GtLogicParser") << "\nLogical expression = '"
01194                         << m_logicalExpression << "'" << "\n  Could not convert "
01195                         << rpnToken.operand << " to string!"
01196                         << "\n  Return empty logical expression." << std::endl;
01197 
01198                 m_logicalExpression.clear();
01199                 return;
01200             }
01201 
01202         }
01203 
01204         convertedLogicalExpression.append(" "); // one whitespace after each token
01205         lastOperation = actualOperation;
01206     }
01207 
01208     // remove the last space
01209     //convertedLogicalExpression.erase(convertedLogicalExpression.size() - 1);
01210     boost::trim(convertedLogicalExpression);
01211 
01212     //LogDebug("L1GtLogicParser")
01213     //        << "\nL1GtLogicParser::convertIntToNameLogicalExpression - "
01214     //        << "\nLogical expression (int) =    '" << m_logicalExpression << "'"
01215     //        << "\nLogical expression (string) = '" << convertedLogicalExpression << "'\n"
01216     //        << std::endl;
01217 
01218     // replace now the logical expression with int with
01219     // the converted logical expression
01220 
01221     m_logicalExpression = convertedLogicalExpression;
01222 
01223     return;
01224 
01225 }
01226 
01227 // return the list of operand tokens for the logical expression
01228 // which are to be used as seeds
01229 std::vector<L1GtLogicParser::OperandToken>
01230     L1GtLogicParser::expressionSeedsOperandList() {
01231 
01232     //LogDebug("L1GtLogicParser")
01233     //<< "\nL1GtLogicParser::expressionSeedsOperandList - "
01234     //<< "\nLogical expression = '" << m_logicalExpression << "'"
01235     //<< "\nm_rpnVector.size() = " << m_rpnVector.size()
01236     //<< "\nm_operandTokenVector.size() = " << m_operandTokenVector.size()
01237     //<< std::endl;
01238 
01239     // seed list
01240     std::vector<OperandToken> opVector;
01241     opVector.reserve(m_operandTokenVector.size());
01242 
01243     // temporary results
01244     std::stack<OperandToken> tmpStack;
01245     std::vector<OperandToken> tmpVector;
01246     tmpVector.reserve(m_operandTokenVector.size());
01247 
01248     OperandToken b1, b2;
01249 
01250     bool newOperandBlock = true;
01251     bool oneBlockOnly = true;
01252     bool operandOnly = true;
01253 
01254     int iOperand = -1;
01255 
01256     OperandToken dummyToken;
01257     dummyToken.tokenName = "dummy";
01258     dummyToken.tokenNumber = -1;
01259     dummyToken.tokenResult = false;
01260 
01261     for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
01262 
01263         //LogTrace("L1GtLogicParser")
01264         //<< "\nit->operation = " << it->operation
01265         //<< "\nit->operand =   '" << it->operand << "'\n"
01266         //<< std::endl;
01267 
01268         switch (it->operation) {
01269 
01270             // RPN always start a block with an operand
01271             case OP_OPERAND: {
01272 
01273                     // more blocks with operations
01274                     // push operands from previous block, if any in the tmpVector
01275                     // (reverse order to compensate the stack push/top/pop)
01276                     if ( (!newOperandBlock) ) {
01277 
01278                         for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin();
01279                                 itOp != tmpVector.rend(); itOp++) {
01280 
01281                             opVector.push_back(*itOp);
01282 
01283                             //LogTrace("L1GtLogicParser")
01284                             //<< "  Push operand " << (*itOp).tokenName
01285                             //<<" on the seed operand list"
01286                             //<< std::endl;
01287 
01288                         }
01289 
01290                         tmpVector.clear();
01291 
01292                         newOperandBlock = true;
01293                         oneBlockOnly = false;
01294 
01295                     }
01296 
01297 
01298                     iOperand++;
01299 
01300                     //LogTrace("L1GtLogicParser")
01301                     //<< "  Push operand " << (m_operandTokenVector.at(iOperand)).tokenName
01302                     //<< " on the operand stack"
01303                     //<< std::endl;
01304 
01305                     tmpStack.push(m_operandTokenVector.at(iOperand));
01306                 }
01307 
01308                 break;
01309             case OP_NOT: {
01310 
01311                     newOperandBlock = false;
01312                     operandOnly = false;
01313 
01314                     b1 = tmpStack.top();
01315                     tmpStack.pop();                          // pop the top
01316 
01317                     tmpStack.push(dummyToken);               // and push dummy result
01318 
01319                     //LogTrace("L1GtLogicParser")
01320                     //<< "  Clear tmp operand list"
01321                     //<< std::endl;
01322 
01323                     tmpVector.clear();
01324 
01325                 }
01326 
01327                 break;
01328             case OP_OR: {
01329 
01330                     newOperandBlock = false;
01331                     operandOnly = false;
01332 
01333                     b1 = tmpStack.top();
01334                     tmpStack.pop();
01335                     b2 = tmpStack.top();
01336                     tmpStack.pop();
01337 
01338                     tmpStack.push(dummyToken);                     // and push dummy result
01339 
01340                     if ( b1.tokenNumber >= 0 ) {
01341                         tmpVector.push_back(b1);
01342 
01343                         //LogTrace("L1GtLogicParser")
01344                         //<< "  Push operand " << b1.tokenName
01345                         //<<" on the tmp list"
01346                         //<< std::endl;
01347                     }
01348 
01349                     if ( b2.tokenNumber >= 0 ) {
01350                         tmpVector.push_back(b2);
01351 
01352                         //LogTrace("L1GtLogicParser")
01353                         //<< "  Push operand " << b2.tokenName
01354                         //<<" on the tmp list"
01355                         //<< std::endl;
01356                     }
01357 
01358                 }
01359 
01360                 break;
01361             case OP_AND: {
01362 
01363                     newOperandBlock = false;
01364                     operandOnly = false;
01365 
01366                     b1 = tmpStack.top();
01367                     tmpStack.pop();
01368                     b2 = tmpStack.top();
01369                     tmpStack.pop();
01370 
01371                     tmpStack.push(dummyToken);
01372 
01373 
01374                     if ( b1.tokenNumber >= 0 ) {
01375                         tmpVector.push_back(b1);
01376 
01377                         //LogTrace("L1GtLogicParser")
01378                         //<< "  Push operand " << b1.tokenName
01379                         //<<" on the tmp list"
01380                         //<< std::endl;
01381                     }
01382 
01383                     if ( b2.tokenNumber >= 0 ) {
01384                         tmpVector.push_back(b2);
01385 
01386                         //LogTrace("L1GtLogicParser")
01387                         //<< "  Push operand " << b2.tokenName
01388                         //<<" on the tmp list"
01389                         //<< std::endl;
01390                     }
01391 
01392                 }
01393 
01394                 break;
01395             default: {
01396                     // should not arrive here
01397                 }
01398 
01399                 break;
01400         }
01401 
01402     }
01403 
01404 
01405     // one block only or one operand only
01406     if ( oneBlockOnly || operandOnly ) {
01407 
01408         // one operand only -
01409         // there can be only one operand, otherwise one needs an operation
01410         if (operandOnly) {
01411             b1 = tmpStack.top();
01412             tmpVector.push_back(b1);
01413         }
01414 
01415         //
01416         for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin();
01417                 itOp != tmpVector.rend(); itOp++) {
01418 
01419             opVector.push_back(*itOp);
01420 
01421             //LogTrace("L1GtLogicParser")
01422             //<< "  One block or one operand only: push operand " << (*itOp).tokenName
01423             //<<" on the seed operand list"
01424             //<< std::endl;
01425 
01426         }
01427 
01428     } else {
01429 
01430         //LogTrace("L1GtLogicParser")
01431         //        << "  More blocks:  push the last block on the seed operand list" << std::endl;
01432 
01433         for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin();
01434                 itOp != tmpVector.rend(); itOp++) {
01435 
01436             opVector.push_back(*itOp);
01437 
01438             //LogTrace("L1GtLogicParser")
01439             //<< "  Push operand:  " << (*itOp).tokenName
01440             //<<" on the seed operand list"
01441             //<< std::endl;
01442 
01443         }
01444 
01445     }
01446 
01447 
01448     // remove duplicates from the seed vector
01449     // slow...
01450     std::vector<OperandToken> opVectorU;
01451     opVectorU.reserve(opVector.size());
01452 
01453     for (std::vector<OperandToken>::const_iterator constIt = opVector.begin(); constIt
01454             != opVector.end(); constIt++) {
01455 
01456         bool tokenIncluded = false;
01457 
01458         for (std::vector<OperandToken>::iterator itOpU = opVectorU.begin(); itOpU
01459                 != opVectorU.end(); itOpU++) {
01460 
01461             if ( ( *itOpU ).tokenName == ( *constIt ).tokenName) {
01462                 tokenIncluded = true;
01463                 break;
01464             }
01465         }
01466 
01467         if (!tokenIncluded) {
01468             opVectorU.push_back(*constIt);
01469         }
01470 
01471     }
01472 
01473 
01474     return opVectorU;
01475 
01476 }
01477 
01478 
01479 // private methods
01480 
01492 L1GtLogicParser::OperationType L1GtLogicParser::getOperation(
01493     const std::string& tokenString,
01494     OperationType lastOperation, TokenRPN& rpnToken) const
01495 {
01496 
01497     OperationType actualOperation = OP_OPERAND;    // default value
01498 
01499     int i = 0;
01500 
01501     while (m_operationRules[i].opType != OP_OPERAND) {
01502         if (tokenString == m_operationRules[i].opString) {
01503             actualOperation = (OperationType) m_operationRules[i].opType;
01504             break;
01505         }
01506         i++;
01507     }
01508 
01509     // check if the operation is allowed
01510     if (m_operationRules[i].forbiddenLastOperation & lastOperation) {
01511         return OP_INVALID;
01512     }
01513 
01514     //
01515     if (actualOperation == OP_OPERAND) {
01516 
01517         rpnToken.operand = tokenString;
01518 
01519     } else {
01520 
01521         rpnToken.operand = "";
01522     }
01523 
01524     rpnToken.operation = actualOperation;
01525 
01526     // else we got a valid operation
01527     return actualOperation;
01528 }
01529 
01540 const L1GtLogicParser::OperationRule* L1GtLogicParser::getRuleFromType(OperationType oType)
01541 {
01542 
01543 
01544     int i = 0;
01545 
01546     while (
01547         (m_operationRules[i].opType != oType) &&
01548         (m_operationRules[i].opType != OP_NULL) ) {
01549         i++;
01550     }
01551 
01552     if (m_operationRules[i].opType == OP_NULL) {
01553         return 0;
01554     }
01555 
01556     return &(m_operationRules[i]);
01557 }
01558 
01559 
01560 // add spaces before and after parantheses - make separation easier
01561 void L1GtLogicParser::addBracketSpaces(const std::string& srcExpression,
01562                                        std::string& dstExpression)
01563 {
01564 
01565     static const std::string brackets="()"; // the brackets to be found
01566 
01567     dstExpression = srcExpression;  // copy the string
01568 
01569     size_t position = 0;
01570     while ( (position = dstExpression.find_first_of(brackets, position)) != std::string::npos ) {
01571 
01572         // add space after if none is there
01573         if (dstExpression[position + 1] != ' ') {
01574             dstExpression.insert(position + 1, " ");
01575         }
01576 
01577         // add space before if none is there
01578         if (dstExpression[position - 1] != ' ') {
01579             dstExpression.insert(position, " ");
01580             position++;
01581         }
01582         position++;
01583     }
01584 }
01585 
01586 
01587 // set the logical expression - check for correctness the input string
01588 bool L1GtLogicParser::setLogicalExpression(const std::string& logicalExpressionVal)
01589 {
01590 
01591     // add spaces around brackets
01592     std::string logicalExpressionBS;
01593     addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
01594 
01595     // trim leading or trailing spaces
01596     boost::trim(logicalExpressionBS);
01597 
01598     clearRpnVector();
01599 
01600     if ( !buildRpnVector(logicalExpressionBS) ) {
01601         m_logicalExpression = "";
01602         return false;
01603     }
01604 
01605     m_logicalExpression = logicalExpressionBS;
01606 
01607     //LogDebug("L1GtLogicParser")
01608     //<< "\nL1GtLogicParser::setLogicalExpression - "
01609     //<< "\nLogical expression = '" << m_logicalExpression << "'\n"
01610     //<< std::endl;
01611 
01612     return true;
01613 
01614 }
01615 
01616 // set the numerical expression (the logical expression with each operand
01617 // replaced with the value) from a string
01618 // check also for correctness the input string
01619 bool L1GtLogicParser::setNumericalExpression(const std::string& numericalExpressionVal)
01620 {
01621 
01622     // add spaces around brackets
01623     std::string numericalExpressionBS;
01624     addBracketSpaces(numericalExpressionVal, numericalExpressionBS);
01625 
01626     // check for consistency with the logical expression
01627     // TODO FIXME
01628 
01629     // trim leading or trailing spaces
01630     boost::trim(numericalExpressionBS);
01631 
01632     m_numericalExpression = numericalExpressionBS;
01633 
01634     //LogDebug("L1GtLogicParser")
01635     //<< "\nL1GtLogicParser::setNumericalExpression - "
01636     //<< "\nNumerical Expression = '" << m_numericalExpression << "'\n"
01637     //<< std::endl;
01638 
01639     return true;
01640 
01641 }
01642 
01643 
01644 // static members
01645 
01646 // rules for operations
01647 // 1st column: operation string
01648 // 2nd column: operation type
01649 // 3rd column: forbiddenLastOperation (what operation the operator/operand must not follow)
01650 const struct L1GtLogicParser::OperationRule L1GtLogicParser::m_operationRules[] =
01651     {
01652         { "AND",  OP_AND,           OP_AND | OP_OR | OP_NOT | OP_OPENBRACKET | OP_NULL },
01653         { "OR",   OP_OR,            OP_AND | OP_OR | OP_NOT | OP_OPENBRACKET | OP_NULL },
01654         { "NOT",  OP_NOT,           OP_OPERAND | OP_CLOSEBRACKET                       },
01655         { "(",    OP_OPENBRACKET,   OP_OPERAND | OP_CLOSEBRACKET                       },
01656         { ")",    OP_CLOSEBRACKET,  OP_AND | OP_OR | OP_NOT | OP_OPENBRACKET           },
01657         { NULL,   OP_OPERAND,       OP_OPERAND | OP_CLOSEBRACKET                       },
01658         { NULL,   OP_NULL,          OP_NULL                                            }
01659     };