File indexing completed on 2024-12-20 03:13:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include "DataFormats/L1TGlobal/interface/GlobalLogicParser.h"
0017
0018
0019 #include <stack>
0020
0021 #include <iostream>
0022 #include <sstream>
0023
0024 #include <boost/algorithm/string.hpp>
0025
0026
0027
0028 #include "FWCore/Utilities/interface/EDMException.h"
0029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0030
0031
0032
0033
0034
0035
0036 GlobalLogicParser::GlobalLogicParser() {
0037
0038 }
0039
0040
0041
0042
0043 GlobalLogicParser::GlobalLogicParser(const RpnVector& rpnVec, const std::vector<OperandToken>& opTokenVector) {
0044 m_rpnVector = rpnVec;
0045 m_operandTokenVector = opTokenVector;
0046 }
0047
0048
0049
0050 GlobalLogicParser::GlobalLogicParser(const std::string& logicalExpressionVal) {
0051
0052
0053 if (!setLogicalExpression(logicalExpressionVal)) {
0054
0055 throw cms::Exception("FailModule") << "\nError in parsing the logical expression = " << logicalExpressionVal
0056 << std::endl;
0057 }
0058 }
0059
0060
0061
0062 GlobalLogicParser::GlobalLogicParser(std::string& logicalExpressionVal) {
0063
0064
0065
0066 std::string logicalExpressionBS;
0067 addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
0068
0069
0070 boost::trim(logicalExpressionBS);
0071
0072 if (!buildRpnVector(logicalExpressionBS)) {
0073
0074 throw cms::Exception("FailModule") << "\nError in parsing the logical expression = " << logicalExpressionVal
0075 << std::endl;
0076 }
0077
0078
0079
0080
0081
0082
0083 logicalExpressionVal = logicalExpressionBS;
0084 m_logicalExpression = logicalExpressionVal;
0085
0086
0087
0088 buildOperandTokenVector();
0089 }
0090
0091
0092 GlobalLogicParser::GlobalLogicParser(const std::string logicalExpressionVal, const std::string numericalExpressionVal) {
0093
0094
0095 if (!setLogicalExpression(logicalExpressionVal)) {
0096
0097 throw cms::Exception("FailModule") << "\nError in parsing the logical expression = " << logicalExpressionVal
0098 << std::endl;
0099 }
0100
0101 if (!setNumericalExpression(numericalExpressionVal)) {
0102
0103 throw cms::Exception("FileModule") << "\nError in parsing the numerical expression = " << numericalExpressionVal
0104 << std::endl;
0105 }
0106 }
0107
0108
0109
0110 GlobalLogicParser::GlobalLogicParser(const std::string& logicalExpressionVal,
0111 const std::string& numericalExpressionVal,
0112 const bool dummy) {
0113 clearRpnVector();
0114 if (!buildRpnVector(logicalExpressionVal)) {
0115 throw cms::Exception("FileModule") << "\nError in building RPN vector for the logical expression = "
0116 << logicalExpressionVal << std::endl;
0117 }
0118
0119 m_logicalExpression = logicalExpressionVal;
0120 m_numericalExpression = numericalExpressionVal;
0121 }
0122
0123
0124 GlobalLogicParser::~GlobalLogicParser() {
0125
0126 }
0127
0128
0129
0130
0131 bool GlobalLogicParser::checkLogicalExpression(std::string& logicalExpressionVal) {
0132
0133 std::string logicalExpressionBS;
0134 addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
0135
0136
0137 boost::trim(logicalExpressionBS);
0138
0139 clearRpnVector();
0140
0141 if (!buildRpnVector(logicalExpressionBS)) {
0142 return false;
0143 }
0144
0145 LogDebug("L1TGlobal") << "\nGtLogicParser::checkLogicalExpression - "
0146 << "\nInitial logical expression = '" << logicalExpressionVal << "'"
0147 << "\nFinal logical expression = '" << logicalExpressionBS << "'\n"
0148 << std::endl;
0149
0150 logicalExpressionVal = logicalExpressionBS;
0151
0152 return true;
0153 }
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 bool GlobalLogicParser::buildRpnVector(const std::string& logicalExpressionVal) {
0165
0166
0167
0168
0169
0170 OperationType actualOperation = OP_NULL;
0171 OperationType lastOperation = OP_NULL;
0172
0173
0174 std::string tokenString;
0175 TokenRPN rpnToken;
0176 std::stack<TokenRPN> operatorStack;
0177
0178 static const std::string whitespaces = " \r\v\n\t";
0179
0180
0181 clearRpnVector();
0182
0183
0184 std::istringstream exprStringStream(logicalExpressionVal);
0185
0186 while (!exprStringStream.eof()) {
0187 exprStringStream >> std::skipws >> std::ws >> tokenString;
0188
0189
0190 if (tokenString.find_first_not_of(whitespaces) == std::string::npos || tokenString.empty()) {
0191
0192
0193
0194
0195 break;
0196 }
0197
0198 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
0199
0200
0201
0202
0203
0204
0205
0206
0207 switch (actualOperation) {
0208 case OP_OPERAND: {
0209
0210 m_rpnVector.push_back(rpnToken);
0211 }
0212
0213 break;
0214 case OP_INVALID: {
0215 int errorPosition = exprStringStream.tellg();
0216
0217 edm::LogError("L1TGlobal") << "\nLogical expression = '" << logicalExpressionVal << "'"
0218 << "\n Syntax error during parsing: "
0219 << "\n " << exprStringStream.str().substr(0, errorPosition) << "\n "
0220 << exprStringStream.str().substr(errorPosition)
0221 << "\n Returned empty RPN vector and result false." << std::endl;
0222
0223
0224 clearRpnVector();
0225
0226 return false;
0227 }
0228
0229 break;
0230 case OP_NOT: {
0231 operatorStack.push(rpnToken);
0232
0233 }
0234
0235 break;
0236 case OP_XOR: {
0237
0238 while (!operatorStack.empty() && operatorStack.top().operation == OP_NOT) {
0239 m_rpnVector.push_back(operatorStack.top());
0240 operatorStack.pop();
0241 }
0242 operatorStack.push(rpnToken);
0243 }
0244
0245 break;
0246 case OP_AND: {
0247
0248 while (!operatorStack.empty() &&
0249 (operatorStack.top().operation == OP_NOT || operatorStack.top().operation == OP_AND)) {
0250 m_rpnVector.push_back(operatorStack.top());
0251 operatorStack.pop();
0252 }
0253 operatorStack.push(rpnToken);
0254 }
0255
0256 break;
0257 case OP_OR: {
0258
0259 while (!operatorStack.empty() &&
0260 (operatorStack.top().operation == OP_NOT || operatorStack.top().operation == OP_XOR ||
0261 operatorStack.top().operation == OP_AND)) {
0262 m_rpnVector.push_back(operatorStack.top());
0263 operatorStack.pop();
0264 }
0265
0266 operatorStack.push(rpnToken);
0267 }
0268
0269 break;
0270 case OP_OPENBRACKET: {
0271
0272 operatorStack.push(rpnToken);
0273 }
0274
0275 break;
0276 case OP_CLOSEBRACKET: {
0277
0278 if (operatorStack.empty()) {
0279 int errorPosition = exprStringStream.tellg();
0280
0281 edm::LogError("L1TGlobal") << "\nLogical expression = '" << logicalExpressionVal << "'"
0282 << "\n Syntax error during parsing - misplaced ')':"
0283 << "\n " << exprStringStream.str().substr(0, errorPosition) << "\n "
0284 << exprStringStream.str().substr(errorPosition)
0285 << "\n Returned empty RPN vector and result false." << std::endl;
0286
0287
0288 clearRpnVector();
0289
0290 return false;
0291 }
0292
0293
0294 do {
0295 if (operatorStack.top().operation != OP_OPENBRACKET) {
0296 m_rpnVector.push_back(operatorStack.top());
0297 operatorStack.pop();
0298 }
0299 if (operatorStack.empty()) {
0300
0301 int errorPosition = exprStringStream.tellg();
0302
0303 edm::LogError("L1TGlobal") << "\nLogical expression = '" << logicalExpressionVal << "'"
0304 << "\n Syntax error during parsing - misplaced ')':"
0305 << "\n " << exprStringStream.str().substr(0, errorPosition) << "\n "
0306 << exprStringStream.str().substr(errorPosition)
0307 << "\n Returned empty RPN vector and result false." << std::endl;
0308
0309
0310 clearRpnVector();
0311 return false;
0312 }
0313 } while (operatorStack.top().operation != OP_OPENBRACKET);
0314
0315 operatorStack.pop();
0316 }
0317
0318 break;
0319 default: {
0320
0321 } break;
0322 }
0323
0324 lastOperation = actualOperation;
0325 }
0326
0327
0328 while (!operatorStack.empty()) {
0329 if (operatorStack.top().operation == OP_OPENBRACKET) {
0330 edm::LogError("L1TGlobal") << "\nLogical expression = '" << logicalExpressionVal << "'"
0331 << "\n Syntax error during parsing - missing ')':"
0332 << "\n Returned empty RPN vector and result false." << std::endl;
0333
0334
0335 clearRpnVector();
0336 return false;
0337 }
0338
0339 m_rpnVector.push_back(operatorStack.top());
0340 operatorStack.pop();
0341 }
0342
0343
0344 int counter = 0;
0345 for (RpnVector::iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
0346 if (it->operation == OP_OPERAND)
0347 counter++;
0348 if (it->operation == OP_OR || it->operation == OP_AND || it->operation == OP_XOR)
0349 counter--;
0350 if (counter < 1) {
0351 edm::LogError("L1TGlobal") << "\nLogical expression = '" << logicalExpressionVal << "'"
0352 << "\n Syntax error during parsing - too many operators"
0353 << "\n Returned empty RPN vector and result false." << std::endl;
0354
0355
0356 clearRpnVector();
0357 return false;
0358 }
0359 }
0360
0361 if (counter > 1) {
0362 edm::LogError("L1TGlobal") << "\nLogical expression = '" << logicalExpressionVal << "'"
0363 << "\n Syntax error during parsing - too many operands"
0364 << "\n Returned empty RPN vector and result false." << std::endl;
0365
0366
0367 clearRpnVector();
0368 return false;
0369 }
0370 return true;
0371 }
0372
0373
0374 void GlobalLogicParser::clearRpnVector() { m_rpnVector.clear(); }
0375
0376
0377
0378 void GlobalLogicParser::buildOperandTokenVector() {
0379
0380
0381
0382
0383
0384 size_t rpnVectorSize = m_rpnVector.size();
0385 m_operandTokenVector.reserve(rpnVectorSize);
0386
0387 int opNumber = 0;
0388
0389 for (RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
0390
0391
0392
0393
0394
0395 switch (it->operation) {
0396 case OP_OPERAND: {
0397 OperandToken opToken;
0398 opToken.tokenName = it->operand;
0399 opToken.tokenNumber = opNumber;
0400 opToken.tokenResult = false;
0401
0402 m_operandTokenVector.push_back(opToken);
0403
0404 }
0405
0406 break;
0407 case OP_NOT: {
0408
0409 }
0410
0411 break;
0412 case OP_OR: {
0413
0414 }
0415
0416 break;
0417 case OP_AND: {
0418
0419 }
0420 case OP_XOR: {
0421
0422 }
0423
0424 break;
0425 default: {
0426
0427 }
0428
0429 break;
0430 }
0431
0432 opNumber++;
0433 }
0434 }
0435
0436
0437 int GlobalLogicParser::operandIndex(const std::string& operandNameVal) const {
0438 int result = -1;
0439
0440 OperationType actualOperation = OP_NULL;
0441 OperationType lastOperation = OP_NULL;
0442
0443 std::string tokenString;
0444 TokenRPN rpnToken;
0445
0446
0447 std::istringstream exprStringStream(m_logicalExpression);
0448
0449
0450 int tmpIndex = -1;
0451
0452 while (!exprStringStream.eof()) {
0453 exprStringStream >> tokenString;
0454
0455
0456
0457
0458
0459 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
0460 if (actualOperation == OP_INVALID) {
0461
0462 edm::LogError("L1TGlobal") << "\nLogical expression = '" << m_logicalExpression << "'"
0463 << "\n Invalid operation/operand " << operandNameVal
0464 << "\n Returned index is by default out of range (-1)." << std::endl;
0465
0466 return result;
0467 }
0468
0469 if (actualOperation != OP_OPERAND) {
0470
0471
0472 } else {
0473 tmpIndex++;
0474 if (rpnToken.operand == operandNameVal) {
0475 result = tmpIndex;
0476
0477
0478
0479
0480
0481
0482
0483 return result;
0484 }
0485 }
0486 lastOperation = actualOperation;
0487 }
0488
0489
0490 edm::LogError("L1TGlobal") << "\nLogical expression = '" << m_logicalExpression << "'"
0491 << "\n Operand " << operandNameVal << " not found in the logical expression"
0492 << "\n Returned index is by default out of range (-1)." << std::endl;
0493
0494 return result;
0495 }
0496
0497
0498 std::string GlobalLogicParser::operandName(const int iOperand) const {
0499 std::string result;
0500
0501 OperationType actualOperation = OP_NULL;
0502 OperationType lastOperation = OP_NULL;
0503
0504 std::string tokenString;
0505 TokenRPN rpnToken;
0506
0507
0508 std::istringstream exprStringStream(m_logicalExpression);
0509
0510
0511 int tmpIndex = -1;
0512
0513 while (!exprStringStream.eof()) {
0514 exprStringStream >> tokenString;
0515
0516
0517
0518
0519
0520 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
0521 if (actualOperation == OP_INVALID) {
0522
0523 edm::LogError("L1TGlobal") << "\nLogical expression = '" << m_logicalExpression << "'"
0524 << "\n Invalid operation/operand at position " << iOperand
0525 << "\n Returned empty name by default." << std::endl;
0526
0527 return result;
0528 }
0529
0530 if (actualOperation != OP_OPERAND) {
0531
0532
0533 } else {
0534 tmpIndex++;
0535 if (tmpIndex == iOperand) {
0536 result = rpnToken.operand;
0537
0538
0539
0540
0541
0542
0543
0544 return result;
0545 }
0546 }
0547 lastOperation = actualOperation;
0548 }
0549
0550
0551 edm::LogError("L1TGlobal") << "\nLogical expression = '" << m_logicalExpression << "'"
0552 << "\n No operand found at position " << iOperand << "\n Returned empty name by default."
0553 << std::endl;
0554
0555 return result;
0556 }
0557
0558
0559
0560 bool GlobalLogicParser::operandResult(const std::string& operandNameVal) const {
0561 for (size_t i = 0; i < m_operandTokenVector.size(); ++i) {
0562 if ((m_operandTokenVector[i]).tokenName == operandNameVal) {
0563 return (m_operandTokenVector[i]).tokenResult;
0564 }
0565 }
0566
0567
0568 edm::LogError("L1TGlobal") << "\n Operand " << operandNameVal << " not found in the operand token vector"
0569 << "\n Returned false by default." << std::endl;
0570
0571 return false;
0572 }
0573
0574
0575
0576 bool GlobalLogicParser::operandResult(const int tokenNumberVal) const {
0577 for (size_t i = 0; i < m_operandTokenVector.size(); ++i) {
0578 if ((m_operandTokenVector[i]).tokenNumber == tokenNumberVal) {
0579 return (m_operandTokenVector[i]).tokenResult;
0580 }
0581 }
0582
0583
0584 edm::LogError("L1TGlobal") << "\n No operand with token number " << tokenNumberVal
0585 << " found in the operand token vector"
0586 << "\n Returned false by default." << std::endl;
0587
0588 return false;
0589 }
0590
0591
0592
0593 const bool GlobalLogicParser::expressionResult() const {
0594
0595
0596
0597
0598
0599 if (m_rpnVector.empty()) {
0600 edm::LogError("L1TGlobal") << "\n No built RPN vector exists."
0601 << "\n Returned false by default." << std::endl;
0602 return false;
0603 }
0604
0605
0606 std::stack<bool> resultStack;
0607 bool b1, b2;
0608
0609 for (RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
0610
0611
0612
0613
0614
0615 switch (it->operation) {
0616 case OP_OPERAND: {
0617 resultStack.push(operandResult(it->operand));
0618 }
0619
0620 break;
0621 case OP_NOT: {
0622 b1 = resultStack.top();
0623 resultStack.pop();
0624 resultStack.push(!b1);
0625 }
0626
0627 break;
0628 case OP_OR: {
0629 b1 = resultStack.top();
0630 resultStack.pop();
0631 b2 = resultStack.top();
0632 resultStack.pop();
0633 resultStack.push(b1 || b2);
0634 }
0635
0636 break;
0637 case OP_XOR: {
0638 b1 = resultStack.top();
0639 resultStack.pop();
0640 b2 = resultStack.top();
0641 resultStack.pop();
0642 resultStack.push(b1 ^ b2);
0643 }
0644
0645 break;
0646 case OP_AND: {
0647 b1 = resultStack.top();
0648 resultStack.pop();
0649 b2 = resultStack.top();
0650 resultStack.pop();
0651 resultStack.push(b1 && b2);
0652 }
0653
0654 break;
0655 default: {
0656
0657 }
0658
0659 break;
0660 }
0661 }
0662
0663
0664
0665
0666
0667
0668
0669
0670 return resultStack.top();
0671 }
0672
0673
0674
0675 bool GlobalLogicParser::operandResultNumExp(const std::string& operandNameVal) const {
0676 bool result = false;
0677
0678
0679 const int iOperand = operandIndex(operandNameVal);
0680
0681 result = operandResult(iOperand);
0682
0683 return result;
0684 }
0685
0686
0687
0688 bool GlobalLogicParser::operandResultNumExp(const int iOperand) const {
0689 bool result = false;
0690
0691
0692
0693 OperationType actualOperation = OP_NULL;
0694 OperationType lastOperation = OP_NULL;
0695
0696 std::string tokenString;
0697 TokenRPN rpnToken;
0698
0699
0700 std::istringstream exprStringStream(m_numericalExpression);
0701
0702
0703 int tmpIndex = -1;
0704
0705 while (!exprStringStream.eof()) {
0706 exprStringStream >> tokenString;
0707
0708
0709
0710
0711
0712 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
0713 if (actualOperation == OP_INVALID) {
0714
0715 edm::LogError("L1TGlobal") << "\nNumerical expression = '" << m_numericalExpression << "'"
0716 << "\n Invalid operation/operand at position " << iOperand
0717 << "\n Returned false by default." << std::endl;
0718
0719 result = false;
0720 return result;
0721 }
0722
0723 if (actualOperation != OP_OPERAND) {
0724
0725
0726 } else {
0727 tmpIndex++;
0728 if (tmpIndex == iOperand) {
0729 if (rpnToken.operand == "1") {
0730 result = true;
0731 } else {
0732 if (rpnToken.operand == "0") {
0733 result = false;
0734 } else {
0735
0736
0737 edm::LogError("L1TGlobal") << "\nNumerical expression = '" << m_numericalExpression << "'"
0738 << "\n Invalid result for operand at position " << iOperand << ": "
0739 << rpnToken.operand << "\n It must be 0 or 1"
0740 << "\n Returned false by default." << std::endl;
0741
0742 result = false;
0743 return result;
0744 }
0745 }
0746
0747
0748
0749
0750
0751
0752
0753
0754 return result;
0755 }
0756 }
0757 lastOperation = actualOperation;
0758 }
0759
0760
0761 edm::LogError("L1TGlobal") << "\nNumerical expression = '" << m_numericalExpression << "'"
0762 << "\n No operand found at position " << iOperand << "\n Returned false by default."
0763 << std::endl;
0764
0765 return result;
0766 }
0767
0768
0769
0770 void GlobalLogicParser::buildOperandTokenVectorNumExp() {
0771
0772
0773
0774
0775
0776 size_t rpnVectorSize = m_rpnVector.size();
0777 m_operandTokenVector.reserve(rpnVectorSize);
0778
0779 int opNumber = 0;
0780
0781 for (RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
0782
0783
0784
0785
0786
0787 switch (it->operation) {
0788 case OP_OPERAND: {
0789 OperandToken opToken;
0790 opToken.tokenName = it->operand;
0791 opToken.tokenNumber = opNumber;
0792 opToken.tokenResult = operandResultNumExp(it->operand);
0793
0794 m_operandTokenVector.push_back(opToken);
0795
0796 }
0797
0798 break;
0799 case OP_NOT: {
0800
0801 }
0802
0803 break;
0804 case OP_OR: {
0805
0806 }
0807
0808 break;
0809 case OP_XOR: {
0810
0811 }
0812
0813 break;
0814 case OP_AND: {
0815
0816 }
0817
0818 break;
0819 default: {
0820
0821 }
0822
0823 break;
0824 }
0825
0826 opNumber++;
0827 }
0828 }
0829
0830
0831 const bool GlobalLogicParser::expressionResultNumExp() const {
0832
0833
0834
0835
0836
0837 if (m_rpnVector.empty()) {
0838 edm::LogError("L1TGlobal") << "\n No built RPN vector exists."
0839 << "\n Returned false by default." << std::endl;
0840 return false;
0841 }
0842
0843
0844 std::stack<bool> resultStack;
0845 bool b1, b2;
0846
0847 for (RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
0848
0849
0850
0851
0852
0853 switch (it->operation) {
0854 case OP_OPERAND: {
0855 resultStack.push(operandResultNumExp(it->operand));
0856 }
0857
0858 break;
0859 case OP_NOT: {
0860 b1 = resultStack.top();
0861 resultStack.pop();
0862 resultStack.push(!b1);
0863 }
0864
0865 break;
0866 case OP_OR: {
0867 b1 = resultStack.top();
0868 resultStack.pop();
0869 b2 = resultStack.top();
0870 resultStack.pop();
0871 resultStack.push(b1 || b2);
0872 }
0873
0874 break;
0875 case OP_XOR: {
0876 b1 = resultStack.top();
0877 resultStack.pop();
0878 b2 = resultStack.top();
0879 resultStack.pop();
0880 resultStack.push(b1 ^ b2);
0881 }
0882
0883 break;
0884 case OP_AND: {
0885 b1 = resultStack.top();
0886 resultStack.pop();
0887 b2 = resultStack.top();
0888 resultStack.pop();
0889 resultStack.push(b1 && b2);
0890 }
0891
0892 break;
0893 default: {
0894
0895 }
0896
0897 break;
0898 }
0899 }
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910 return resultStack.top();
0911 }
0912
0913
0914
0915
0916
0917 void GlobalLogicParser::convertNameToIntLogicalExpression(const std::map<std::string, int>& nameToIntMap) {
0918 if (m_logicalExpression.empty()) {
0919 return;
0920 }
0921
0922
0923
0924 OperationType actualOperation = OP_NULL;
0925 OperationType lastOperation = OP_NULL;
0926
0927 std::string tokenString;
0928 TokenRPN rpnToken;
0929
0930 int intValue = -1;
0931
0932
0933 std::istringstream exprStringStream(m_logicalExpression);
0934 std::string convertedLogicalExpression;
0935
0936 while (!exprStringStream.eof()) {
0937 exprStringStream >> tokenString;
0938
0939 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
0940 if (actualOperation == OP_INVALID) {
0941
0942 edm::LogError("L1TGlobal") << "\nLogical expression = '" << m_logicalExpression << "'"
0943 << "\n Invalid operation/operand in logical expression."
0944 << "\n Return empty logical expression." << std::endl;
0945
0946 m_logicalExpression.clear();
0947 return;
0948 }
0949
0950 if (actualOperation != OP_OPERAND) {
0951 convertedLogicalExpression.append(getRuleFromType(actualOperation)->opString);
0952
0953 } else {
0954 typedef std::map<std::string, int>::const_iterator CIter;
0955
0956 CIter it = nameToIntMap.find(rpnToken.operand);
0957 if (it != nameToIntMap.end()) {
0958 intValue = it->second;
0959 std::stringstream intStr;
0960 intStr << intValue;
0961 convertedLogicalExpression.append(intStr.str());
0962
0963 } else {
0964
0965 edm::LogError("L1TGlobal") << "\nLogical expression = '" << m_logicalExpression << "'"
0966 << "\n Could not convert " << rpnToken.operand << " to integer!"
0967 << "\n Return empty logical expression." << std::endl;
0968
0969 m_logicalExpression.clear();
0970 return;
0971 }
0972 }
0973
0974 convertedLogicalExpression.append(" ");
0975 lastOperation = actualOperation;
0976 }
0977
0978
0979
0980 boost::trim(convertedLogicalExpression);
0981
0982 LogDebug("L1TGlobal") << "\nGtLogicParser::convertNameToIntLogicalExpression - "
0983 << "\nLogical expression (strings) = '" << m_logicalExpression << "'"
0984 << "\nLogical expression (int) = '" << convertedLogicalExpression << "'\n"
0985 << std::endl;
0986
0987
0988
0989
0990 m_logicalExpression = convertedLogicalExpression;
0991
0992 return;
0993 }
0994
0995
0996
0997
0998 void GlobalLogicParser::convertIntToNameLogicalExpression(const std::map<int, std::string>& intToNameMap) {
0999 if (m_logicalExpression.empty()) {
1000 return;
1001 }
1002
1003
1004
1005 OperationType actualOperation = OP_NULL;
1006 OperationType lastOperation = OP_NULL;
1007
1008 std::string tokenString;
1009 TokenRPN rpnToken;
1010
1011
1012 std::istringstream exprStringStream(m_logicalExpression);
1013 std::string convertedLogicalExpression;
1014
1015 while (!exprStringStream.eof()) {
1016 exprStringStream >> tokenString;
1017
1018 actualOperation = getOperation(tokenString, lastOperation, rpnToken);
1019 if (actualOperation == OP_INVALID) {
1020
1021 edm::LogError("L1TGlobal") << "\nLogical expression = '" << m_logicalExpression << "'"
1022 << "\n Invalid operation/operand in logical expression."
1023 << "\n Return empty logical expression." << std::endl;
1024
1025 m_logicalExpression.clear();
1026 return;
1027 }
1028
1029 if (actualOperation != OP_OPERAND) {
1030 convertedLogicalExpression.append(getRuleFromType(actualOperation)->opString);
1031
1032 } else {
1033 typedef std::map<int, std::string>::const_iterator CIter;
1034
1035
1036 int indexInt;
1037 std::istringstream iss(rpnToken.operand);
1038 iss >> std::dec >> indexInt;
1039
1040 CIter it = intToNameMap.find(indexInt);
1041 if (it != intToNameMap.end()) {
1042 convertedLogicalExpression.append(it->second);
1043
1044 } else {
1045
1046 edm::LogError("L1TGlobal") << "\nLogical expression = '" << m_logicalExpression << "'"
1047 << "\n Could not convert " << rpnToken.operand << " to string!"
1048 << "\n Return empty logical expression." << std::endl;
1049
1050 m_logicalExpression.clear();
1051 return;
1052 }
1053 }
1054
1055 convertedLogicalExpression.append(" ");
1056 lastOperation = actualOperation;
1057 }
1058
1059
1060
1061 boost::trim(convertedLogicalExpression);
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 m_logicalExpression = convertedLogicalExpression;
1073
1074 return;
1075 }
1076
1077
1078
1079 std::vector<GlobalLogicParser::OperandToken> GlobalLogicParser::expressionSeedsOperandList() {
1080
1081
1082
1083
1084
1085
1086
1087
1088 std::vector<OperandToken> opVector;
1089 opVector.reserve(m_operandTokenVector.size());
1090
1091
1092 std::stack<OperandToken> tmpStack;
1093 std::vector<OperandToken> tmpVector;
1094 tmpVector.reserve(m_operandTokenVector.size());
1095
1096 OperandToken b1, b2;
1097
1098 bool newOperandBlock = true;
1099 bool oneBlockOnly = true;
1100 bool operandOnly = true;
1101
1102 int iOperand = -1;
1103
1104 OperandToken dummyToken;
1105 dummyToken.tokenName = "dummy";
1106 dummyToken.tokenNumber = -1;
1107 dummyToken.tokenResult = false;
1108
1109 for (RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
1110
1111
1112
1113
1114
1115 switch (it->operation) {
1116
1117 case OP_OPERAND: {
1118
1119
1120
1121 if ((!newOperandBlock)) {
1122 for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin(); itOp != tmpVector.rend();
1123 itOp++) {
1124 opVector.push_back(*itOp);
1125
1126
1127
1128
1129
1130 }
1131
1132 tmpVector.clear();
1133
1134 newOperandBlock = true;
1135 oneBlockOnly = false;
1136 }
1137
1138 iOperand++;
1139
1140
1141
1142
1143
1144
1145 tmpStack.push(m_operandTokenVector.at(iOperand));
1146 }
1147
1148 break;
1149 case OP_NOT: {
1150 newOperandBlock = false;
1151 operandOnly = false;
1152
1153 b1 = tmpStack.top();
1154 tmpStack.pop();
1155
1156 tmpStack.push(dummyToken);
1157
1158
1159
1160
1161
1162 tmpVector.clear();
1163
1164 }
1165
1166 break;
1167 case OP_OR: {
1168 newOperandBlock = false;
1169 operandOnly = false;
1170
1171 b1 = tmpStack.top();
1172 tmpStack.pop();
1173 b2 = tmpStack.top();
1174 tmpStack.pop();
1175
1176 tmpStack.push(dummyToken);
1177
1178 if (b1.tokenNumber >= 0) {
1179 tmpVector.push_back(b1);
1180
1181
1182
1183
1184
1185 }
1186
1187 if (b2.tokenNumber >= 0) {
1188 tmpVector.push_back(b2);
1189
1190
1191
1192
1193
1194 }
1195
1196 }
1197
1198 break;
1199 case OP_XOR: {
1200 newOperandBlock = false;
1201 operandOnly = false;
1202
1203 b1 = tmpStack.top();
1204 tmpStack.pop();
1205 b2 = tmpStack.top();
1206 tmpStack.pop();
1207
1208 tmpStack.push(dummyToken);
1209
1210 if (b1.tokenNumber >= 0) {
1211 tmpVector.push_back(b1);
1212
1213
1214
1215
1216
1217 }
1218
1219 if (b2.tokenNumber >= 0) {
1220 tmpVector.push_back(b2);
1221
1222
1223
1224
1225
1226 }
1227
1228 }
1229
1230 break;
1231 case OP_AND: {
1232 newOperandBlock = false;
1233 operandOnly = false;
1234
1235 b1 = tmpStack.top();
1236 tmpStack.pop();
1237 b2 = tmpStack.top();
1238 tmpStack.pop();
1239
1240 tmpStack.push(dummyToken);
1241
1242 if (b1.tokenNumber >= 0) {
1243 tmpVector.push_back(b1);
1244
1245
1246
1247
1248
1249 }
1250
1251 if (b2.tokenNumber >= 0) {
1252 tmpVector.push_back(b2);
1253
1254
1255
1256
1257
1258 }
1259
1260 }
1261
1262 break;
1263 default: {
1264
1265 }
1266
1267 break;
1268 }
1269 }
1270
1271
1272 if (oneBlockOnly || operandOnly) {
1273
1274
1275 if (operandOnly) {
1276 b1 = tmpStack.top();
1277 tmpVector.push_back(b1);
1278 }
1279
1280
1281 for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin(); itOp != tmpVector.rend(); itOp++) {
1282 opVector.push_back(*itOp);
1283
1284
1285
1286
1287
1288 }
1289
1290 } else {
1291
1292
1293
1294 for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin(); itOp != tmpVector.rend(); itOp++) {
1295 opVector.push_back(*itOp);
1296
1297
1298
1299
1300
1301 }
1302 }
1303
1304
1305
1306 std::vector<OperandToken> opVectorU;
1307 opVectorU.reserve(opVector.size());
1308
1309 for (std::vector<OperandToken>::const_iterator constIt = opVector.begin(); constIt != opVector.end(); constIt++) {
1310 bool tokenIncluded = false;
1311
1312 for (std::vector<OperandToken>::iterator itOpU = opVectorU.begin(); itOpU != opVectorU.end(); itOpU++) {
1313 if ((*itOpU).tokenName == (*constIt).tokenName) {
1314 tokenIncluded = true;
1315 break;
1316 }
1317 }
1318
1319 if (!tokenIncluded) {
1320 opVectorU.push_back(*constIt);
1321 }
1322 }
1323
1324 return opVectorU;
1325 }
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340 GlobalLogicParser::OperationType GlobalLogicParser::getOperation(const std::string& tokenString,
1341 OperationType lastOperation,
1342 TokenRPN& rpnToken) const {
1343 OperationType actualOperation = OP_OPERAND;
1344
1345 int i = 0;
1346
1347 while (m_operationRules[i].opType != OP_OPERAND) {
1348 if (tokenString == m_operationRules[i].opString) {
1349 actualOperation = (OperationType)m_operationRules[i].opType;
1350 break;
1351 }
1352 i++;
1353 }
1354
1355
1356 if (m_operationRules[i].forbiddenLastOperation & lastOperation) {
1357 return OP_INVALID;
1358 }
1359
1360
1361 if (actualOperation == OP_OPERAND) {
1362 rpnToken.operand = tokenString;
1363
1364 } else {
1365 rpnToken.operand = "";
1366 }
1367
1368 rpnToken.operation = actualOperation;
1369
1370
1371 return actualOperation;
1372 }
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384 const GlobalLogicParser::OperationRule* GlobalLogicParser::getRuleFromType(OperationType oType) {
1385 int i = 0;
1386
1387 while ((m_operationRules[i].opType != oType) && (m_operationRules[i].opType != OP_NULL)) {
1388 i++;
1389 }
1390
1391 if (m_operationRules[i].opType == OP_NULL) {
1392 return nullptr;
1393 }
1394
1395 return &(m_operationRules[i]);
1396 }
1397
1398
1399 void GlobalLogicParser::addBracketSpaces(const std::string& srcExpression, std::string& dstExpression) {
1400 static const std::string brackets = "()";
1401
1402 dstExpression = srcExpression;
1403
1404 size_t position = 0;
1405 while ((position = dstExpression.find_first_of(brackets, position)) != std::string::npos) {
1406
1407 if (((position + 1) != std::string::npos) && (dstExpression[position + 1] != ' ')) {
1408 dstExpression.insert(position + 1, " ");
1409 }
1410
1411
1412 if ((position != 0) && (dstExpression[position - 1] != ' ')) {
1413 dstExpression.insert(position, " ");
1414 position++;
1415 }
1416 position++;
1417 }
1418 }
1419
1420
1421 bool GlobalLogicParser::setLogicalExpression(const std::string& logicalExpressionVal) {
1422
1423 std::string logicalExpressionBS;
1424 addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
1425
1426
1427 boost::trim(logicalExpressionBS);
1428
1429 clearRpnVector();
1430
1431 if (!buildRpnVector(logicalExpressionBS)) {
1432 m_logicalExpression = "";
1433 return false;
1434 }
1435
1436 m_logicalExpression = logicalExpressionBS;
1437
1438
1439
1440
1441
1442
1443 return true;
1444 }
1445
1446
1447
1448
1449 bool GlobalLogicParser::setNumericalExpression(const std::string& numericalExpressionVal) {
1450
1451 std::string numericalExpressionBS;
1452 addBracketSpaces(numericalExpressionVal, numericalExpressionBS);
1453
1454
1455
1456
1457
1458 boost::trim(numericalExpressionBS);
1459
1460 m_numericalExpression = numericalExpressionBS;
1461
1462
1463
1464
1465
1466
1467 return true;
1468 }
1469
1470
1471
1472
1473
1474
1475
1476 const struct GlobalLogicParser::OperationRule GlobalLogicParser::m_operationRules[] = {
1477 {"AND", OP_AND, OP_AND | OP_OR | OP_XOR | OP_NOT | OP_OPENBRACKET | OP_NULL},
1478 {"OR", OP_OR, OP_AND | OP_OR | OP_XOR | OP_NOT | OP_OPENBRACKET | OP_NULL},
1479 {"XOR", OP_XOR, OP_AND | OP_OR | OP_XOR | OP_NOT | OP_OPENBRACKET | OP_NULL},
1480 {"NOT", OP_NOT, OP_OPERAND | OP_CLOSEBRACKET},
1481 {"(", OP_OPENBRACKET, OP_OPERAND | OP_CLOSEBRACKET},
1482 {")", OP_CLOSEBRACKET, OP_AND | OP_OR | OP_XOR | OP_NOT | OP_OPENBRACKET},
1483 {nullptr, OP_OPERAND, OP_OPERAND | OP_CLOSEBRACKET},
1484 {nullptr, OP_NULL, OP_NULL}};