00001
00017
00018 #include "DataFormats/L1GlobalTrigger/interface/L1GtLogicParser.h"
00019
00020
00021 #include <stack>
00022
00023 #include <iostream>
00024 #include <sstream>
00025
00026 #include <boost/algorithm/string.hpp>
00027
00028
00029
00030
00031 #include "FWCore/Utilities/interface/EDMException.h"
00032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00033
00034
00035
00036
00037
00038
00039 L1GtLogicParser::L1GtLogicParser() {
00040
00041
00042 }
00043
00044
00045
00046
00047
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
00058
00059 L1GtLogicParser::L1GtLogicParser(const std::string& logicalExpressionVal)
00060 {
00061
00062
00063
00064 if ( !setLogicalExpression(logicalExpressionVal) ) {
00065
00066
00067 throw cms::Exception("FailModule")
00068 << "\nError in parsing the logical expression = " << logicalExpressionVal
00069 << std::endl;
00070
00071 }
00072
00073 }
00074
00075
00076
00077 L1GtLogicParser::L1GtLogicParser(std::string& logicalExpressionVal)
00078 {
00079
00080
00081
00082
00083 std::string logicalExpressionBS;
00084 addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
00085
00086
00087 boost::trim(logicalExpressionBS);
00088
00089 if ( !buildRpnVector(logicalExpressionBS) ) {
00090
00091 throw cms::Exception("FailModule")
00092 << "\nError in parsing the logical expression = " << logicalExpressionVal
00093 << std::endl;
00094 }
00095
00096
00097
00098
00099
00100
00101 logicalExpressionVal = logicalExpressionBS;
00102 m_logicalExpression = logicalExpressionVal;
00103
00104
00105
00106 buildOperandTokenVector();
00107
00108 }
00109
00110
00111 L1GtLogicParser::L1GtLogicParser(const std::string logicalExpressionVal,
00112 const std::string numericalExpressionVal) {
00113
00114
00115 if ( !setLogicalExpression(logicalExpressionVal) ) {
00116
00117
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
00127 throw cms::Exception("FileModule")
00128 << "\nError in parsing the numerical expression = " << numericalExpressionVal
00129 << std::endl;
00130 }
00131
00132 }
00133
00134
00135
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
00154 L1GtLogicParser::~L1GtLogicParser()
00155 {
00156
00157 }
00158
00159
00160
00161
00162 bool L1GtLogicParser::checkLogicalExpression(std::string& logicalExpressionVal) {
00163
00164
00165 std::string logicalExpressionBS;
00166 addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
00167
00168
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
00202
00203
00204
00205
00206 OperationType actualOperation = OP_NULL;
00207 OperationType lastOperation = OP_NULL;
00208
00209
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
00217 clearRpnVector();
00218
00219
00220 std::istringstream exprStringStream(logicalExpressionVal);
00221
00222 while ( !exprStringStream.eof() ) {
00223
00224 exprStringStream >> std::skipws >> std::ws >> tokenString;
00225
00226
00227 if (tokenString.find_first_not_of(whitespaces) == std::string::npos ||
00228 tokenString.length() == 0) {
00229
00230
00231
00232
00233
00234 break;
00235 }
00236
00237 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
00238
00239
00240
00241
00242
00243
00244
00245
00246 switch (actualOperation) {
00247 case OP_OPERAND: {
00248
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
00267 clearRpnVector();
00268
00269 return false;
00270 }
00271
00272 break;
00273 case OP_NOT: {
00274 operatorStack.push(rpnToken);
00275
00276 }
00277
00278 break;
00279 case OP_AND: {
00280
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
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
00299 operatorStack.push(rpnToken);
00300 }
00301
00302 break;
00303 case OP_OPENBRACKET: {
00304
00305
00306 operatorStack.push(rpnToken);
00307 }
00308
00309 break;
00310 case OP_CLOSEBRACKET: {
00311
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
00325 clearRpnVector();
00326
00327 return false;
00328 }
00329
00330
00331 do {
00332 if (operatorStack.top().operation != OP_OPENBRACKET) {
00333 m_rpnVector.push_back(operatorStack.top());
00334 operatorStack.pop();
00335 }
00336 if (operatorStack.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
00349 clearRpnVector();
00350 return false;
00351 }
00352 } while (operatorStack.top().operation != OP_OPENBRACKET);
00353
00354 operatorStack.pop();
00355 }
00356
00357 break;
00358 default: {
00359
00360 }
00361 break;
00362 }
00363
00364 lastOperation = actualOperation;
00365
00366 }
00367
00368
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
00379 clearRpnVector();
00380 return false;
00381 }
00382
00383 m_rpnVector.push_back(operatorStack.top());
00384 operatorStack.pop();
00385 }
00386
00387
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
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
00417 clearRpnVector();
00418 return false;
00419 }
00420
00421 return true;
00422 }
00423
00424
00425
00426 void L1GtLogicParser::clearRpnVector()
00427 {
00428
00429 m_rpnVector.clear();
00430
00431 }
00432
00433
00434
00435
00436 void L1GtLogicParser::buildOperandTokenVector()
00437 {
00438
00439
00440
00441
00442
00443
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
00452
00453
00454
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
00471 }
00472
00473 break;
00474 case OP_OR: {
00475
00476 }
00477
00478 break;
00479 case OP_AND: {
00480
00481 }
00482
00483 break;
00484 default: {
00485
00486 }
00487
00488 break;
00489 }
00490
00491 opNumber++;
00492 }
00493
00494 }
00495
00496
00497
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;
00508
00509
00510 std::istringstream exprStringStream(m_logicalExpression);
00511
00512
00513 int tmpIndex = -1;
00514
00515 while (!exprStringStream.eof()) {
00516
00517 exprStringStream >> tokenString;
00518
00519
00520
00521
00522
00523 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
00524 if (actualOperation == OP_INVALID) {
00525
00526
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
00540
00541 } else {
00542
00543 tmpIndex++;
00544 if (rpnToken.operand == operandNameVal) {
00545 result = tmpIndex;
00546
00547
00548
00549
00550
00551
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
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;
00580
00581
00582 std::istringstream exprStringStream(m_logicalExpression);
00583
00584
00585 int tmpIndex = -1;
00586
00587 while (!exprStringStream.eof()) {
00588
00589 exprStringStream >> tokenString;
00590
00591
00592
00593
00594
00595 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
00596 if (actualOperation == OP_INVALID) {
00597
00598
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
00612
00613 } else {
00614
00615 tmpIndex++;
00616 if (tmpIndex == iOperand) {
00617 result = rpnToken.operand;
00618
00619
00620
00621
00622
00623
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
00643
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
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
00664
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
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
00686
00687 const bool L1GtLogicParser::expressionResult() const
00688 {
00689
00690
00691
00692
00693
00694
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
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
00711
00712
00713
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();
00725 resultStack.push(!b1);
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
00749 }
00750
00751 break;
00752 }
00753
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763 return resultStack.top();
00764
00765
00766 }
00767
00768
00769
00770
00771 bool L1GtLogicParser::operandResultNumExp(const std::string& operandNameVal) const
00772 {
00773
00774 bool result = false;
00775
00776
00777 const int iOperand = operandIndex(operandNameVal);
00778
00779 result = operandResult(iOperand);
00780
00781 return result;
00782
00783 }
00784
00785
00786
00787 bool L1GtLogicParser::operandResultNumExp(const int iOperand) const
00788 {
00789
00790 bool result = false;
00791
00792
00793
00794 OperationType actualOperation = OP_NULL;
00795 OperationType lastOperation = OP_NULL;
00796
00797 std::string tokenString;
00798 TokenRPN rpnToken;
00799
00800
00801 std::istringstream exprStringStream(m_numericalExpression);
00802
00803
00804 int tmpIndex = -1;
00805
00806 while (!exprStringStream.eof()) {
00807
00808 exprStringStream >> tokenString;
00809
00810
00811
00812
00813
00814 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
00815 if (actualOperation == OP_INVALID) {
00816
00817
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
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
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
00859
00860
00861
00862
00863
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
00884
00885 void L1GtLogicParser::buildOperandTokenVectorNumExp()
00886 {
00887
00888
00889
00890
00891
00892
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
00901
00902
00903
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
00920 }
00921
00922 break;
00923 case OP_OR: {
00924
00925 }
00926
00927 break;
00928 case OP_AND: {
00929
00930 }
00931
00932 break;
00933 default: {
00934
00935 }
00936
00937 break;
00938 }
00939
00940 opNumber++;
00941 }
00942
00943 }
00944
00945
00946
00947
00948 const bool L1GtLogicParser::expressionResultNumExp() const
00949 {
00950
00951
00952
00953
00954
00955
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
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
00972
00973
00974
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();
00986 resultStack.push(!b1);
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
01010 }
01011
01012 break;
01013 }
01014
01015 }
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026 return resultStack.top();
01027
01028
01029 }
01030
01031
01032
01033
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
01046
01047 OperationType actualOperation = OP_NULL;
01048 OperationType lastOperation = OP_NULL;
01049
01050 std::string tokenString;
01051 TokenRPN rpnToken;
01052
01053 int intValue = -1;
01054
01055
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
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
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(" ");
01110 lastOperation = actualOperation;
01111 }
01112
01113
01114
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
01124
01125
01126 m_logicalExpression = convertedLogicalExpression;
01127
01128 return;
01129
01130 }
01131
01132
01133
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
01144
01145 OperationType actualOperation = OP_NULL;
01146 OperationType lastOperation = OP_NULL;
01147
01148 std::string tokenString;
01149 TokenRPN rpnToken;
01150
01151
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
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
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
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(" ");
01205 lastOperation = actualOperation;
01206 }
01207
01208
01209
01210 boost::trim(convertedLogicalExpression);
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221 m_logicalExpression = convertedLogicalExpression;
01222
01223 return;
01224
01225 }
01226
01227
01228
01229 std::vector<L1GtLogicParser::OperandToken>
01230 L1GtLogicParser::expressionSeedsOperandList() {
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240 std::vector<OperandToken> opVector;
01241 opVector.reserve(m_operandTokenVector.size());
01242
01243
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
01264
01265
01266
01267
01268 switch (it->operation) {
01269
01270
01271 case OP_OPERAND: {
01272
01273
01274
01275
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
01284
01285
01286
01287
01288 }
01289
01290 tmpVector.clear();
01291
01292 newOperandBlock = true;
01293 oneBlockOnly = false;
01294
01295 }
01296
01297
01298 iOperand++;
01299
01300
01301
01302
01303
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();
01316
01317 tmpStack.push(dummyToken);
01318
01319
01320
01321
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);
01339
01340 if ( b1.tokenNumber >= 0 ) {
01341 tmpVector.push_back(b1);
01342
01343
01344
01345
01346
01347 }
01348
01349 if ( b2.tokenNumber >= 0 ) {
01350 tmpVector.push_back(b2);
01351
01352
01353
01354
01355
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
01378
01379
01380
01381 }
01382
01383 if ( b2.tokenNumber >= 0 ) {
01384 tmpVector.push_back(b2);
01385
01386
01387
01388
01389
01390 }
01391
01392 }
01393
01394 break;
01395 default: {
01396
01397 }
01398
01399 break;
01400 }
01401
01402 }
01403
01404
01405
01406 if ( oneBlockOnly || operandOnly ) {
01407
01408
01409
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
01422
01423
01424
01425
01426 }
01427
01428 } else {
01429
01430
01431
01432
01433 for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin();
01434 itOp != tmpVector.rend(); itOp++) {
01435
01436 opVector.push_back(*itOp);
01437
01438
01439
01440
01441
01442
01443 }
01444
01445 }
01446
01447
01448
01449
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
01480
01492 L1GtLogicParser::OperationType L1GtLogicParser::getOperation(
01493 const std::string& tokenString,
01494 OperationType lastOperation, TokenRPN& rpnToken) const
01495 {
01496
01497 OperationType actualOperation = OP_OPERAND;
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
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
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
01561 void L1GtLogicParser::addBracketSpaces(const std::string& srcExpression,
01562 std::string& dstExpression) {
01563
01564 static const std::string brackets = "()";
01565
01566 dstExpression = srcExpression;
01567
01568 size_t position = 0;
01569 while ((position = dstExpression.find_first_of(brackets, position))
01570 != std::string::npos) {
01571
01572
01573 if (((position + 1) != std::string::npos) && (dstExpression[position
01574 + 1] != ' ')) {
01575 dstExpression.insert(position + 1, " ");
01576 }
01577
01578
01579 if ((position != 0) && (dstExpression[position - 1] != ' ')) {
01580 dstExpression.insert(position, " ");
01581 position++;
01582 }
01583 position++;
01584 }
01585 }
01586
01587
01588
01589 bool L1GtLogicParser::setLogicalExpression(const std::string& logicalExpressionVal)
01590 {
01591
01592
01593 std::string logicalExpressionBS;
01594 addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
01595
01596
01597 boost::trim(logicalExpressionBS);
01598
01599 clearRpnVector();
01600
01601 if ( !buildRpnVector(logicalExpressionBS) ) {
01602 m_logicalExpression = "";
01603 return false;
01604 }
01605
01606 m_logicalExpression = logicalExpressionBS;
01607
01608
01609
01610
01611
01612
01613 return true;
01614
01615 }
01616
01617
01618
01619
01620 bool L1GtLogicParser::setNumericalExpression(const std::string& numericalExpressionVal)
01621 {
01622
01623
01624 std::string numericalExpressionBS;
01625 addBracketSpaces(numericalExpressionVal, numericalExpressionBS);
01626
01627
01628
01629
01630
01631 boost::trim(numericalExpressionBS);
01632
01633 m_numericalExpression = numericalExpressionBS;
01634
01635
01636
01637
01638
01639
01640 return true;
01641
01642 }
01643
01644
01645
01646
01647
01648
01649
01650
01651 const struct L1GtLogicParser::OperationRule L1GtLogicParser::m_operationRules[] =
01652 {
01653 { "AND", OP_AND, OP_AND | OP_OR | OP_NOT | OP_OPENBRACKET | OP_NULL },
01654 { "OR", OP_OR, OP_AND | OP_OR | OP_NOT | OP_OPENBRACKET | OP_NULL },
01655 { "NOT", OP_NOT, OP_OPERAND | OP_CLOSEBRACKET },
01656 { "(", OP_OPENBRACKET, OP_OPERAND | OP_CLOSEBRACKET },
01657 { ")", OP_CLOSEBRACKET, OP_AND | OP_OR | OP_NOT | OP_OPENBRACKET },
01658 { NULL, OP_OPERAND, OP_OPERAND | OP_CLOSEBRACKET },
01659 { NULL, OP_NULL, OP_NULL }
01660 };